首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
二进制漏洞
发新帖
17
8
[原创]栈溢出基础及利用
发表于: 2021-3-7 21:37
13563
[原创]栈溢出基础及利用
奋进的小杨
2021-3-7 21:37
13563
学习,得向基础看齐。之前面试,别人问了我栈溢出,又问了堆溢出,索性今天就栈溢出基础弄个总结,并结合IDA。希望自己可以有新收获。 ## 1. 栈溢出理论 > 1)我们先回顾一下call和ret指令,可以认为是函数调用栈。 call的操作是,调用一个过程,指挥处理器从新的内存地址开始执行。过程使用ret来将处理器转回到该过程被调用的程序点上。 从物理的角度来解释,call指令将其返回地址压入堆栈,再把被调用过程的地址复制到指令指针寄存器。当过程准备返回时,它的ret指令从堆栈把返回地址弹回到指令指针寄存器。 函数调用栈在内存中从高地址向低地址生长,所以栈顶对应的内存地址在压栈时变小,退栈时变大。  >2)函数调用背景。 函数状态主要涉及三个寄存器--esp,ebp,eip。esp 用来存储函数调用栈的栈顶地址,在压栈和退栈时发生变化。ebp 用来存储当前函数状态的基地址,在函数运行时不变,可以用来索引确定函数参数或局部变量的位置。eip 用来存储即将执行的程序指令的地址。 a.将被调用函数的参数压入栈内  b.将被调用函数的返回地址压入栈内  c.将调用函数的基地址(ebp)压入栈内,并将当前栈顶地址传到 ebp 寄存器内  d.将被调用函数的局部变量压入栈内  e.将被调用函数的局部变量弹出栈外  f.将调用函数(caller)的基地址(ebp)弹出栈外,并存到 ebp 寄存器内  g.将被调用函数的返回地址弹出栈外,并存到 eip 寄存器内  >3)当函数正在执行内部指令的过程中我们无法拿到程序的控制权,只有在发生函数调用或者结束函数调用时,程序的控制权会在函数状态之间发生跳转,这时才可以通过修改函数状态来实现攻击。 我们只需要让溢出数据用攻击指令的地址来覆盖返回地址就可以了。我们可以在溢出数据内包含一段攻击指令,也可以在内存其他位置寻找可用的攻击指令。  自此,栈溢出的基础理论讲完。 >与此相关的技术,有下面这些。 修改返回地址,让其指向溢出数据中的一段指令(shellcode) 修改返回地址,让其指向内存中已有的某个函数(return2libc) 修改返回地址,让其指向内存中已有的一段指令(ROP) 修改某个被调用函数的地址,让其指向另一个函数(hijack GOT) ## 2. 栈溢出利用 1)实验目的:证明存在栈溢出漏洞 2)实验环境:IDA,OD,小程序。 3)要求(个人要求):个人突破,熟练使用IDA和OD。 准备代码如下: ``` #include<iostream> #include<stdio.h> using namespace std; #define PASSWORD "1234567" //The macro defines the value of the password int verify_password(char* password) { int authenticated; char buffer[8]; // add local buffer to be overflowed authenticated = strcmp(password, PASSWORD); //compare the two values strcpy(buffer, password); //over flowed here! return authenticated; } int 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!\n\n"); } else { printf("Congratulation! You have passed the verification!\n"); break; } } return 0; } } } } ``` >**看到代码后,怎样来利用了?步骤是怎样的? 1)运行程序,观察情况,特别需要注意字符串和一些特殊的函数。 2)在上一步的基础上,我们在关键点上设下断点。 3)控制台交互,观察栈的运行情况,从而发现破绽。** 1),导入OD,或者IDA,都可以。当然导入OD,较为简单。这里我选择用IDA,执行本地调试。先执行win32_remote.exe,然后在IDA界面,点击debugger,具体的环境设置,网上很全,当然如果有问题,也可以和我交流。按F9开始执行,看到“please input password:”。这个字符串,很重要,将是我们的突破口。 , (其实用IDA来调试,查看栈的情况,也可以,但是没有OD方便。) 2)通过上一步的字符串,来定位到该位置。alt+T,可以全局搜索该字符串。在00C717D6这里。  搜索到后,选中这一代码段的标记,sub_C717B0,快捷键N,实现改名。  为了进一步确定,我们可以通过查看伪代码,具体的情况,如图。  这里注意到一个关键的函数,sub_C712AD,我们双击进入,看到返回的是另一个函数sub_C71640,我们继续点击,看到了这个代码段。  这里可以确认,密码是“1234567”。有些时候,某些程序的密码就在程序的内部,也有的是一个密码生成器,自动生成,需要逆向算法。j_strcmp是一个比较的接口,j_strcpy是将输入的密码,复制到&Dest上。可以确定这个&Dest就是栈的开头。下图是该栈的情况。   这里有个8很明显。记住。 我们进入OD,Ctrl+G,搜索这个,00C717D6,并F2,下断点。  F9运行程序,可以看到正好停在这里。 这时,我输入“12345678”,这个比正确的密码多了一个8,结果竟然成功了。  这不是重点,重点是观察寄存器的变化。 3)上一步,我们已经设置了断点,输入了8个数,就成功的通过了。我们来单步执行,重点观察一下寄存器。 * 这是输入前,栈的情况  * 输入错误的数据后,栈的情况    * 输入正确的数据后,栈的情况  **这里是不是说明,当我们填充的数据把008FF934填的只剩下两个,就可以了呢。** * 我们再次填入12345678,因为我们已经知道这个密码是可以通过验证的。  * 为了更确信,我们填入123456789,来试试。最后发现错误。  综上分析,当我们把00BEF64C这一行填满的时候,可以实现栈溢出,从而通过验证。为了验证这种猜想,我们再设计一个输入密码,1234567q,试试看,为什么成不成功。   最后的结果都成功了。 后来经过大量的验证,发现如下的密码都可以通过,比如1234567q,1234577q, 1237890q,1234980q,还有很多。但是也有一些是通不过的,比如:1231237q,1233217q等。 **根据逻辑,现在就有两个问题需要解决,1.有些密码可以,有些不可以,那么它是通过什么来判断的呢? 2.为什么当输入的密码溢出栈后,说白了,就是太长,就会报错,而刚刚好我们把栈填满,就不报错呢?** ## 3. 解答上面的问题 #### 第一个问题 通过查阅资料,得到了下面的一些启发。 程序的关键地方是strcpy(buffer,password); 栈内的依次存放的是authenticated、局部变量char buffer[8]。  当我们输入的密码,超过buffer的长度,正好覆盖掉authenticated。而在源代码中authenticated是否等于0,用来说明当前密码正确与否的状态,。转换到汇编代码中,[ebp-4]是否等于0,用来判断密码是否正确。  所以,只需要输入任意八位数字,填满buffer,利用字符截断符NULL来填充[ebp-0x4]的值,就可以绕过密码验证。  #### 第二个问题 当我们输入更长的数字后,会发生什么呢? 首先authenticated会修改,同时后面的EBP和返回地址也会修改,查阅资料上解释的是,程序崩溃,出现异常。但是我觉得不是的。因为当我故意夸大输入的长度时,才会出现奔溃。当我仅仅输入10个数字的时候,是没有出现崩溃的。  至于它的崩溃点是那里,这里可以通过pattern字符来验证,我不做深究。 从逻辑上,可以认为是,当我们输入的长度过长,覆盖了ret,会导致栈无法正常返回,从而堆栈不平衡,导致崩溃。 如果大家对此,有什么好的看法,请私信告诉我。下一篇,堆溢出。
登录后可查看完整内容
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
最后于
2021-3-8 19:52 被奋进的小杨编辑 ,原因:
#缓冲区溢出
#Windows
#Linux
收藏
・
17
点赞
・
8
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
mb_vemlmxkm
感谢你分享这么好的资源!
2026-8-20 19:34
東陽不列山
感谢你的贡献,论坛因你而更加精彩!
2025-9-18 02:07
一路南寻
为你点赞!
2025-6-5 01:14
心游尘世外
为你点赞!
2024-9-26 05:12
QinBeast
为你点赞!
2024-9-25 01:58
飘零丶
看雪因你而更加精彩!
2024-6-28 04:55
shinratensei
看雪因你而更加精彩!
2024-6-27 04:36
PLEBFE
为你点赞~
2023-1-14 04:25
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
7
)
有毒
雪 币:
18082
活跃值:
(17521)
能力值:
(RANK:730 )
在线值:
发帖
56
回帖
533
粉丝
362
关注
私信
有毒
10
2
楼
等待师傅完善,支持
2021-3-8 09:02
0
奋进的小杨
雪 币:
1859
活跃值:
(2290)
能力值:
( LV5,RANK:60 )
在线值:
发帖
15
回帖
35
粉丝
29
关注
私信
奋进的小杨
3
楼
有毒
等待师傅完善,支持
版主,帮帮看看,哪些需要修改的
2021-3-9 09:01
0
SSH山水画
雪 币:
602
活跃值:
(15405)
能力值:
( LV12,RANK:380 )
在线值:
发帖
57
回帖
335
粉丝
412
关注
私信
SSH山水画
3
4
楼
坐等堆溢出
2021-3-10 15:41
0
Fruei
雪 币:
4438
活跃值:
(1853)
能力值:
( LV2,RANK:10 )
在线值:
发帖
1
回帖
19
粉丝
0
关注
私信
Fruei
5
楼
学习了
2021-3-19 08:09
0
wx_A.R
雪 币:
365
活跃值:
(559)
能力值:
( LV3,RANK:30 )
在线值:
发帖
2
回帖
28
粉丝
13
关注
私信
wx_A.R
6
楼
配图简直太好了,一清二楚
2023-10-12 22:16
0
mb_vemlmxkm
雪 币:
265
能力值:
( LV1,RANK:0 )
在线值:
发帖
2
回帖
2
粉丝
0
关注
私信
mb_vemlmxkm
7
楼
可以可以,听了好几节课都没听懂的函数调用栈,这里搞懂了
2026-8-20 20:07
0
yuanyouran
雪 币:
305
活跃值:
(3075)
能力值:
( LV2,RANK:10 )
在线值:
发帖
5
回帖
184
粉丝
0
关注
私信
yuanyouran
8
楼
学习了
2026-9-9 10:09
0
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
奋进的小杨
15
发帖
35
回帖
60
RANK
关注
私信
他的文章
[原创]水獭大模型安全卫士发布:为大模型安全保驾护航
976
[原创]KVM场景制作qcow2文件
2332
[原创]漏洞原理的梳理(不断更新中)
2363
[原创]通过一次演习,产生的对DOS的思考。
2089
[原创]2021腾讯PC客户端初赛题解(对大佬解题手法的学习)
8811
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部