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

为何含空字节的栈溢出Payload无效?如何填充0x00001292至返回地址

缓冲区溢出中空字节导致失败的问题分析与解决

问题背景

我在学习缓冲区溢出技术,编写的silly_password.c程序中,check_authentication函数因使用strcpy存在栈溢出漏洞,可通过命令行参数覆盖函数返回地址。目前已成功用AAAA...将返回地址填充为0x41414141,但需要将返回地址填充为目标指令地址0x00001292时遇到问题:

  • 使用命令gdb -q --args silly_password $(perl -e 'print "\x92\x12" x 20;')时,栈被0x12921292填充且溢出成功;
  • 但使用含空字节的命令gdb -q --args silly_password $(perl -e 'print "\x92\x12\x00\x00" x 20;')时,栈未发生溢出。

相关代码:

int check_authentication(char *password) {
    char password_buffer[16];
    volatile int auth_flag = 0;
    strcpy(password_buffer, password);
    if(strcmp(password_buffer, "brillig") == 0)
        auth_flag = 1;
    if(strcmp(password_buffer, "outgrabe") == 0)
        auth_flag = 1;
    return auth_flag; // 此处为栈布局中的返回地址位置
}

原因分析

1. Shell命令行参数的截断行为

Shell在处理命令行参数时,会将空字节\x00视为字符串结束符。当你用$(perl ...)生成含\x00的字符串时,shell只会传递\x00之前的内容给程序,也就是\x92\x12,后续的\x00\x00完全被截断,导致传入程序的payload长度不够,无法覆盖返回地址。

2. strcpy的停止复制特性

即使程序能收到含\x00的参数,strcpy函数本身也会在遇到\x00时立即停止复制,不会继续往缓冲区后方(包括返回地址所在的栈位置)写入数据,自然无法触发溢出覆盖。

解决方法

方法1:利用栈原有空字节,仅覆盖低地址位

32位程序中,栈的高位地址通常默认是0。如果目标地址0x00001292的高两位本来就是栈上的原有值(空字节),你只需要覆盖返回地址的低两位即可:

  1. 先计算从缓冲区到返回地址的填充长度:比如password_buffer是16字节,加上auth_flag的4字节,再加上ebp的4字节,总共需要填充16+4+4=24个字节才能到达返回地址位置;
  2. 生成payload:perl -e 'print "A"x24 . "\x92\x12"',这样返回地址的低两位被设为0x1292,高两位保留栈上原有的0x0000,最终组合成目标地址0x00001292。

方法2:绕过命令行,用文件/标准输入传递payload

命令行无法传递含空字节的字符串,改用标准输入或文件输入可以完整传递payload:

  1. 生成包含空字节的payload到文件:
    perl -e 'print "A"x24 . "\x92\x12\x00\x00"' > payload.bin
    
    (注意:这里的24是示例填充长度,需要根据实际栈布局调整)
  2. 在gdb中运行程序,从文件读取payload:
    gdb -q silly_password
    run < payload.bin
    
    这种方式下,程序会读取文件中的所有字节(包括\x00),strcpy会完整复制直到缓冲区溢出,覆盖返回地址。

方法3:寻找无空字节的等价指令地址

如果目标地址0x00001292的空字节无法绕过,可以查找目标指令的其他可访问地址——比如程序的代码段中,有没有其他偏移指向同一个指令,且地址不含空字节;或者利用跳转指令(如jmp esp、call eax等)的非空地址,再构造后续payload跳转到目标指令。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:57:36