ret2syscall
ret2syscall
其实在ret2shellcod里我们就已经使用过ret2syscall的类似解法,也就是系统调用但只用了orw,这篇文章来介绍静态链接的elf文件使用gadget构造系统调用execve(“/bin/sh”,NULL,NULL)拿shell
对于i386程序想要系统调用execve(“/bin/sh”,NULL,NULL)需要达成以下条件:
- 系统调用号,即 eax 应该为 0xb,因为是execve所以是0xb
- 第一个参数,即 ebx 应该指向 /bin/sh 的地址,其实执行 sh 的地址也可以。
- 第二个参数,即 ecx 应该为 0
- 第三个参数,即 edx 应该为 0
- 最后int 0x80 系统调用
接下来就用ROPgadget来找对应gadget
1 | ROPgadget --binary pwn --only 'pop|ret' | grep 'eax' |
找齐之后可以开始构造payload
pwn71
该题要注意偏移ida上给出的有误故使用gdb调试
1 | gdb pwn |
通过观察汇编可知此时起始地址相对于esp的偏移为0x1C
1 | .text:08048E8F 8D 44 24 1C lea eax, [esp+1Ch] |
故返回地址的偏移为 ebp地址-esp地址-esp距起始位置的距离+4(ebp)
即0xffffd1d8-0xffffd150-0x1c+4=112
exp:
1 | from pwn import * |
pwn72 多系统调用
该题依旧是静态编译,但没有/bin/sh字符需要先调用read读入一个/bin/sh再进行系统调用
1 | from pwn import * |
pwn73一把梭
本来已经用ROPgadget写出一把梭了但是看着怪怪的以为没跑出来回去用老方法没打通不知道是哪有问题
该题有明显栈溢出,静态编译
使用该指令自动构造ROP链
1 | ROPgadget --binary pwn --ropchain |
1 | ROP chain generation |
exp:
1 | from pwn import * |
我自己写的但是没跑通,有师傅看到的话可以指点一下吗
1 | from pwn import * |
pwn74one_gadget
该题主要用于科普one_gadget,麻烦的点在于它没有给libc,群里又没找到,只有到libc database search上对着wp试
check
1 | 桌面$ checksec pwn |
找到的libc是这个libc6_2.27-3ubuntu1.6_amd64.solibc database search
main函数:
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
发现会输出printf的地址可以用来找libc基地址
此处v4[0],v4[1]绕来绕去的最后也不知道是调用哪的函数,直接选择看汇编
1 | .text:00000000000008F2 48 8D 45 E8 lea rax, [rbp+var_18] |
直接从call rdx反着往上看,call的地址就是我们输入的数据
查看one_gadget
1 | 桌面$ one_gadget libc.so |
通过gdb调试可以发现,当运行到call rdx时rsp+0x70处的值为零,而rsp+0x40处不为零,故只要输入onegadget的地址0x10a2fc+libc_base作为[rbp+var_18]后续call该地址处的值时即可get shell
完整exp
1 | from pwn import* |
%ld 要求输入的是一个长整型值的字符串表示故将地址转换成字符串形式使得能够正常读入。