LD_PRELOAD与绕过PHP禁用函数和提权
前言
前些天晚上看https://xxe.one/index.php?threads/146这个文章,其中的第17个问题引起了我的注意,之前在某次的攻防中遇到过大佬绕过宝塔的PHP函数禁用,当时大概看了一下报告,觉得是一种我之前没有学到的bypass,然后大概了解了一下,没有仔细深究。没想到半年过去了,这第17个问题勾起了我的回忆,于是打算再仔细看看。
本文主要原理参考于Dynamic linker tricks: Using LD_PRELOAD to cheat, inject features and investigate programs
LD_PRELOAD
LD_PRELOAD是Linux系统中的可选环境变量,该环境变量可以控制动态链接库的加载位置。在任何操作系统中,几乎所有代码都依赖库,库可以说是现代操作系统的基石之一,库同时又分为静态链接库和动态链接库,在代码进行编译时链接到代码中的库成为静态链接库,相反,编译时未链接到代码中,每次执行时才进行加载的是动态链接库,相比较而言,动态链接库具有更加灵活,内存占用少,更易维护等优点。
在Linux中,动态链接库按照如下顺序查找执行:
- 编译时指定的动态链接库路径
- 环境变量
LD_PRELOAD
- 环境变量
LD_LIBRARY_PATH
/etc/ld.so.cache
目录/lib
目录/usr/lib
目录
从上面动态链接库加载的顺序来看,LD_PRELOAD
的加载级别是相当高的,所以可以通过使用LD_PRELOAD
来劫持动态链接库,以实现绕过一些限制。
之所以使用LD_PRELOAD
而不是LD_LIBRARY_PATH
,是因为LD_LIBRARY_PATH
需要修改环境变量
Example
就使用参考文章中的例子,简单易懂
rand.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
srand(time(NULL));
int i = 10;
while(i--) printf("%d\n",rand()%100);
return 0;
}
使用gcc rand.c -o rand
编译,从代码不难看出这是一个输出10个随机数的程序,结果不言而喻。
接着编译另一个文件:
unrand.c
int rand(){
return 1;
}
使用gcc -shared-fPIC unrand.c -o unrand.so
将该文件编译为动态链接库
执行命令LD_PRELOAD=$PWD/unrand.so ./rand
,可以观察到输出为10个1,而非随机数
通过ldd rand
和LD_PRELOAD=$PWD/unrand.so ldd rand
可以观察到,第二条命令加载了一个新的动态链接库,在Linux中,rand()
函数在libc.so.6
这个动态链接库中,但是LD_PRELAOD
的优先级更高,所以rand
程序优先加载了我的动态链接库,使用了我自定义的rand()
函数
所以使得通过加载LD_PRELOAD
来实现某些Bypass成为可能。
绕过PHP禁用函数
绕过PHP禁用函数的思路来自于yangyangwithgnu大佬的bypass disable_functions via LD_PRELOAD,详情可阅读上述仓库中的README
。
提权
在阅读bypass disable_functions via LD_PRELOAD时,我在该仓库中发现了一个issues,该页面的最后有人贴出了一个利用LD_PRELOAD
来提权的操作,详见Sudo (LD_PRELOAD) (Linux Privilege Escalation)
《LD_PRELOAD与绕过PHP禁用函数和提权》链接:https://xdym11235.com/archives/149.html
具体版权规定详见侧栏版权说明页面
兄弟是干什么行业的?可有合作的意向?
无
代码看不懂还是来踩踩
留下脚印!
嘿嘿?