格式化串漏洞利用姿势

确定偏移

  • 利用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)实现

DynELF时leak函数至少返回1字节,并且addr地址中可以出现\x00,