pwntools ---前六节

作者: Black_Sun | 来源:发表于2019-07-03 18:42 被阅读18次
    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')
    

    这句话的意思是:

    1. os设置系统为linux系统,在完成ctf题目的时候,大多数pwn题目的系统都是linux
    2. arch设置架构为amd64,可以简单的认为设置为64位的模式,对应的32位模式是’i386’
    3. 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(有些新的参数介绍)

    相关文章

      网友评论

        本文标题:pwntools ---前六节

        本文链接:https://www.haomeiwen.com/subject/abyqbxtx.html