l = listen()
使用listen来开启一个本地的监听端口
r = process("./test")
shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0')
pwn_ssh=ssh(host='pwnable.kr',user='fd',password='guest',port=2222)
使用ssh进行远程连接进行交互
>>> context.arch = 'i386'
>>> context.os = 'linux'
>>> context.endian = 'little'
>>> context.word_size = 32
可以使用context来指定cpu类型以及操作系统,设定系统的指定参数。对比如下:
>>> asm ('nop' )
'\ x90'
>>> context (arch = 'arm' , os = 'linux' , endian = 'big' , word_size = 32 )
>>> asm ('nop' )
' \ xe3 \ xf0 \ x00'
/////////////
设置记录详情
日志记录的详情:
Can also control logging verbosity and terminal fancyness
NOTERM
SILENT
DEBUG
>>> context.log_level = 'debug'
汇编和反汇编:
>>> asm('mov eax, 0').encode('hex')
'b800000000'
>>> print disasm('6a0258cd80ebf9'.decode('hex'))
0: 6a 02 push 0x2
2: 58 pop eax
3: cd 80 int 0x80
5: eb f9 jmp 0x0
///////////////////////////////////////////////////////////
http://blog.csdn.net/gyhgx/article/details/53439417
http://www.91ri.org/14382.html
>>> e = ELF('/bin/cat')
>>> e.read(e.address+1, 3)
'ELF'
>>> e.asm(e.address, 'ret')
>>> e.save('/tmp/quiet-cat')
>>> disasm(file('/tmp/quiet-cat','rb').read(1))
' 0: c3 ret'
下面是一些可用的函数:
asm(address, assembly) : 在指定地址进行汇编
bss(offset) : 返回bss段的位置,offset是偏移值
checksec() : 对elf进行一些安全保护检查,例如NX, PIE等。
disasm(address, n_bytes) : 在指定位置进行n_bytes个字节的反汇编
offset_to_vaddr(offset) : 将文件中的偏移offset转换成虚拟地址VMA
vaddr_to_offset(address) : 与上面的函数作用相反
read(address, count) : 在address(VMA)位置读取count个字节
write(address, data) : 在address(VMA)位置写入data
section(name) : dump出指定section的数据
Context设置:
context是pwntools用来设置环境的功能。在很多时候,由于二进制文件的情况不同,我们可能需要进行一些环境设置才能够正常运行exp,比如有一些需要进行汇编,但是32的汇编和64的汇编不同,如果不设置context会导致一些问题。
一般来说我们设置context只需要简单的一句话:
context(os='linux', arch='amd64', log_level='debug')
这句话的意思是:
- os设置系统为linux系统,在完成ctf题目的时候,大多数pwn题目的系统都是linux
- arch设置架构为amd64,可以简单的认为设置为64位的模式,对应的32位模式是’i386’
- log_level设置日志输出的等级为debug,这句话在调试的时候一般会设置,这样pwntools会将完整的io过程都打印下来,使得调试更加方便,可以避免在完成CTF题目时出现一些和IO相关的错误。
////////////////////////////////////
DynELF
DynELF是leak信息的神器。前提条件是要提供一个输入地址,输出此地址最少1byte数的函数。官网给出的说明是:Given a function which can leak data at an arbitrary address, any symbol in any loaded library can be resolved
d = DynELF(leak, elf=ELF("./xxx")) #初始化DynELF模块
///////////////////////////
gdb.debug 和 gdb.attach
1 用gdb启动程序,并弹出新窗口与其交互
2 附加到一个程序上,pid/pwnlibs.tubes/socket都可以
gdb.attach(proc.pidof(p)[0])
//////////////////////////
args 快速访问所有的命令行参数
python foo.py REMOTE=1
args['REMOTE'] == '1'
/////////////////
一些实用工具
Default
b64d('dGVzdA==')
b64e("test")
bits(511, zero = "+", one = "-") 把参数转换为位
bits_str(511) 得到'0000000111111111'
enhex("test") 得到'74657374'
isprint(c) 判断一个字符是否可打印
randoms(10) 返回'evafjilupm'
rol('abcdefg', 2) 得到'cdefgab'
unhex("74657374") 得到'test'
urldecode("test%20%41")
net 查询网络借口
proc 查询进程
pause
safeeval 执行python代码,但不会产生副作用
其他
Default
hexdump
read and write
enhex and unhex
more
group
align and align_down
urlencode and urldecode
which
wget
urlencode
常用模块
asm 汇编与反汇编
dynelf 用于远程符号泄露,需要提供leak方法
elf 对elf文件进行操作
gdb 配合gdb进行调试
memleak 用于内存泄漏
shellcraft shellcode的生成器
tubes 包括tubes.sock,tubes.process,tubes.ssh,tubes.serialtube,分别适用于不同场景的PIPE
utils 一些实用的小功能,例如CRC计算,cyclic pattern等
asm
把shellcode汇编成字节形式:
usage: asm [-h] [-f {raw,hex,string,elf}] [-o file] [-c context] [-v AVOID] [-n] [-z] [-d] [-e ENCODER] [-i INFILE] [-r] [line [line ...]]
line
Lines to assemble. If none are supplied, use stdin
链接到汇编,如果没有提供,就使用标准输入
-v <avoid>, --avoid <avoid>
避免出现不需要的字符(比如0x00)
-z, --zero
编码shellcode避免NULL字节出现
-d, --debug
使用gdb调试shellcode
-e <encoder>, --encoder <encoder>
使用需要的编码器
-i <infile>, --infile <infile>
需要指定的输入文件
-r, --run
Run output
/////////////////////////////////////////
checksec
Check binary security settings
//////////////////////////////////////////////
constgrep
查找文件头部的常量:
例如:
constgrep -c freebsd -m ^PROT_ ‘3 + 4’
regex
使用正则表达式匹配你要查找的内容
constant
需要寻找的常数
-e <<constant name>>, --exact <<constant name>>
Do an exact match for a constant instead of searching for a regex
做一个精确匹配,(这里说的并不是搜索一个正则表达式)
-i, --case-insensitive
搜索不区分大小写
-m, --mask-mode
进行模糊匹配,不要求严格匹配,可以比匹配的字符少。
-c <<opt>>, --context <<opt>>
程序运行在什么样的架构之上(默认:linux/i386)
elfdiff
比较两个对象的不同
cyclic
count:打印多少
-a <alphabet>, --alphabet <alphabet>
有什么符号代替字母表
-n
排列变化的,子字符串长度
-l <lookup_value>, -o <lookup_value>, --offset <lookup_value>, --lookup <lookup_value>
Do a lookup instead printing the alphabet
pwn elfpatch
Patch an ELF file
usage: pwn [-h]
{asm,checksec,constgrep,cyclic,disasm,elfdiff,elfpatch,errno,hex,phd,pwnstrip,scramble,shellcraft,unhex,update}
pwn phd
将文件按十六进制输出
-w <width>, --width <width>
每一行输出的十六进制个数
-l <highlight>, --highlight <highlight>
高亮显示要查找的字节(参数放在程序的后面)
-s <skip>, --skip <skip>
跳过指定字节数开始显示
-c <count>, --count <count>
仅展示多少字节
-o <offset>, --offset <offset>
从左边你需要的地址开始执行
--color {always,never,auto}
Colorize the output. When ‘auto’ output is colorized exactly when stdout is a TTY. Default is ‘auto’.
pwn pwnstrip
Strip binaries for CTF usage
-b, --build-id
Strip build ID
-p <function>, --patch <function>
Patch function
加载一个函数的功能 ,测试一堆二进制文件
pwn scramble
Shellcode encoder
-f {raw,hex,string,elf}, --format {raw,hex,string,elf}
Output format (defaults to hex for ttys, otherwise raw)
不会用
pwn shellcraft
微软的shellcode生成器
相关参数看如下网站:
http://pwntoolsdocinzh-cn.readthedocs.io/en/master/commandline.html#
pwn unhex
hex
把16进制数转化为标准输入
pwnlib.adb — Android Debug Bridge
通过使用Android调试桥接器与Android设备进行交互的程序。
Using Android Devices with Pwntools
- 1.最重要的就是context.device
- 在任意一个范围内选择一个驱动
- 手工的填写一个编号
- 添加一个设备的实例
获得第一个有效的设备
context.device = adb.wait_for_device()
给设备添加一个编号
context.device = 'ZX1G22LH8S'
给设备设置名称
for device in adb.devices():
if device.product == 'shamu':
break
else:
error("Could not find any shamus!")
pwnlib.adb
通过此模块你可以调用此设备的所有功能。
获取一个进程列表
print adb.process(['ps']).recvall()
获取属性
print adb.properties.ro.build.fingerprint
读或者写入一个文档
print adb.read('/proc/version')
adb.write('/data/local/tmp/foo', 'my data')
class pwnlib.adb.adb.AdbDevice(serial, type, port=None, product='unknown', model='unknown', device='unknown', features=None, **kw)
系统的基本信息
例如:
>>> device = adb.wait_for_device()
>>> device.arch
'arm'
>>> device.bits
32
>>> device.os
'android'
>>> device.product
'sdk_phone_armv7'
>>> device.serial
'emulator-5554'
pwnlib.adb.adb.adb(argv, *a, **kw)
返回ABD子命令的输出:
>>> adb.adb(['get-serialno'])
'emulator-5554\n'
pwnlib.adb.adb.boot_time() → int
设备的启动时间,采用四舍五入。
pwnlib.adb.adb.build(* a,** kw )
返回设备的Build ID
pwnlib.adb.adb.compile(source)
使用 Android NDK的源文件和项目
pwnlib.adb.adb.current_device(any=False)
返回context.device选中的adbDevice的实例
例子:
>>> device = adb.current_device(any=True)
>>> device
AdbDevice(serial='emulator-5554', type='device', port='emulator', product='sdk_phone_armv7', model='sdk phone armv7', device='generic')
>>> device.port
'emulator'
pwnlib.adb.adb.devices(*a, **kw)
返回连接设备相对应的Device对象的列表
pwnlib.adb.adb.disable_verity(*a, **kw)
禁用设备上的dm-verity
pwnlib.adb.adb.exists(* a,** kw )
返回目标设备上路径是否存在。
例子:
>>> adb.exists('/')
True
>>> adb.exists('/init')
True
>>> adb.exists('/does/not/exist')
False
wnlib.adb.adb.fastboot(*a, **kw)
执行快速启动命令
返回:命令输出结果
pwnlib.adb.adb.find_ndk_project_root(source)
给定一个目录路径,找到最顶层的项目根目录
tl;dr “foo/bar/jni/baz.cpp” ==> “foo/bar”
pwnlib.adb.adb.fingerprint(*a, **kw)
返回设备的构建的指纹信息
pwnlib.adb.adb.forward(*a, **kw)
设置端口已经转发的设备
pwnlib.adb.adb.getprop(*a, **kw)
从系统属性存储中读取一个属性。
参数: name(str)-选项,读取一个属性
返回:如果name没有指定,将返回所有属性的dict值,否则将返回name的属性值。
pwnlib.adb.adb.install(apk, *arguments)
在设备上安装一个APK
pwnlib.adb.adb.install(apk, *arguments)
这是一个'pm install'封装包,她支持'adb install'
参数:
apk (str) 安装路径
arguments – 补充 参数 ‘pm install’, e.g. '-l', '-g'.
pwnlib.adb.adb.interactive(* a,** kw )
产生一个交互式的shell
pwnlib.adb.adb.isdir(* a,** kw )
返回目标设备的路径是否存在。
例子:
>>> adb.isdir('/')
True
>>> adb.isdir('/init')
False
>>> adb.isdir('/does/not/exist')
False
pwnlib.adb.adb.listdir(*a, **kw)
返回一个进入设备目录的的列表
注意:
在adbd SELinux环境中,使用运行的SYNC LIST功能。如果adbd在su域('adb root')中运行,则其行为与预期相同。
否则,由于adbd上的限制了SELinux策略,可能会返回更少的文件。
pwnlib.adb.adb.logcat(*a, **kw)
读取系统日志文件
默认情况下,读取文件后导致日志退出。
参数:
stream:如果是true,是流形式,不是读取形式,默认是False
返回: 如果stream是False,返回包含日志数据的字符串,否则,返回 pwnlib.tubes.tube.tube的连接到日志输出。
pwnlib.adb.adb.makedirs(* a,** kw )
在目标设备上创建一个目录和所有父目录。
注意:
如果目录存在,它什么也不做。
例子:
>>> adb.makedirs('/data/local/tmp/this/is/a/directory/heirarchy')
>>> adb.listdir('/data/local/tmp/this/is/a/directory')
['heirarchy']
pwnlib.adb.adb.mkdir(*a, **kw)
在目标设备上建立目录
注意:
如果目录存在,它什么也不做。
参数: path(str):目标的路径
例子:
>>> adb.mkdir('/')
>>> path = '/data/local/tmp/mkdir_test'
>>> adb.exists(path)
False
>>> adb.mkdir(path)
>>> adb.exists(path)
True
>>> adb.mkdir('/init')
Traceback (most recent call last):
...
PwnlibException: mkdir failed for /init, File exists
pwnlib.adb.adb.packages(*a, **kw)
返回系统上安装的软件包列表
pwnlib.adb.adb.pidof(* a,** kw )
返回指定进程的PID列表。
pwnlib.adb.adb.proc_exe(* a,** kw )
返回,提供的PID的可执行文件的完整路径
pwnlib.adb.adb.process(* a,** kw )
在设备上执行一个进程
请参阅pwnlib.tubes.process.process文档了解更多信息。
Returns: A pwnlib.tubes.process.process tube.
例子:
>>> adb.root()
>>> print adb.process(['cat','/proc/version']).recvall()
Linux version ...
pwnlib.adb.adb.product(*a, **kw)
返回设备产品标识符
pwnlib.adb.adb.pull(* a,** kw )
从设备下载文件
参数:
remote_path(str) - 设备上文件的路径或目录
local_path(str) 保存文件的路径。在默认情况下使用文件的名称。
返回:文件的内容
例子:
>>> _=adb.pull('/proc/version', './proc-version')
>>> print read('./proc-version')
Linux version ...
pwnlib.adb.adb.push(* a,** kw )
上传文件到设备
参数:
local_path(str) 要推送的本地文件的路径
remote_path(str) 将文件存储在设备上的路径或目录
Returns:文件的远程路径
例子:
>>> write('./filename', 'contents')
>>> adb.push('./filename', '/data/local/tmp')
'/data/local/tmp/filename'
>>> adb.read('/data/local/tmp/filename')
'contents'
>>> adb.push('./filename', '/does/not/exist')
Traceback (most recent call last):
...
PwnlibException: Could not stat '/does/not/exist'
pwnlib.adb.adb.read(*a, **kw)
从设备下载文件,并提取其内容
参数:
path(str)设备上的文件路径
target(str)可选,存储文件的位置。默认使用临时文件
callback(callable)详细文档adb.protocol.AdbClient.read
例子:
>>> print adb.read('/proc/version')
Linux version ...
>>> adb.read('/does/not/exist')
Traceback (most recent call last):
...
PwnlibException: Could not stat '/does/not/exist'
pwnlib.adb.adb.reboot(* a,** kw )
重新启动设备
pwnlib.adb.adb.reboot_bootloader(* a,** kw )
从引导模式里重新启动
pwnlib.adb.adb.remount(* a,** kw )
将文件系统重新设置为可写
pwnlib.adb.adb.root(* a,** kw )
以root身份重新启动 adbd
>>> adb.root()
pwnlib.adb.adb.setprop(*a, **kw)
将属性写入系统属性存储区
pwnlib.adb.adb.shell(* a,** kw )
返回交互式shell。
pwnlib.adb.adb.uninstall(package, *arguments)
从设备上卸载APK。
这是'pm卸载',它支持'adb'卸载。
参数:
package(str)要卸载的包的名称 (例 'com.foo.MyPackage')
arguments 补充参数,例如 'pm install''-k'
pwnlib.adb.adb.unlink(* a,** kw )
取消链接目标设备上的文件或目录
Examples
>>> adb.unlink("/does/not/exist")
Traceback (most recent call last):
...
PwnlibException: Could not unlink '/does/not/exist': Does not exist
>>> filename = '/data/local/tmp/unlink-test'
>>> adb.write(filename, 'hello')
>>> adb.exists(filename)
True
>>> adb.unlink(filename)
>>> adb.exists(filename)
False
>>> adb.mkdir(filename)
>>> adb.write(filename + '/contents', 'hello')
>>> adb.unlink(filename)
Traceback (most recent call last):
...
PwnlibException: Cannot delete non-empty directory '/data/local/tmp/unlink-test' without recursive=True
>>> adb.unlink(filename, recursive=True)
>>> adb.exists(filename)
False
pwnlib.adb.adb.unlock_bootloader(* a,** kw )
解锁设备的引导程序
注意:
这需要与设备进行物理交互
pwnlib.adb.adb.unroot(* a,** kw )
将adbd重新启动为AID_SHELL
pwnlib.adb.adb.uptime() →float
Returns:设备的正常运行时间,以秒为单位
pwnlib.adb.adb.wait_for_device(* a,** kw )
等待设备连接
默认情况下,等待当前选择的设备(通过context.device)。要等待特定的设备,请设置context.device。要等待其它任何设备,必循清除context.device
Returns:AdbDevice设备的实例
例子:
>>> device = adb.wait_for_device()
pwnlib.adb.adb.which(*a, **kw)
检索$PATH设备上二进制文件的完整路径
Parameters:
name (str) 二进制名称
all(bool)返回所有路径,还是只返回第一个
*a 其它参数 adb.process()
**kw 其它参数adb.process()
Returns:
路径或路径列表
例子:
>>> adb.which('sh')
'/system/bin/sh'
>>> adb.which('sh', all=True)
['/system/bin/sh']
>>> adb.which('foobar') is None
True
>>> adb.which('foobar', all=True)
[]
pwnlib.adb.adb.write(* a,** kw )
用提供的内容在设备上创建一个文件
参数:
path (str) 设备上文件的路径
data(str) 存储在文件中的内容
例子
>>> adb.write('/dev/null', 'data')
>>> adb.write('/data/local/tmp/')
相关链接网站:
https://binjitsu.readthedocs.io/commandline.html#asm
pwntools学习网站:
http://pwntoolsdocinzh-cn.readthedocs.io/en/master/intro.html(中文网站)
https://etenal.me/archives/972
https://www.cnblogs.com/liuyimin/p/7512252.html(详细清楚)
http://cheesehack.tistory.com/category/Etc/Pwntools%20reference(有些新的参数介绍)
网友评论