沙箱逃逸----切换进程工作模式绕过
这两天打 CSAW 又学到了一种新的沙箱逃逸的方法–切换进程的工作模式,使用32位的系统调用号执行系统调用,来绕过原本沙箱禁用掉的系统调用。理解起来倒也不难,但是有几个点需要注意一下,这里详细的记录下利用过程。
这两天打 CSAW 又学到了一种新的沙箱逃逸的方法–切换进程的工作模式,使用32位的系统调用号执行系统调用,来绕过原本沙箱禁用掉的系统调用。理解起来倒也不难,但是有几个点需要注意一下,这里详细的记录下利用过程。
在PWN的学习过程中,阅读glibc的源代码是一项必备的技能。一方面而言有些问题需要深入到源码中寻找答案,另一方面阅读源码来探究glibc中函数的实现是再合适不过的方法(有很多师傅做了优秀的总结,可不论怎么阅读他人的总结还是不如自己去实际的探究一下),最后一方面,在不断探究和学习源码的过程中其实也在不断的进步并打下基础,如此看来阅读glibc中的源码百利而无一害。但我对于第一次尝试阅读源码的印象颇深,无从下手,不知所措。于是乎我写下了这篇文章,来向当初和我一样入门的师傅们提供一些经验和建议。
之前分析的三个函数文章链接:
这篇是IO函数源码分析四部曲中的最后一个fclose函数(并不是以后不分析了,说实话我感觉分析源码去看看我们平常使用的函数到底是怎么实现的,这个过程很有意思,因此以后有机会的话会再调试一些其他函数,花了四天分析了这四个函数,从最开始分析fopen函数源码的时候懵懵逼逼(那篇文章我基本是纯配合着动态调试才搞懂的整体逻辑),到分析fread函数时对reserve area以及输入和输出缓冲区有了认识,再到基本是对着源码分析的fwrite函数(也是配合着动态调试,不过此时就是静态分析源码为主了),最后到分析fclose函数源码时感觉的异常顺利和自然。真的是分析每个函数时都有不同的感受。
这个fwrite函数中的_IO_write_ptr指针的挪动和fread函数中的_IO_read_ptr指针的挪动是不太一样的。先回顾一下上一篇文章中_IO_read_ptr指针什么时候挪动?当系统调用read的时候从文件中读取多少个字节的数据到输入缓冲区,就将_IO_read_end指针挪动多少个字节 初始值和_IO_read_base是一样的 ,而此时的_IO_read_ptr指针不动。当执行memcpy函数将数据从输入缓冲区拷贝多少个字节的数据到我们指定的内存地址,就将_IO_read_ptr指针挪动多少个字节。在_IO_read_base和_IO_read_ptr之间是已经拷贝过的数据,_IO_read_ptr和_IO_read_end之间是输入缓冲区中还未拷贝的数据。
而本次分析的fwrite函数则是直接将_IO_buf_end的值赋给了_IO_write_end(read的那个指针可不是这样),而_IO_write_ptr的初始值则和_IO_write_base的值一样。该函数先从指定的内存地址读取一定字节的数据到输出缓冲区,此时的_IO_write_ptr指针挪动(我这里以及上下文提到的挪动指的都是在原本的基础上加)相应的字节。此时的_IO_write_base指针和_IO_write_ptr指针之间的区域是将要从输出缓冲区写入文件的数据,而_IO_write_ptr指针和_IO_write_end指针之间的区域是输出缓冲区的可用区域(就是还能再往输出缓冲区拷贝多少个字节的内容),当执行系统调用write往文件中写入一定的字节的内容后,_IO_write_ptr就会减去相应的字节。
上面的内容一定要清楚,不然分析的时候就会陷入误区
前面两篇文章的地址如下:
上一篇分析的是fopen函数,这次来分析下fread函数。
IO学习–源码分析fread函数
house of force是针对top chunk的一种手法,通过这种攻击手法,可以将top chunk更新到任意内存,再次申请堆块并写入数据,这就相当于任意地址任意写了。
关于unlink的学习总结,我打算分成4个部分来说明,分别是unlink的利用整体思路、如何伪造fake_chunk、探究下unlink漏洞是如何实现的、相关题目的WP。我这篇博客并没有画图片来说明unlink的操作,我认为不是特别适合完全不懂unlink的师傅来参考学习,建议去看一些其他师傅一些画图说明unlink的博客,对unlink有个模糊的认识后,再看这篇文章应该效果最好