首页
论坛
课程
招聘
《汇编语言详解与二进制漏洞初阶》
01.栈溢出实验-临近变量淹没
## 一.实验环境: ``` 操作系统 Windows XP SP3 开发环境 VC++ 6.0 调试器 Ollydbg ``` ## 二.实验代码: ``` #include <stdio.h> #include<string.h> #define PASSWORD "1234567" int verify_password (char *password) { int authenticated; char buffer[8]; authenticated=strcmp(password,PASSWORD); strcpy(buffer,password); return authenticated; } main() { int valid_flag=0; char password[1024]; while(1) { printf("please input password: "); scanf("%s",password); valid_flag = verify_password(password); if(valid_flag) { printf("incorrect password!nn"); } else { printf("Congratulation! You have passed the verification!n"); break; } } } ``` ## 三.溢出原理 程序未对输入的密码进行长度检测,接收密码的缓冲区只有8,而输入的密码最长可以输入1024。判断密码是否正确的变量authenticated存储在栈中,当输入的密码长度大于8时,输入的字符串将冲破缓冲区,淹没authenticated所处的位置。当密码错误时authenticated的值是1,正确的时候authenticated的值是0.这就意味着我们可以构造一个合适的输入字符串来改变判断结果。 ## 四.实战调试 我们的重点不是逆向工程,而是漏洞分析,故此不再详诉诸如寻找main函数等逆向知识。 1.在jmp mai下断点,方便后续反复调试 ![图片描述](/upload/attach/201811/201811281016_RSU94EXGY2ANDNK.png) 2.单步步入main函数分析程序 ![图片描述](/upload/attach/201811/201811281017_J23FBFCJTGBB57B.png) 3.分析main函数逻辑,可以看出主要问题出在密码比对函数00401005 3.1输出引导字符串后,要求用户输入密码。 ![图片描述](/upload/attach/201811/201811281017_9GPNXMB4X9DGTHS.png) 3.2通过00401005处的函数进行密码比对 ![图片描述](/upload/attach/201811/201811281018_XXU7U29EPD6884H.png) 3.3判断比对结果是不是0,如果是0则输出成功字符串,如果是1则输出失败字符串。 ![图片描述](/upload/attach/201811/201811281018_8E4XWEYCR9399GM.png) 4.单步执行程序,随便输入一个密码,然后单步步入00401005函数,分析这个函数的内容。 ![图片描述](/upload/attach/201811/201811281018_KR39VDTCXVPQNB9.png) 4.1可以看出这个00401005是个跳转,直接单步进入函数真实位置。 ![图片描述](/upload/attach/201811/201811281018_MDE763Y9E9US7A8.png) 4.2进入到函数内部后可以看到真正的密码是1234567,如果我们是在逆向破解这个程序,那么到了这一步,就已经算是成功了。但是我们的目的是分析漏洞,所以我们现在进一步分析这个函数。 ![图片描述](/upload/attach/201811/201811281019_KZ8WYXPAS5VBT92.png) 4.2.1可以看出,在strcmp之后,ebp-4的位置上就有了密码比对的结果 4.2.1.1strcmp比对密码,将比对结果存入ebp-4的位置上 ![图片描述](/upload/attach/201811/201811281019_D4KJNBPM4SHJYVC.png) 4.2.1.2栈中的密码比对结果 ![图片描述](/upload/attach/201811/201811281019_CEPWYM3SUZQR85S.png) 4.2.2如果是正常的程序,这个时候就应该返回了,但是因为是实验代码,所以下面还有一个strcpy的拷贝函数,将输入的密码字符串拷贝入一个长度为8的缓冲区中。 ![图片描述](/upload/attach/201811/201811281019_JEUJVBG2UAXBGUW.png) 4.2.3当执行完strcpy的时候我们看一下堆栈区,可以看到字符串缓冲区的位置就在密码字符串比对结果旁边,并且strcpy没有对拷贝入的字符串进行长度判断。因此我们可以判断,我们在构造一个合适的字符串传入的情况下,是可以覆盖密码字符串比对结果的。这也意味着我们可以传入一个合适的字符串来冲破密码验证。 ![图片描述](/upload/attach/201811/201811281020_FBYCZBNZTXJSPXB.png) 5.我们重新加载这个程序,并且传入一个特定的字符串“qqqqqqqq” ![图片描述](/upload/attach/201811/201811281020_PHZM85HZWD9Y95G.png) 6.运行到密码比对函数进行分析 6.1可以看出strcmp函数没有任何问题的执行成功并且返回了1,代表密码错误。并且把存储在eax中的返回值存储到ebp-4的位置上。 6.1.1函数执行 ![图片描述](/upload/attach/201811/201811281020_M8GBB2SETAADX47.png) 6.1.2返回值存储在eax中 ![图片描述](/upload/attach/201811/201811281020_GF6P7K8ZE3U5KK7.png) 6.1.3 eax中的值mov到了ebp-4的位置上 ![图片描述](/upload/attach/201811/201811281020_JFTRC4N2YQ65636.png) 6.2下面到了引起溢出错误的strcpy函数,详细分析该函数溢出的过程。 6.2.1首先记录一下strcpy没有执行前堆栈的情况 ![图片描述](/upload/attach/201811/201811281021_843XH6HCP65AQS6.png) 6.2.2 执行strcpy函数 ![图片描述](/upload/attach/201811/201811281021_CUN3HG8CABXJW98.png) 6.2.3 可以看到,堆栈中原本保存着密码比对结果的位置ebp-4,由于传入字符串超长,已经被覆盖成了0。这样一来,原本比对失败的结果就变成了比对成功。 ![图片描述](/upload/attach/201811/201811281021_W7S2DVTN48WKWHS.png) 7.运行至返回,成功输出密码比对成功的信息 ![图片描述](/upload/attach/201811/201811281021_K78ETMGTJZ8E9CN.png) 7.1控制台成功信息 ![图片描述](/upload/attach/201811/201811281022_2SXAPW82MUSS7HU.png) 8.那么是任何长于1234567的字符串都可以成功覆盖比对结果吗,尝试一下,输入9个q,可以看到,对比结果的位置上并没有被覆盖成00,而是71,而只有对比结果等于0才可以成功验证。这说明不是任意长度字符串都可以。 ![图片描述](/upload/attach/201811/201811281022_ZWAU98TSFPEPZFK.png) 9.那么有什么结果可以覆盖成整好是0呢,那么答案是长度为8的字符串,长度为8的字符串实际长度为9,因为还有用来标记字符串结束的00,我们就是要使用结尾处的00来覆盖对比结果,使其数值为0。 ![图片描述](/upload/attach/201811/201811281022_76KK6WHB964G6JP.png) 参考材料:《0day安全:软件漏洞分析技术》

上一节 :
下一节 :
章节评论 (9)
浮尘小生 2018-11-28
 举报
竟然看懂了( ̄∀ ̄)
Littlebirds 2018-11-29
 举报
希望老师有时间了继续更新,这个例子真好,我在将.exe文件放到ollydbg里面调试时,发现反汇编窗口汇编代码太多了,花了不少功夫才找到jmp
怎么能快捷的找到需要那行代码啊?
hacker一疒亻 2019-8-11
 举报
是不是可以这样理解:我将这样一个有漏洞的程序分发给某个目标主机,只要他运行了,是不是就可以控制这台主机了?我的意思是说,这样有漏洞的程序,在编译的时候,能编译过去么?
www明天 2019-12-19
 举报
微软从VS2013开始,就强制使用    scanf_s,    gets_s等输入
aniston 2020-1-11
 举报
我在vs2012上用C++编写测试程序,运行时输入8个q,对比结果失败。提示溢出。
是语言的问题(只能用C编写测试程序才能实现上述效果),还是编译环境的问题(vs2012有什么默认的栈溢出检测机制)?
【讲师回复】 如果流程没问题,那么就是环境配置有问题
2020-1-13
wx_小彬 2020-4-8
 举报
看的有点迷迷糊糊的,虽然最终看懂了。我是不是要回头把汇编学好一点。
wx_T_380 2020-5-8
 举报
吃瓜群众
mb_zwdrvtyi 2020-7-3
 举报
@aniston  可能是你用的是64位的,改成32位的试试TDM-GCC  4.6.1  32-bit
随风而行12 2020-7-10
 举报
牛逼,老师V武
域名:加速乐 | SSL证书:亚洲诚信 | 安全网易易盾| 同盾反欺诈| 服务器:绿盟科技
©2000 - 2020 看雪学院 / 沪ICP备16048531号-1 / 沪公网安备 31011502006611号