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

Windows PowerShell中栈溢出内存覆盖异常:高十六进制值无法按预期写入

栈溢出攻击中高十六进制值内存覆盖异常的原因与解决办法

问题场景

下述C程序存在栈溢出漏洞,可实施内存覆盖攻击,但在Windows PowerShell中执行攻击命令时,输入\xaa\xbb\xcc\xdd这类高位十六进制值无法覆盖预期内存地址;而输入\x11\x22\x33\x44这类低位十六进制值时,能正常完成预期覆盖。

程序代码

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
    int value = 5;
    char buffer_one[8], buffer_two[8];
    strcpy(buffer_one, "one"); /* Put "one" into buffer_one. */
    strcpy(buffer_two, "two"); /* Put "two" into buffer_two. */
    printf("[BEFORE] buffer_two is at %p and contains '%s'\n", buffer_two, buffer_two);
    printf("[BEFORE] buffer_one is at %p and contains '%s'\n", buffer_one, buffer_one);
    printf("[BEFORE] value is at %p and is %d (0x%08x)\n", &value, value, value);
    printf("\n[STRCPY] copying %d bytes into buffer_two\n\n", strlen(argv[1]));
    strcpy(buffer_two, argv[1]); /* Copy first argument into buffer_two. */
    printf("[AFTER] buffer_two is at %p and contains '%s'\n", buffer_two, buffer_two);
    printf("[AFTER] buffer_one is at %p and contains '%s'\n", buffer_one, buffer_one);
    printf("[AFTER] value is at %p and is %d (0x%08x)\n", &value, value, value);
}

执行命令

.\a.out $(python -c "print('A'*16 + '\xaa\xbb\xcc\xdd')")

异常输出

[BEFORE] buffer_two is at 0061FF0C and contains 'two'
[BEFORE] buffer_one is at 0061FF14 and contains 'one'
[BEFORE] value is at 0061FF1C and is 5 (0x00000005)

[STRCPY] copying 20 bytes into buffer_two

[AFTER] buffer_two is at 0061FF0C and contains 'AAAAAAAAAAAAAAAA¼+ªª'
[AFTER] buffer_one is at 0061FF14 and contains 'AAAAAAAA¼+ªª'
[AFTER] value is at 0061FF1C and is -1499059284 (0xa6a62bac)

原因分析

  • PowerShell编码转换干扰:PowerShell默认以UTF-8或UTF-16处理字符串,当Python输出包含高位ASCII字节(值>0x7F,如0xaa、0xbb)时,这些字节不符合UTF-8的有效编码规则,PowerShell会自动将其替换为Unicode替换字符�(十六进制0xFFFD)。后续控制台代码页(如CP936)的转义进一步改变了字节值,最终传递给程序的不是原始的十六进制字节,导致内存覆盖结果异常。
  • 低位十六进制值无干扰:0x11、0x22这类低位值属于ASCII控制字符,是UTF-8的有效单字节编码,PowerShell不会对其进行修改,因此能正常传递给程序完成预期覆盖。

解决办法

方法1:用Python输出字节流并通过管道传递(需修改程序)

修改程序从标准输入读取 payload,然后用Python直接输出原始字节流,避免PowerShell的编码转换:

# 修改后的程序读取stdin示例(替换原strcpy(buffer_two, argv[1]))
# fread(buffer_two, 1, 20, stdin);

python -c "import sys; sys.stdout.buffer.write(b'A'*16 + b'\xaa\xbb\xcc\xdd')" | .\a.out

方法2:用PowerShell直接构造字节数组转换为字符串

通过PowerShell的字节数组构造原始payload,再用ASCII编码强制转换为字符串,避免编码替换:

$payload = [byte[]]((0x41)*16 + 0xaa, 0xbb, 0xcc, 0xdd)
$payloadStr = [System.Text.Encoding]::ASCII.GetString($payload)
.\a.out $payloadStr

方法3:改用WSL执行

在Windows Subsystem for Linux的bash环境下运行原命令,WSL的字符串处理不会干扰原始字节传递:

./a.out $(python -c "print('A'*16 + '\xaa\xbb\xcc\xdd')")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 12:35:20