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

Neovim中运行pwntools脚本时io.interactive()进程异常终止

问题描述

使用Python 3.10.x搭配pwntools编写漏洞利用脚本时,代码中的io.interactive()本该启动交互shell,但在Neovim通过!./%命令运行脚本时,交互shell未正常启动,进程直接停止,同时伴随BytesWarning类型的警告。

原代码

#!/usr/bin/python3
from pwn import *

elf = context.binary = ELF("house_of_force")
libc = elf.libc
 
gs = '''
continue
'''
def start():
    if args.GDB:
        return gdb.debug(elf.path, gdbscript=gs)
    else:
        return process(elf.path)
 
# Select the "malloc" option, send size & data.
def malloc(size, data):
    io.send("1")
    io.sendafter("size: ", f"{size}")
    io.sendafter("data: ", data)
    io.recvuntil("> ")
 
# Calculate the "wraparound" distance between two addresses.
def delta(x, y):
    return (0xffffffffffffffff - x) + y
 
io = start()
 
# This binary leaks the address of puts(), use it to resolve the libc load address.
io.recvuntil("puts() @ ")
libc.address = int(io.recvline(), 16) - libc.sym.puts
 
# This binary leaks the heap start address.
io.recvuntil("heap @ ")
heap = int(io.recvline(), 16)
io.recvuntil("> ")
io.timeout = 0.1
 
# =============================================================================
 
# =-=-=- EXAMPLE -=-=-=
 
# The "heap" variable holds the heap start address.
log.info(f"heap: 0x{heap:02x}")
 
# Program symbols are available via "elf.sym.<symbol name>".
log.info(f"target: 0x{elf.sym.target:02x}")
 
# The malloc() function chooses option 1 from the menu.
# Its arguments are "size" and "data".
malloc(24, b"Y"*24)
 
# The delta() function finds the "wraparound" distance between two addresses.
log.info(f"delta between heap & main(): 0x{delta(heap, elf.sym.main):02x}")

# =============================================================================

io.interactive()

错误信息

/home/pegasus/Documents/Courses/HeapLAB-main/house_of_force/./exploit.py:19: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  io.sendafter("size: ", f"{size}")
/home/pegasus/.local/lib/python3.10/site-packages/pwnlib/tubes/tube.py:813: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  res = self.recvuntil(delim, timeout=timeout)
/home/pegasus/Documents/Courses/HeapLAB-main/house_of_force/./exploit.py:21: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  io.recvuntil("> ")
[*] delta between heap & main(): 0xfffffffffebd9816
[*] Switching to interactive mode
[*] Stopped process '/home/pegasus/Documents/Courses/HeapLAB-main/house_of_force/house_of_force' (pid 7496)
解决方案

1. 解决Neovim交互终端限制

Neovim的!./%命令属于非交互式执行,无法支持pwntools的交互shell功能,换用以下方式运行脚本:

  • 直接在系统终端执行:./exploit.py
  • 在Neovim内打开交互式终端运行::terminal ./%

2. 修复BytesWarning警告

pwntools要求所有IO操作必须使用字节类型,修改代码中字符串为字节格式:

  • io.send("1") → io.send(b"1")
  • io.sendafter("size: ", f"{size}") → io.sendafter(b"size: ", f"{size}".encode())
  • io.recvuntil("> ") → io.recvuntil(b"> ")
  • io.recvuntil("puts() @ ") → io.recvuntil(b"puts() @ ")
  • io.recvuntil("heap @ ") → io.recvuntil(b"heap @ ")

修正后的完整代码

#!/usr/bin/python3
from pwn import *

elf = context.binary = ELF("house_of_force")
libc = elf.libc
 
gs = '''
continue
'''
def start():
    if args.GDB:
        return gdb.debug(elf.path, gdbscript=gs)
    else:
        return process(elf.path)
 
# Select the "malloc" option, send size & data.
def malloc(size, data):
    io.send(b"1")
    io.sendafter(b"size: ", f"{size}".encode())
    io.sendafter(b"data: ", data)
    io.recvuntil(b"> ")
 
# Calculate the "wraparound" distance between two addresses.
def delta(x, y):
    return (0xffffffffffffffff - x) + y
 
io = start()
 
# This binary leaks the address of puts(), use it to resolve the libc load address.
io.recvuntil(b"puts() @ ")
libc.address = int(io.recvline(), 16) - libc.sym.puts
 
# This binary leaks the heap start address.
io.recvuntil(b"heap @ ")
heap = int(io.recvline(), 16)
io.recvuntil(b"> ")
io.timeout = 0.1
 
# =============================================================================
 
# =-=-=- EXAMPLE -=-=-=
 
# The "heap" variable holds the heap start address.
log.info(f"heap: 0x{heap:02x}")
 
# Program symbols are available via "elf.sym.<symbol name>".
log.info(f"target: 0x{elf.sym.target:02x}")
 
# The malloc() function chooses option 1 from the menu.
# Its arguments are "size" and "data".
malloc(24, b"Y"*24)
 
# The delta() function finds the "wraparound" distance between two addresses.
log.info(f"delta between heap & main(): 0x{delta(heap, elf.sym.main):02x}")

# =============================================================================

io.interactive()

额外排查点

如果修改后仍存在问题,可检查:

  • 目标程序是否在io.interactive()执行前已崩溃,可添加io.wait_for_close()查看进程退出状态
  • 若使用GDB调试,确保context.terminal配置正确,比如添加context.terminal = ['gnome-terminal', '-e'](根据你的终端模拟器调整)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:10:27