ღ Miranda

Bypassing ASLR + DEP using ROP + Return-to-dl-resolve in 32-bit system

使用Return-to-dl-resolve技术在没有libc库的情况下执行system函数。

传统的利用return-to-plt+ROP来绕过ASLR + DEP的技术需要知道库中函数的偏移地址,而在没有libc库的情况下可以使用Return-to-dl-resolve技术来达到动态获得库函数地址的目的,关于dl-resolve的技术细节请参照lazy-binding-in-detail

Environment

Vulnerable code

编译程序并且打开系统的ASLR:

程序是一个简单的缓冲区溢出,可以覆盖返回地址,在DEP的保护下,我们可以使用ROP技术来执行代码,为了绕过ASLR,这里使用了return-to-plt技术。

return-to-plt

call write@plt

调用write@plt的代码如下:

函数的plt其实地址可以用objdump -d -j.plt bof读出:

栈的布局如下:

运行:

看到write@plt被成功调用打出了我们想要的字符串。

Relocation directly

接下来改一下ROP,将直接调用write@plt改为将reloc_offset放在栈中,直接跳到0x8048300执行:

看到write@pltreloc_offset0x18,修改代码为:

运行:

Make fake Elf32_Rel structure

接下来要建立假的Elf32_Rel结构体,原来第一个结构体的位置为:

这里我们可插入一个非常大的reloc_offset,把结构体位置定位到我们可以控制的区域,选择区域为base_stage+28reloc_offset = (base_stage+28) - addr_relplt,在指定区域插入伪造的结构体,先看看原来的write的结构体:

构造为:

后半段改为:

这样同样能调用write:

Make fake Elf32_Sym structure

我们知道在找到Elf32_Rel结构体后,会通过r_info >> 8得到Elf32_Sym结构体的位置

writer_info >> 8 = 4,所以在SYMTAB[4],也就是0x80481cc + 64:

我们可以把结构体放在base_stage + 36处,原结构体为:

所以构造为:

还要修改Elf32_Rel结构体中的r_info,保证:

所以base_stage + 36需要加padding,使得为0x10的倍数,计算得到这里正好符合padding的要求,可以不需要padding,修改后为:

结果一样:

Make fake string table

我们知道Elf32_Sym结构体第一项是函数名称字符串在STRTAB中的偏移:

只需要修改st_name字段,直接在Elf32_Sym结构体后加字符串即可:

结果:

Get shell

只要把write\x00改为system\x00,然后修改对应的参数就可以了,完整的脚本:

运行:

这样就在不知道库中函数偏移的情况下调用了system

refer: ROP stager + Return-to-dl-resolveによるASLR+DEP回避

发表评论

电子邮件地址不会被公开。