Linux Buffer Overflow
前置基础知识
本文记录学习ctf-wiki的实验过程
https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/stackoverflow-basic-zh/
- 汇编中
CALL
与RET
指令 - 汇编中高级过程,通过堆栈传递函数参数
- 汇编中的函数调用过程及堆栈变化
- gdb使用方法
环境准备
- [+]ubuntu
- [+]关闭ASLR。修改/proc/sys/kernel/randomize_va_space文件
- [+]gcc + gcc-multilib
- [+]pwntools
- [+]pwngdb(gdb插件)
测试代码
1 |
|
编译程序
1 | gcc -m32 -fno-stack-protector overflow.c -o example |
-m32
执行编译程序为32位程序-fno-stack-protector
关闭栈溢出保护-o
编译后输出的文件名
调试过程
下断点
在gdb中利用函数下断点b vulnerable
,函数断在vulnerable入口
逐步执行到0x56556239
,输入过量的字符
继续向下,其中注意栈中的数据覆盖情况,由于输入了过量的字符,缓冲区空间被填满并溢出,溢出的数据将缓冲区后面的地址覆盖
继续向下执行查看vulnerable函数的RET指令返回地址,返回地址信息为0x7271706f
,该地址信息是连续递减的16进制数字,转换为ascii为rqpo
。在计算机中,由于小端显示会将正常的输入翻序,所以原信息为opqr
,正好对应上图栈地址中0xffffd04c
的内容,而该地址是ebp+4
。
根据汇编中的RET指令的原理,如果将RET跳转的地址信息进行覆盖,覆盖为一个有效的命令执行地址,那就可以控制程序的执行过程,从而执行我们希望执行的指令。
构造利用代码
通过数有次序的字符,可以猜出缓冲区的大小。这个题中缓冲区大小为20个字节,所以要先用20个字节将缓冲区填满\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41
,再对EBP
进行覆盖\\x42\\x42\\x42\\x42
,再拼接要跳转小端显示的地址(该题目要求跳转到success函数中,可以通过IDA Pro等逆向工具获取success函数的内存地址,我是通过在gdb中对success下断点获取到的内存地址),原地址为0x565561ed
,经过小端显示处理后为\\xed\\x61\\x55\\x56
,将这三个部分进行拼接得到payload
1 | \\x41\\x41\\x41\\x41\\x41\\x41\\x41\\x41 |
因为这里的\xed是非打印字符,所以我采用python发送的方式进行调试,利用pwntools进行输入。
在调试器中成功执行。
利用pwntools编写利用代码
1 | # -*- coding=utf8 -*- |
总结
- [+] 目前只在调试器中成功执行,在脱离调试器后还无法显示结果,正在努力解决。
- 目前对pwntools还不太了解,要熟练掌握。