HTB-You know 0xDiablos
引言
- 项目概述:HTB的EASY难度 PWN靶机 You know 0xDiablos https://app.hackthebox.com/challenges/106 本文详细解释了溢出payload的结构以及为什么要这样构造,友好的为想要入手PWN的朋友解释了原理
- 技术点涉及: 32位linux逆向、32位程序调用、栈溢出
- 目标与读者:网络安全兴趣爱好者、PWN新手
基本情况
运行看看
1 | └─$ ./vuln |
输入啥,就吐出啥
使用checksec查一下保护
1 | ─$ checksec vuln |
意思是没有任何保护,实实在在的新手题,可以更聚焦栈溢出的核心原理
逆向分析
将程序放到IDA分析
主函数中发现一个叫做vuln的函数
应该就是目标了gets()
很标准的高危函数
这里有个数组s距离ebp B8H
gets(s),那么就可以利用这个s数组进行溢出junk = b'a'*0xB8
想象下,我们输入了大量垃圾内容,从栈的某个位置一直写到栈的底部,栈底指针EBP指向的是父函数的EBP值,然后EBP+0x4的位置就是存放的当前函数的返回地址(父函数调用当前函数后的下一行指令地址)
是不是多写点就可以改变函数的运行
那么攻击载荷就可以这样大致构建了payload = junk + ebp+ret
很明显,是要我去分析那个flag函数
flag函数打开了flag.txt,如果两个参数比较成功就会返回读取的值
就是说我还得在栈中构建好两个参数
最终的攻击载荷大致就是这个结构payload = junk + ebp+ret + ret2 + arg1 + arg2
call逻辑讲解
这里来讲解下为什么要这么构建payload
由于IDA F5是变成了伪C代码,所以调用约定是C的调用约定
32位程序,参数从右至左,依次入栈
正常call flag的流程如下
1 | push arg2 |
而我要伪造一个call,就需要在栈里面调整好参数的站位,而且要注意我使用ret,而不是call,ret不会push一个地址进去。下面我会详细讲解为什么payload是这样构造的,结构为什么这样排列
1 | 正常call的栈 |
而我要调用flag,就得将返回地址覆盖为flag的地址
大致的载荷构建结构如下
1 | xxxxx垃圾数据 |
而且flag还有参数
1 | xxxxx垃圾数据 |
所以32位的paylaod像这构造
1 | payload = junk + ebp + ret + ret2 + arg1 + arg2 |
发送payload
可以看到刚进flag函数的时候
栈顶的值是这样,这时候还没有执行push ebp
,说明如果这是正常的call的话,这里存放的应该是调用flag()的下一行指令的地址,也就是flag()执行完毕后需要返回的地址,这里的ebp的值是0x62626262
是因为ebp=b'b'*4
,我随便写的四个b在哪里占位置
1 | 0xffce8ac0: 0xdeadbeef63636363 |
完整的poc如下
1 | from pwn import * |