• readelf -h binary 查看二进制文件头
  • readelf -S binary 查看二进制文件节表(section table)
  • readelf -l binary 查看二进制文件段表(program header table)
  • readelf -x number|name binary 打印下标为number或名字为name的section内容(十六进制)
  • readelf -p number|name binary 以字符串形式打印节区内容
  • readelf -s binary 读取符号表
  • objdump -s binary 将所有节的内容打印出来
  • objdump -d binary 将代码段进行反汇编
  • objdump -r binary 查看重定位表

确定偏移

  • 利用pwntools提供的FmtStr(exec_fmt),获取offset

读/写栈上数据

  • 读:计算出要读的地址是第xxx个不定参数,然后利用%xxx$x 读取(x-十六进制读,lx长整读取(64位))
  • 写:首先泄露栈上rbp的值,然后根据rbp与返回地址之间的差值,得出返回地址所在的栈地址,利用任意地址写即可覆盖返回地址,如下图所示,可泄露show函数栈帧中rbp1的值,然后利用rbp1与printf函数返回地址之间的差值,计算可到printf返回地址所在的地址,覆盖之(绕过FULL RELRO,泄露show函数的返回地址,可以绕过PIE,泄露main函数的返回地址,即__libc_start_main_ret,可以leak libc)

读/写任意地址数据

  • 读:
    • 发送:payload = START + %xx$s + END+ addr
    • 接收:
      1. recvuntil(START)   
        data = recvuntil(END, drop=1, timeout=1)
        if not data:
            data = '\x00'
    • 读取addr地址处的字符串,xxx是根据addr在栈上的地址计算出的不定参数的值recvuntil(START)
  • 写:
    • payload = %yyyc+%xxx$hn+[padding]+addr
    • xxx计算方法同上,yyy为要写入的数据,可以用fmtstr_payload(offset, writes)实现

继续阅读