0%

'ret2_dl_runtime_resolve'

0x00 前言

之前一直想写一篇ret2_dl_runtime_resolve的文章,一直没有时间,借此机会分分享一下这种利用方式,虽然,这不是很新的利用方式,但是,这种利用方式,可以通杀某一类栈溢出的题目,可以实现秒题,这里主要是分享一下利用的原理,至于利用,也有现成的工具(roputils),当然,网上关于这种利用方式的文章有好多,可以自行百度,但是有些东西只有自己调试了才是自己的,看着明白,不一定都会用,会用也不一定真正明白原理,有错误之处还请矫正

0x01 利用场景

我觉得这种利用方式最好的使用场景是

  • linux下32位程序
  • partial RELRO/no RELRO
  • No PIE
  • 存在rop或者其他可以控制栈的漏洞

程序保护参考:http://47.94.212.159:1948/pwn.md#/3

0x02 原理介绍

0x00 延时绑定机制

这种利用方式基于延时绑定(lazy binding)机制,简单来说,就是程序载入内存之后,程序所用到的动态链接库函数的地址不会立刻写入got表,而是,在第一次调用动态链接库函数的时候,把动态链接库函数的地址写入got表

0x01 正常的动态链接库函数写入got表的过程

0x00 测试环境

  • ubuntu16.04

  • gcc(需要添加32位支持输入命令 sudo apt-get install libc6-dev-i386

  • gdb(pwndbg插件)

0x01 测试源码

1
2
3
4
5
6
7
//gcc test.c -o test -m32  -z noexecstack -fno-stack-protector -no-pie  -z lazy
#include<stdio.h>
int main(){
printf("hello");
printf("hello world");
return 0;
}

第一行为编译命令参考:http://47.94.212.159:1948/pwn.md#/3/7

0x02 开始调试

  • 下断点到printf函数之前
  • 然后si

image-20191204144334064

可以看到call 的地址为 080482E0,这个地址是什么呢

image-20191204144522413

会jmp到 [0x0804A00C] 的地址了,0x0804A00C这个地址就是prinf函数在got表的位置的地址啦

image-20191204144735605

然后我们可以看到

image-20191204150331212

接下来的操作是:

  • push 0
  • push 0x804a004
  • jmp [0x804a008] <0xf7fee000>

我们可以看到