从Python将shellcode作为命令行参数传递

1 投票
1 回答
2913 浏览
提问于 2025-04-16 17:46

我现在正在为我的同学准备一个关于计算机安全的小演讲。为了让他们对这个话题稍微感兴趣一点,我想展示一下在C语言中错误使用strcpy函数是如何被利用的。以下是这个有漏洞程序的代码:

#include<string.h>
#include<stdio.h>
void function(char *buffer1)
{
 char buffer2[5];
 strcpy(buffer2,buffer1);
}

int main (int argc, char **argv)
{
 function(argv[1]);
 return 0;
}

我仅仅通过命令行就能让这个应用崩溃,方法是用以下命令调用它:

test.exe ABCDEFGHIJKLMNOPQRSTUVWXYZ

这让我得到了正确的0x4D4C4B4A(MLKJ)作为EIP(指令指针)。如果我从Python调用它也能成功:

os.system("test.exe ABCDEFGHIJKLMNOPQRSTUVWXYZ")

不过,如果我想把一个地址放在JKLM的位置,比如这样:

 os.system("test.exe ABCDEFGHI\x75\x9a\x21\x1bNOPQRSTUVWXYZ")

那么在栈的ESP附近我得到了以下输出:

0028cca0  e4 21 d7 41 42 43 44 45-46 47 48 49 75 c2 9a 21  .!.ABCDEFGHIu..!
0028ccb0  1b 4e 4f 50 51 52 53 54-55 56 57 58 59 5a 00 00  .NOPQRSTUVWXYZ..

这里的75 c2 9a 21很重要,因为它几乎是我预期的结果,除了0x1B(这是ASCII字符中的ESCAPE),被0xC2替代了。当我改变地址的顺序,让它看起来像这样:\x21\x1b\x75\x9a时,9a又被同样神秘的C2替代了。有没有人知道代码出了什么问题?我是不是漏掉了什么基本的点,还是这是一种防止基于栈的缓冲区溢出的保护措施?

谢谢,

1 个回答

1

看起来你的文本正在进行UTF-8转换。请注意,你原来的字节:

75 9a 21 1b
   ^^

被替换成了

75 c2 9a 21 1b
   ^^^^^

我已经标出了UTF-8编码的字节。如果你在用Python 3,可以试试:

os.system(b"test.exe ABCDEFGHI\x75\x9a\x21\x1bNOPQRSTUVWXYZ")

这里的b""表示这些数据是一串字节,不应该从Unicode转换成默认编码(在你的情况下,似乎是UTF-8)。

撰写回答