编写自己的缓冲区溢出利用程序(2)
这是冯.诺曼计算机体系结构的缺陷.
下面是缓冲区溢出利用的示意图:
i) 函数对字串缓冲区的操作, 方向一般都是从内存低址向高址的.
如: strcpy(s, "aaa.....";
s s+1 s+2 s+3 ...
+---+---+---+--------+---+...+
(内存低址) | a | a | a | ...... | a |...| (内存高址)[iocblog.net 来源]
+---+---+---+--------+---+...+
ii) 函数返回地址的复盖
/ | ...... | (内存高址)
/ +--------------------+
调用函数栈帧 | 0x41414141 |
+--------------------+
| 0x41414141 | 调用函数的返回地址
+--------------------+
/| ...... |
/ +--------------------+ s+8
/ | 0x41414141 |
/ +--------------------+ s+4
被调用函数栈帧 | 0x41414141 |
+--------------------+ s
| 0x41414141 |
+--------------------+
| ...... |
+....................+
| ...... | (内存低址)
注: 字符a的十六进制ascii码值为0x41.
iii) 从上图可以看出: 如果我们用的是进程可以访问的某个地址而不是0x41414141来改写调用函数的返回地址, 而这个地址正好是我们准备好的代码的入口, 那么进程将会执行我们的代码。 否则, 如果用的是进程无法访问的段的地址, 将会导致进程崩馈――segment fault core dumped (段出错内核转储); 如果该地址处有无效的机器指令数据, 将会导致非法指令(illigal instruction)错误, 等等。
4) 缓冲区在heap(堆)区或bbs区的情况
i) 如果缓冲区的内存空间是在函数里通过动态申请得到的(如: 用malloc()函数申请), 那么在函数的栈帧中只是分配了存放指向heap(堆)中相应申请到的内存空间的指针。 这种情况下, 溢出是发生在(heap)堆中的, 想要复盖相应的函数返回地址, 看来几乎是不可能的。 这种情况的利用可能性要看具体情形, 但不是不可能的。
ii) 如果缓冲区在函数中定义为静态(static), 则缓冲区内存空间的位置在非初始化(bbs)区,和在heap(堆)中的情况差不多, 利用是可能的。 但还有一种特姝情况, 就是可以利用它来复盖函数指针, 让进程后来调用相应的函数变成调用我们所指定的代码。
3. 从缓冲区溢出的利用可以得到什么?
从上文我们看到, 缓冲区溢出的利用可以使我们能够改写相关内存的内容及函数的返回地址, 从而改变代码的执行流程, 让进程去执行我们准备好的代码。
但是, 进程是以我们当前登录的用户身份来运行的. 能够执行我们准备好的代码又怎样呢? 我们还是无法突破系统对当前用户的权限设置, 无法干超越权限的事.
换句话来说, 要想利用缓冲区溢出得到更高的权限, 我们还得利用系统的一些特性.
对于unix来讲, 有两个特性可以利用.
i) suid及sgid程序
unix是允许其他用户可以以某个可执行文件的文件拥有者的用户id或用户组id的身份来执行该文件的,这是通过设置该可执行文件的文件属性为suid或sgid来实现的。也就是说如果某个可执行文件被设了suid或sgid, 那么当系统中其他用户执行该文件时就相当于以该文件属主的用户或用户组身份来执行该文件。如果某个可执行文件的属主是root, 而这个文件被设了suid, 那么如果该可执行文件存在可利用的缓冲区溢出漏洞, 我们就可以利用它来以root的身份执行我们准备好的代码。 没有比让它为我们产生一个具有超级用户root身份的shell更吸引人了, 是不是?
ii) 各种端口守护(服务)进程
unix中有不少守护(服务)进程是以root的身份运行的, 如果这些程序存在可利用的缓冲区溢出,那么我们就可以让它们以当前运行的用户身份――root去执行我们准备被好的代码。由于守护进程已经以root的身份在运行, 我们并不需要相对应的
Tag: 缓冲区溢出
文章整理:iocblog
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。