PIE绕过

Maple Lv2

1,PIE介绍

PIE全称是position-independent executable,中文解释为地址无关可执行文件,该技术是一个针对代码段(.text)、数据段(.data)、未初始化全局变量段(.bss)等固定地址的一个防护技术,如果程序开启了PIE保护的话,在每次加载程序时都变换加载地址,从而不能通过ROPgadget等一些工具来帮助解题。

简单来说,在开启PIE之后,你不能再查找到代码段的绝对地址了,只能看到一个地址的后四位数字。

这个地址并不是程序实际运行地址,而是于程序加载基址之间的偏移量。如果没有开启pie保护,程序的加载基址默认是0x400000,现在开启了PIE之后,每次运行程序的加载基址都是不同的

程序的实际运行地址=程序加载基址+程序偏移地址

注意:开启pie保护之后pwngdb调试的时候不能下断点,需要通过b *$rebase(offset)这种方式下断点,offset是ida中反汇编出来的程序地址偏移量

2.绕过方式

2.1 格式化字符串泄露真实地址

无敌的格式化字符串又一次展现了它的神力

如果一个程序中存在格式化字符串漏洞。我们就可以配合格式化字符串漏洞将程序某个函数的真实地址泄露出来

直接写个exp:

1
2
3
p.sendline(b'aaaa%12$p')
p.recvuntil(b'aaaa')
base_addr = int(p.recv(14),16)-offset # offset为偏移地址,这个需要动态调试查看

2.2 partial write

partial write(部分写入)就是一种利用了PIE技术缺陷的bypass技术。由于内存的页载入机制,PIE的随机化只能影响到单个内存页。通常来说,一个内存页大小为0x1000,这就意味着不管地址怎么变,某条指令的后12位,3个十六进制数的地址是始终不变的。因此通过覆盖EIP的后8或16位 (按字节写入,每字节8位)就可以快速爆破或者直接劫持EIP。

省流: 不管程序加载基址怎么变化,偏移量和真实地址的最后三位都是一样的

假设后门函数地址为0x09C5

exp:

1
payload = b'a'*0x30 + b'a'*0x8 + b'\xC5\x09' # 第二字节可能\x19、\x29...尝试一下
  • 标题: PIE绕过
  • 作者: Maple
  • 创建于 : 2025-04-05 11:44:22
  • 更新于 : 2025-04-15 22:09:42
  • 链接: https://github.com/maple-pwn/maple-pwn.github.io/2025/04/05/PIE绕过/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。