栈溢出进阶(二):

发布于 2023-04-01  230 次阅读


一:stack pivot ( 64位程序栈劫持)

原理:

之前的文章讲过32位程序的栈劫持,原理一样

主要是利用leave ret

栈溢出时我们把rbp覆盖为fake rbp(假rbp),返回地址改为leave ret, 第一次函数正常执行leave ret进行mov rsp,rbp ; pop,rbp,此时rbp就指向了假的rbp,也就是我们构造栈的rbp位置,然后此时rsp指向返回地址里的是leave ret,pop eip,再次执行leave ret ,进行mov rsp,rbp ;pop rbp ,就把数据执行流劫持到我们构造的payload所在的栈中。由于此时pop 了一次rbp,rsp指向的位置为rbp+8的位置,这个位置是栈顶。所以减去偏移距离同时还要减去8。此时pop eip,就执行了栈顶的数据。完成了两次leave ret。成功劫持数据执行流来执行我们的payload。

栗题:

缓冲区大小0xE0,rbp长度为0x8,返回地址长度为0x8,read只能读入0xF0,0xF0=0xE0+0x8+0x8。刚刚覆盖rbp和返回地址。

动态调试看rbp距离我们写入地址的距离。

是在dca0处读入数据。

old rbp 与我们输入字符串的距离是我们想要的。能泄露的也是这个地址 。 d90 -ca0=F0,前边原理说过减过偏移距离后要再减去8。即F0-8。

先来泄露出canary值与栈顶的地址。

由于这个程序本身没有调用system,要想getshell的话先执行system binsh,所以需要先泄露libc地址。

程序有puts ,接下来找pop rdi,一般pop r15下半部分拆开单独拿出来就是pop rdi。 再找到leave ret ,main 函数地址。开始构造payload来泄露puts的libc。

泄露完libc程序会再次回到main函数,这次就会直接getshell,不过这次是控制程序泄露完libc再回到main函数,栈会被抬高。先判断抬高的栈距离我们第一次泄露的栈有多远。

先打印出原先的栈

再gdb调试输入aa看buf的地址为多少

之前的栈是f0a8,抬高的栈是efd8。偏移为0xD0字节。开始构造第二个payload。

exp:

二:SROP

sigreturn 系统调用号为0xF。

原理:

深一点讲:

因此我们可以跳过①②两个步骤,自己在栈上布置上下文

sigreturn系统调用代码的存放位置。

内核会根据上下文(Sigreturn Farme)的内容来恢复对应的寄存器。

例题:

main函数中的vuln函数:

可以看出调用read和write都是通过syscall来调用的,没有leave 只有retn,不用覆盖ebp,是buf缓冲区和rsp直接相连的。

可以看到该gadgets汇编代码是把rax设置为0xF,其实就是调用15号系统调用,也就是sigreturn。记下gadgets地址0x4004DA

动态调试看write能泄露的东西。

write和read的位置是一样的,dd60,查看write打印出的30个字节

我们可以通过这个地址来泄露栈地址,因为binsh是存在栈中,泄露出来栈计算偏移也就相当于我们知道了binsh的位置。

之后来调用SROP,将rax设置为59,rip设置为syscall,再将rdi设置为binsh的地址。就能getshell,在此之前先泄露栈地址。

gdb调试时可以看到

接下来泄露栈地址计算偏移。

泄露的地址后四位是ec68,动态调试write与read地址一样,后四位为eb50,偏移为ec68-eb50=0x118 ,那么binsh的位置就是栈地址减去0x118

接下来构造第二个payload

用binsh覆盖缓冲区,接着先调用gadget把rax设置为0xF,再调用syscall,然后syscall调用frame,frame也就是我们构造的上下文(Sigreturn Farme),发送即可 getshell。

除此之外,我们有时也可以通过调用setcontext函数来进行SROP,在Glibc2.27 环境下我们一般用setcontext+53来完成SROP。

但是当GLibc发生变化时,setcontext代码也会有所变化,这种方法一般都是结合堆来利用。

SROP利用方式总结

首先要通过栈溢出控制栈的内容,结合堆的话就当前边没说。接着需要知道相应的地址。 有些题把59号系统调用exceve禁用了 ,这种情况下就需要通过orw(open read write)来得到flag。又可以通过mprotect来划出一片可读可写可执行的区域,利用 shellcode来orw,得到flag。


穿过云层我试着努力向你奔跑