格式化字符串笔记

格式化字符串笔记

基本格式

%[parameter][flags][field width][.precision][length]type

  • parameter :
    • n$,获取格式化字符串中的第n个参数
  • length : 输出的长度
    • $hhn,写入一个字节
    • $hn,写入两个字节
    • $n,​写入四个字节
    • $lln,写入八个字节

类型

参数 输入类型 输出类型
%c 字符,通常用来配合%n写
%d 十进制整数
%x 十六进制整数
%p 十六进制整数,与%x基本一样,只是附加了前缀0x,可用来判断目标环境是32bit还是64bit
%s 指针 字符串,经常用来读GOT表内容,遇'\x00'截断
%n 指针 写入已经输出字节个数

more

基础

  • %n$x可以获取到对应的第n+1个参数的数值
  • 利用%x来获取对应栈的内存,但建议使用%p,可以不用考虑位数的区别
  • 利用%s来获取变量所对应地址的内容,只不过有零截断
  • 利用%order$x来获取指定参数的值,利用%order$s来获取指定参数对应地址的内容

踩坑

  • 利用任意写建议不要一次性写完,可以分字节写
  • 遇到过滤$h$n,可以用$+hn,等同于$hn

64位前六个参数问题

  • %1$lx: RSI
  • %2$lx: RDX
  • %3$lx: RCX
  • %4$lx: R8
  • %5$lx: R9
  • %6$lx: 栈上的第一个QWORD

FmtStr

自动查找偏移地址:

#! /usr/bin/env python
# -*- coding: utf-8 -*-

from pwn import *

def exec_fmt(payload):
    p = process('a.out')     #文件路径
    p.sendline(payload)
    info = p.recv()
    p.close()
    return info

autofmt = FmtStr(exec_fmt)
print autofmt.offset

fmtstr

产生格式化字符串工具: payload = fmtstr_payload(offset, writes, numbwritten=0, write_size='byte')

  • offset (int) – 第一个格式化偏移
  • writes (dict) – 字典,向哪个地址写入什么值 {addr: value, addr2: value2}
  • numbwritten (int) – 输出字符串已经写入字节数
  • write_size (str) – byte, short or int.即每次写一个字节、两个字节还是四个字节,默认按字节

fmtarg

pwngdb来判断某个参数的偏移

gef➤  fmtarg 0x00007fffffffdb28
The index of format argument : 10