onegadget不起作用

本文深入探讨了在利用one_gadget进行漏洞攻击时所需满足的条件,如0x4526a要求[rsp+0x30]==NULL。文章详细讲解了如何通过调整__malloc_hook和realloc_hook来满足条件,实现getshell的目的。通过实例分析,读者可以了解到如何通过控制push数量调整esp指针,使esp’满足one_gadget的条件。

one_gadget的执行是需要一些条件的

0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL

0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL

0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL

0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

例如0x4526a,我们需要满足[rsp+0x30] == NULL这个条件。
当向__malloc_hook写one_gadget时,如果不满足one_gadget的条件时,而我们的环境不太好调整,所以无法getshell。
我们可以通过__malloc_hook和realloc_hook相配合的方法来使得one_gadget生效。
以0x4526a这个one_gadget为例
当eip到达这个位置时,esp为0x7fffffffdb88
在这里插入图片描述
在这里插入图片描述
[esp+0x30]=0x00007fffffffdd50
但是我们可以看到[esp+0x38]=NULL。我们可以通过调整esp指针的值来使得新的esp’满足[esp’+0x30]=[esp+0x38]=NULL。
能够调整esp的手段就是通过控制__malloc_hook里面存的__libc_realloc地址来控制push的数量
在这里插入图片描述
,所在在这我们只需要向__malloc_hook存入0x7ffff7a916c2,少一个push,esp’=esp+8,所以[esp’+0x30]=[esp+0x38]
在这里插入图片描述
在这里面我们分析的很粗糙,如果要仔细分析的话,要考虑实际的堆栈空间。
实际做题目时,我们可以尝试几次,来使得[esp+0x30]满足条件。

<think>嗯,用户问的是“pwn本地打不通”,这个问题在CTF比赛或者二进制安全研究中挺常见的。首先,我得回想一下自己之前遇到类似问题的经验。本地打不通可能有多种原因,得一步步排查。 首先想到的是,用户可能在本地运行漏洞利用代码时没有成功触发预期的效果,比如没有拿到shell或者程序崩溃了,但远程却能成功。这种情况通常有几个常见原因。比如,本地环境和远程环境不一致,这包括libc版本、程序保护机制(如ASLR、NX、Canary)是否开启,或者程序本身的编译选项不同。用户可能没注意到这些差异,导致本地测试时无法复现远程环境的情况。 接下来,用户可能没有正确设置环境。比如,ASLR(地址随机化)在本地是默认开启的,但远程可能关闭了,或者反之。这时候需要检查/proc/sys/kernel/randomize_va_space的值,或者使用setarch命令来关闭ASLR进行测试。另外,有时候需要确保本地运行的libc版本和远程一致,否则偏移量计算会有问题,导致利用失败。 然后是漏洞利用脚本的问题。比如,用户可能在脚本中硬编码了一些地址,比如libc基址或者函数的GOT表地址,但这些地址在本地和远程可能不同,导致本地无法正确跳转。这时候需要使用动态获取的方法,比如泄漏地址后再计算偏移。另外,利用逻辑中的某些步骤可能在本地环境下不适用,比如某些gadget在本地不存在,或者栈布局不同,导致ROP链构造失败。 还有可能是输入方式的问题。本地执行时,用户可能用python2的exp.py的方式生成输入,但python3的字符串处理不同,导致payload不正确。或者使用了管道符| 来连接输入,但程序可能需要更精确的输入方式,比如使用process()之后进行交互,或者需要处理标准输入输出的缓冲问题。 另外,程序本身的行为可能有差异。比如,本地编译的程序可能有调试信息或者优化选项不同,导致漏洞触发条件不同。或者本地测试时程序是32位的,而远程是64位的,导致结构体对齐、函数调用约定等差异,影响利用。 还有可能用户没有正确处理程序的崩溃情况。比如,在溢出后程序崩溃时,某些情况下需要保持标准输入输出流的打开,或者需要重新连接,而本地测试时没有正确处理,导致利用失败。 针对这些问题,用户需要逐一排查。首先检查环境和保护机制是否一致,使用checksec工具查看。然后确认libc版本是否匹配,可以用ldd命令查看本地依赖,或者使用Docker模拟远程环境。接着,检查利用脚本中的地址是否动态计算,避免硬编码。此外,使用调试工具如gdb,配合peda或pwndbg插件,观察程序崩溃时的寄存器状态、栈布局,确认payload是否正确覆盖返回地址或修改关键数据。 还有,可能用户没有正确处理程序的交互,比如在发送payload后需要接收一些输出,或者需要等待一段时间才能继续输入,这时候使用pwntools的send、sendline、recvuntil等方法时,顺序或超时设置不正确,导致本地测试时流程出错。 另外,有时候本地测试时,程序的行为会因为附加了调试器而改变,比如某些反调试机制被触发,或者信号处理不同,导致漏洞无法触发。这时候可以尝试在不调试的情况下直接运行exp,看是否成功。 最后,用户可能遇到的是一些细节问题,比如文件路径问题、权限问题(比如需要root权限运行某些操作),或者本地测试时使用的漏洞利用技术本身存在问题,需要重新审视漏洞的原理和利用步骤。 总之,解决本地打不通的问题需要系统性地对比本地和远程环境,仔细检查利用脚本的每个步骤,使用调试工具逐步分析程序执行流程,并确保所有依赖和配置一致。可能需要多次尝试和验证,逐步排除可能的原因,最终找到问题所在并进行修复。</think>在CTF二进制安全领域,当遇到"本地漏洞利用(pwn)打不通"的情况时,通常需要系统化排查以下原因。以下是分步骤的解决方案: --- ### **一、环境差异排查** 1. **保护机制对比** ```bash checksec ./pwnfile # 本地检查 readelf -a ./pwnfile | grep 'NX\|Canary' # 远程对比(需有文件) ``` - 若远程开启`ASLR`而本地关闭: ```bash echo 2 | sudo tee /proc/sys/kernel/randomize_va_space # 开启ASLR setarch `uname -m` -R ./pwnfile # 临时启用 ``` 2. **libc版本一致性** - 本地查看:`ldd ./pwnfile | grep libc` - 远程匹配:通过`Docker`构建相同环境或使用`patchelf`修改加载器: ```bash patchelf --set-interpreter /path/to/ld.so ./pwnfile patchelf --replace-needed libc.so.6 /path/to/libc.so ./pwnfile ``` --- ### **二、利用脚本调试** 1. **动态地址处理** 避免硬编码地址,改用动态计算: ```python from pwn import * libc = ELF('/path/to/libc.so') offset = libc.sym['system'] - libc.sym['puts'] ``` 2. **调试观察** 使用`gdb`附加进程观察崩溃点: ```python p = process('./pwnfile') gdb.attach(p, ''' b *main+10 continue ''') ``` - 检查关键寄存器值(`$rip`, `$rsp`) - 验证栈溢出长度是否正确 --- ### **三、输入方式修正** 1. **输入管道优化** 使用`pwntools`的标准化输入: ```python payload = flat([ cyclic(100), # 用于定位溢出偏移 p64(gadget_addr), ]) p.sendlineafter(b'> ', payload) ``` 2. **缓冲区问题处理** 添加`clean()`函数清空缓冲区: ```python def clean(): p.recv(timeout=1) clean() p.send(payload) ``` --- ### **四、常见错误场景** 1. **栈对齐问题(x64架构)** 在ROP链中添加`ret`指令调整对齐: ```python rop = ROP(elf) rop.raw(rop.ret) # 对齐栈 rop.system(next(elf.search(b'/bin/sh'))) ``` 2. **onegadget条件不满足** 通过`gdb`验证约束条件: ```bash gdb-pwndbg> x/10gx $rsp+0x40 # 检查onegadget所需寄存器状态 ``` --- ### **五、远程验证准备** 1. **本地模拟远程** 使用`socat`模拟监听: ```bash socat tcp-listen:9999,reuseaddr,fork exec:./pwnfile ``` 修改脚本连接本地测试: ```python p = remote('127.0.0.1', 9999) ``` --- ### **六、日志分析** 启用`pwntools`完整日志: ```python context.log_level = 'debug' ``` 观察输出是否符合预期(如地址泄漏是否正确、交互时序是否匹配)。 --- 通过以上步骤,90%的本地利用失败问题可被定位。若仍不成功,建议在`CTF`社区(如CTFtime、攻防世界论坛)分享代码片段求助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值