2.栈溢出简单利用

看代码

#include <stdio.h> #include "windows.h" #define PASSWORD "1234567" int verify_password(char *password) { int authenticated; char buffer[8]; authenticated=strcmp(password,PASSWORD); strcpy(buffer,password); return authenticated; } int main() { int valid_flag=0; char password[1024]; while (1) { printf("请输入密码:"); scanf("%s",password); valid_flag=verify_password(password); if (valid_flag) { printf("错误!\n"); } else { printf("正确!\n"); break; } } return 0; }
会点C语言就能看懂吧,有个验证密码是否正确的函数

要注意的一点是要关闭编译时的GZ选项,VC6以上版本关闭GS编译选项

具体方式:vc6工程-设置-c/c++-工程选项里面去掉GZ

vsC/C++ 代码生成 缓冲区安全检查 否

生成程序输入密码,当输入的为8位但是数值比1234567大时均会通过验证,这是为什么呢?

拿到OD中看下

当输入12345678时,堆栈中如下所示

0012FB18 34333231 ;4321 0012FB1C 38373635 ;8765 0012FB20 00000000; ;authenticated 0012FB24 /0012FF80; ;ebp


strcmp之后authenticated的值为0000001,strcpy函数用字符串12345678最后一个NULL给覆盖了这个值,所以会通过验证
当我们输入01234567时,因为比1234567小,所以strcmp会返回-1.补码为0xFFFFFFFF,OD中看下

0012FB18 33323130 ;3210 0012FB1C 37363534 ;7654 0012FB20 FFFFFF00 ;authenticated 0012FB24 /0012FF80 ;ebp
authenticated为FFFFFF,所以还是不会通过验证的
另外问下为什么我OD中那些像strcpy什么的函数都识别不出来,CALL的都是一个模块内的地址
是不是符号的问题?


下面我们再换种方式

#include <stdio.h> #include "windows.h" #define PASSWORD "1234567" char *p={ "\x12\x12\x12\x12\x12\x12\x12\x12"//buffer "\x34\x34\x34\x34"//authenticated "\xaa\xaa\xaa\xaa"//ebp "\xbb\xbb\xbb\xbb"//eip }; int verify_password(char *password) { int authenticated; char buffer[8]; authenticated=strcmp(password,PASSWORD); strcpy(buffer,password); return authenticated; } int main() { int valid_flag=0; char password[1024]; while (1) { printf("请输入密码:"); scanf("%s",password); valid_flag=verify_password(p); if (valid_flag) { printf("错误!\n"); } else { printf("正确!\n"); break; } } return 0; }
为了方便测试直接在程序内定义一个字符串,这样编译运行后会弹出一个引用的0xbbbbbbbb内存不能 为read错误,原因就不多说了。

我们把这个0xxbbbbbbbb改为输出正确的分支就可以,拖到OD中找到输出正确的地址,是0x00401106,替换掉就OK 。

运行下就会输出正确了,不过程序之后会崩溃掉,因为栈内EBP被覆盖为无效值,使得程序在退出时堆栈无法平衡。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值