Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
## 📄 **Hacklet 1: Privilege Escalation via File Upload**
### 🖥️ **Overview**
This hacklet demonstrates a **file upload vulnerability** in a containerized environment that can be exploited to achieve **remote code execution (RCE)**. If the container runs as **root**, attackers can escalate their privileges and gain unauthorized access to the host system.
---
### 🔴 **Vulnerability: Privilege Escalation via File Upload**
The vulnerability arises from the following issues:
1. **Insecure File Upload Implementation:** The app allows users to upload files without any file type validation.
2. **Root User Execution:** The Docker container runs as **root**, allowing uploaded scripts to be executed with elevated privileges.
---
### ⚔️ **Exploit Steps**
1. **Create a malicious script** named `malicious.sh` with the following content:
```bash
#!/bin/bash
echo "You've been hacked!"
whoami
```
2. **Upload the script** via the Flask app's file upload page at **http://localhost:5000**.
3. **Execute the uploaded script** by visiting the following URL:
```
http://localhost:5000/execute/malicious.sh
```
4. **Expected Output:**
```text
You've been hacked!
root
```
---
### 🔍 **Root Cause Analysis**
The vulnerability exists because:
- The app does not validate the type of uploaded files.
- The Docker container is running as **root**, allowing uploaded files to be executed with **root privileges**.
---
### 🛡️ **Fixes Applied**
1. **Run the Container as a Non-Root User:**
- Updated the **Dockerfile** to create a non-root user and run the app under that user.
**Updated Dockerfile:**
```Dockerfile
# Use a minimal Python image
FROM python:3.9-slim
# Create a non-root user
RUN useradd -m appuser
# Set the working directory
WORKDIR /app
# Copy the necessary files
COPY ./app /app
COPY requirements.txt /app
# Install dependencies
RUN pip install -r requirements.txt
# Change ownership of the working directory
RUN chown -R appuser /app
# Switch to the non-root user
USER appuser
# Expose the port the app runs on
EXPOSE 5000
# Start the Flask app
CMD ["python", "app.py"]
```
2. **Restrict File Types for Upload:**
- Updated the **`upload_file()`** function to allow only specific file types (e.g., images).
**Updated `upload_file()` in `app.py`:**
```python
# Allowed file extensions
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return 'No file part'
file = request.files['file']
if file.filename == '':
return 'No selected file'
if not allowed_file(file.filename):
return 'File type not allowed'
file_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
file.save(file_path)
return f'File {file.filename} uploaded successfully!'
```
---
### ✅ **Verification After Fix**
1. Rebuild and run the app:
```bash
docker compose build
docker compose up
```
2. **Check that the container is running as a non-root user:**
```bash
docker exec -it messaging-app-web-1 whoami
```
**Expected Output:**
```text
appuser
```
3. **Try uploading and executing the malicious script again.**
- The execution should fail or return a limited output.
---
### 📊 **Summary Table**
| **Vulnerability** | **Description** | **Fix Applied** |
|----------------------------------|------------------------------------------------------------------|----------------------------------------|
| Privilege Escalation via File Upload | Users can upload and execute malicious scripts with root privileges | Run container as non-root user, restrict file types |
---
Would you like me to generate the `.md` file now? 😊