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

本文通过一个具体的缓冲区溢出示例,详细分析了使用Strcpy时遇到的问题及解决方法。示例中,作者尝试利用Strcpy构造攻击字符串来触发溢出,但由于字符串结尾的/x00字符导致溢出失败。通过调整shellcode长度解决了该问题。
摘要由CSDN通过智能技术生成

在缓冲区溢出攻击程序设计中,用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!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值