从Python将shellcode作为命令行参数传递
我现在正在为我的同学准备一个关于计算机安全的小演讲。为了让他们对这个话题稍微感兴趣一点,我想展示一下在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)。