一直对白帽技术情有独钟,无奈囿于环境、圈子等因素,总是管中窥豹,不得法门。也许这个圈子很小众,没多少人愿意或者有精力与时间去深入其中吧。大神们可能都在哪个偏僻的角落苦练内功呢,没成立几个门派、没招收弟子吧。况且,软件厂商谁都不愿意把漏洞及利用方法公之于众,法律层面也不允许利用系统缺陷牟利,红客黑客等被不论是否被招安都不愿意去公开杀手锏,更不愿意不经意间再搞一个“熊猫烧香”出来,反而误了卿卿性命。当然,希望还是要有的,总有那一小撮人,不愿随波逐流,不辞昼夜地做一些“无所谓”的试验,如与哪位过客有缘,愿意指点一二,仍旧十分感激!
前期翻书研究了一下Linux系统的内存管理,获益良多,很受鼓舞。遂想深入尝试一下栈溢出漏洞(stack overflow),并得闲研究了一番。本想待探索得有点眉目后再发布结果出来,哪怕是阶段性的验证结果,无奈纵使尽浑身解数,也未能得愿。姑且当做一次小试牛刀吧,虽中途折戟,铩羽而归,但验证了一些什么,毫不后悔,“我来了,我看见,我没有征服”O(∩_∩)O哈哈~,只得总结下经验教训供大家借鉴吧。
网上讲述堆栈溢出漏洞原理多如牛毛,涉及到的例子也比较多,可实际可行、经得起上机验证的并不多,很多还得自己琢磨着组装。也许是因为Linux内核的版本也在不停地更新完善,致使各类版本的栈溢出代码已经失效了。
Linux系统进程的内存布局大体如下:
内核区 线性地址大于0xC000 0000 |
Linux内核 | 高地址 ↑ ...... ↓ |
命令行参数及环境变量 | 变量区 | |
栈 用于保存函数调用参数、调用返回地址、caller基地址、callee局部变量,当然还有canary值等 |
栈底 ...... 栈顶 |
|
堆 malloc、new等申请的内存 |
堆 | |
未初始化或初始化为0的全局变量区 | .bss |
|
已初始化的全局变量、静态(局部)变量 | .data | |
常量区 | .rodata |
|
代码区 | .text |
在进程运行期间,进程在自身线性地址内存空间的布局大体如此表,值得注意的是:并不是所有的常量都会被保存到rodata段,存在一些特殊情况:
- 有些立即数会直接编码到指令里,位于代码段;
- 重复的字符串常量会合并,程序中只保留一份;
- 某些系统中rodata段会被多个进程共享,用于提高空间利用率。
另外,有的嵌入式系统中,rodata不会加载到RAM中,而是直接在ROM中读取。