首页
社区
课程
招聘
[原创][分享]Pwn从入门到放弃(二)
发表于: 2019-12-28 22:15 9069

[原创][分享]Pwn从入门到放弃(二)

2019-12-28 22:15
9069

该题目是AliCTF 2016中一道题,vss

第一步:
checksec看一下该程序开了哪些保护:

图片描述

同样也是64位小端,只开启了RELOR和NX两项保护。

第二步:
运行该程序看看:

图片描述

让输入一段password,随便输入了几个字母,没有任何正确和错误的提示

*第三步:
用gdb调试看看:

图片描述

发现崩溃在了0x401124处,movzx eax,BYTE PTR [rbp+rax*1-0x40],但似乎无法计算溢出位置。

第四步:
将该程序丢到IDA看一下:

图片描述

发现函数无法识别,应该是使用了strip将符号信息做了剔除。程序定位在了start处。

知识点1:strip,简单的说就是给文件脱掉外衣,具体就是从特定文件中剥掉一些符号信息和调试信息,使文件变小。

第五步:
寻找main函数入口,这里有两种方法,一种是通过经验判断,在start末尾处的call,应该是libc_start_main函数,而其上方处offset sub_4011B1应该就是main函数了。另一种是,直接shift+F12通过字符串查找“password”,找到main函数。
图片描述

第六步:
进入main函数后,F5查看伪代码:
图片描述

其中sub_473EA0应为read函数,猜测应该是用于读取password的输入。

在进入sub_40108E函数时,发现了对于读取输入值后的逻辑判断:

图片描述

如果是以“py”开头,则直接返回,后面的循环判断看的懵,没办法,C/C++功底太差,@_@

图片描述

另外,在40108E函数中看到疑似strncpy的函数。

知识点2:strncpy函数是将输入内容的指定长度字符串复制给一个字符串数组中,代码举例:

第七步:
动态调试看看吧,因为我使用的是linux的虚拟机,因此需要使用IDA来远程动态调试。

图片描述

在sub437EA0和sub40108E处下个断,输入70个"A"和10个"1",然后动态跟一下栈状态:

输入70个"A"和10个"1"时的,栈帧状态:

当进入sub40108E后,完成strncpy后的栈帧状态:

发现RBP和返回地址已被覆盖,因此可以得知73~80个字符可以覆盖返回地址,在完成strcpy后,会将所输入的内容逐个字符与66h进行异或,然后最终报错:

RBP+RAX的值刚好位于了只读的区域:

第八步:
由于可控可执行的栈空间73~80(8个字节),因此需要利用stack pivot技术将栈顶上移到main栈帧空间中利用(因为main函数申请了400h的空间),然后再构造ropchain:

图片描述

第九步:
程序由于没有引入libc.so,因此只能考虑使用程序中的syscall,利用syscall来调用所需的函数。

图片描述

知识点3:关于syscall的调用方法,可以参看syscall调用表

第十步:
栈溢出布局思路(自带画图工具凑合画的):

图片描述

另外,由于需要使用syscall来调用所需函数,因此需要为syscall调用时的参数进行布局,上篇文章已经提过了,关于64位寄存器,依次是rdi、rsi、rdx、rcx、r8、r9,而read和sys_execve都是需要三个参数的,所以我们们要找到类似pop rdi、pop rsi、pop rdx的命令来控制三个参数。

代码一:

代码二:


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2020-1-2 17:14 被bugchong编辑 ,原因:
上传的附件:
  • vss (793.28kb,34次下载)
收藏
免费 4
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//