一些pwn
……
ret2text
checksec
32位,未开启canary,开启了NX
丢到ida里面看一下
可以看到vulnerable函数里有gets函数,读到的值传到buffer里,距离ebp16个字节写exp
看到getshell函数首地址为
打通。
ret2shellcode
checksec一下
32位文件,未开启canary保护,未开启PIE,具有RWX段。
丢到ida
定义了一个字符型数组s,gets输入到s,并将s的0x64位字节数据赋给buf2
在gdb中发现gets函数的栈帧长度为0x92字,esp存储的是一个指针,可以看到数据是从0xffffd01c开始填充
通过python可以算出需要填充108 + 4 个垃圾字节,再加4个字节的数据——返回地址
找到全局变量buf2的地址
写脚本
1 | from pwn import * |
得到了本地程序的shell
ret2syscall
checksec
看到32位程序,开启了RELRO
no ret2text no ret2shellcode
丢到ida里
看到gets()函数
v4与ebp相距0x64 = 100
gdb动态调试一下
看到填充位置与ebp相差0xa8 - 0x3c = 108
所以有时候ida也不太准
基本ROP,ret2syscall,通过gadgets构成代码拿到shell
用ROPgadget搜索到如下gadgets
写exp
1 | from pwn import * |
打通!
tip:
在笔者学习这个payload时,疑惑0xb为什么可以直接传递,搜集了一下信息,以后慢慢学。(doge)
在这个栈溢出攻击中,
0xb
和"/bin/sh"
之间的区别涉及到系统调用号和字符串的存储方式。
- 系统调用号(syscall number):
0xb
是系统调用号,对应于execve
系统调用。在x86体系结构中,0xb
对应于sys_execve
。- 系统调用号通常直接作为参数传递给EAX寄存器,因此可以直接放在ROP链中。
- 字符串 “/bin/sh”:
"/bin/sh"
是一个字符串,存储在内存中的某个位置。在ROP攻击中,我们需要将该字符串的地址传递给execve
系统调用的参数之一。- 字符串本身的内容不适合直接放在ROP链中,因为ROP链需要是一系列的地址。所以我们将字符串的地址放在ROP链中,然后
execve
在执行时会读取该地址处的字符串。
ret2libc1
checksec
32位程序,未开启canary,未开启PIE,开启了栈不可执行。
丢到ida里
发现危险函数gets()
函数secure()有一个system()函数但是命令”shell!?”没有任何作用,但是由于system()函数的调用,在plt表里会有system()函数对应的got表地址的表项,进而能解析出system()函数的真实地址,从而调用system()函数。
需要填充108 + 4 = 112个垃圾数据
写exp
1 | from pwn import * |
打通!
ret2libc2
checksec
32位程序,未开启了canary和PIE,开启了部分RELRO和栈不可执行。
没有后门函数,也没有足够的gadgets。
没有找到”/bin/sh”
在全局区找到了全局变量buf2,可以劫持程序流到buf2写入”/bin/sh”再进行ROP
payload的结构如下
要填充0x78 - 0x0c + 4 = 108 + 4 = 112个垃圾数据
写exp
1 | from pwn import * |
打通!
ret2libc3
看到有两个文件
checksec ret2libc3
32位,未开启canary和PIE
丢到ida里
没有找到后门函数,又没有RWX段无法ret2text和ret2shellcode,而且没有足够的gadget所以也无法用ret2syscall,只能用ret2libc。
栈溢出漏洞在第二个read
栈结构如下
此处笔者遇到一个问题,题中给的libc文件和实际程序的所用的libc文件不一样所以分析题中所给的libc文件是无法打通的,可以利用ldd -v ret2libc3来查看程序所用的libc文件
可以看到所用的libc为libc.so.6
其路径为/lib/i386-linux-gnu/libc.so.6
写exp
1 | from pwn import * |
打通!