关闭

strcpy构造二进制字符串小问题

1164人阅读 评论(0) 收藏 举报

在缓冲区溢出攻击程序设计中,用Strcpy()构造攻击字符串是很常见的,这两天在做一个小例子的调试过程中,没想到还出了点问题。
以前调试溢出程序时,拿的都是网上的攻击代码,很多时候只要将跳转地址处理好就行,一直没注意这样的小问题,现在认真看了下后,把它给弄明白了。

例子:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

// jmp esp address
#define jmpesp "/x12/x45/xfa/x7f"  

//jmp to shellcode
#define jmpcode "/xEB/xEE"

char shellcode[] ="/x90/x90/x90/x90/x90/x90/x90/x90";

void overflow()

 char name[8];
 char Buff[20];
 memset(Buff, 0x90, sizeof(Buff)-1);

 strcpy(Buff, shellcode);
     strcpy(Buff+12, jmpesp);   
 strcpy(Buff+16,jmpcode);
 strcpy(name,Buff);
 return;
}

void main()
{
 printf("begin overflow!!");
 overflow();
 printf("ok,end!!");
 return;
}

关于上面这个溢出小例子的原意是这样的:
在overflow()中首先为name分配了八字节的空间,先将Buff空间全设置为0x90,然后用来保存超常字符串,当执行strcpy(name,Buff)时导致溢出发生,用jmp esp地址覆盖返回地址,然后执行jmpcode指令,再次跳转至shellcode处执行相应代码。从设计思路以及具体实现上来看,这个程序完全可以达到预期效果,但实际调试中,程序并没有按照预期设想执行,竟能够打印出“ok,end!!”字符串,这是怎么回事?

在跟踪调试的过程中,发现返回地址没有被覆盖,于是查看执行完strcpy(name,Buff)后name所指地址空间的内容,竟然是
"/x90/x90/x90/x90/x90/x90/x90/x90/x00",
竟然有个结束符,把字符串给截断了,只导致EBP被改写,而返回地址并没有改变,使得流程按正常情况执行。

跟踪strcpy执行流程发现,它以四字节在源串与目标串之间拷贝数据,之后对末尾部分处理,本例执行
strcpy(Buff, shellcode)时,
当拷贝完八字节后,比较源串数据后执行如下语句
mov byte ptr [edi],dl
此时edi指向Buff+8,dl值为/x00,因此在strcpy(name,Buff)时就将八字节的/x90和一字节的/x00写入Buff地址,只改写了EBP的一个字节,没有改写到返回地址。

如果如此定义:
char shellcode[] ="/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90";
那么拷贝时产生的末尾/x00字节,将被strcpy(Buff+12, jmpesp)语句拷贝的内容覆盖,成为一个完整的字符串,程序正常溢出,跳转。
ok!

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:42914次
    • 积分:607
    • 等级:
    • 排名:千里之外
    • 原创:13篇
    • 转载:12篇
    • 译文:0篇
    • 评论:13条
    文章分类
    一塊瞎掰