Inkline
Inkline is an enterprise e-signature portal: send agreements, track signatures, and keep an audit trail. Register, manage your documents, and sign.
The Scenario
Inkline handles signed agreements for enterprises. An engineer doing a security pass
flagged that an admin account had its password changed overnight, with no record of a
reset email ever being sent, and a template pack imported right afterward that nobody
recognises.
Start from a normal account and work out how an outsider could take over the admin and
turn a template import into code execution on the server.
Lab Intel
Synopsis
Inkline's password-reset token is home-rolled: token = sha256(user_id . SERVER_SECRET) with a short secret. A browsable /scripts directory leaks gen_reset_token.py documenting the construction. The document search is time-based blind SQLi, but it only yields the admin's bcrypt hash (uncrackable - the dead end). The real path: observe your own reset link (uid + token shown on /account.php), brute the short SERVER_SECRET offline, forge the admin's token (sha256('1' . secret)), POST /reset.php to set the admin password (which also logs you in as admin). As admin, the template-pack import stores an uploaded .phar and validates it with file_exists('phar://...'); on PHP 7.4 that deserializes the phar metadata, and a TemplateCache object (a file-write __destruct gadget) writes a PHP web shell into the web root -> RCE -> /flag.txt.
Architecture
A hard chain on three containers (nginx gateway + PHP 7.4/Apache + MySQL 8). Recon: /scripts dir listing reveals the reset-token formula; the search SQLi is a time-based blind dead end (bcrypt). Exploit: forge a reset token for uid=1 after recovering the short secret from your own token, which both resets and authenticates you as admin; then abuse the admin .phar template import, whose file_exists('phar://...') triggers PHP object injection via the TemplateCache file-write POP gadget, dropping a web shell. The flag at /flag.txt is read by the www-data worker after RCE.
Who It's For
Players ready to chain a home-rolled-crypto token forgery with a modern deserialization primitive: recognising a short-secret signing scheme, inverting it from an observed sample, and turning a phar upload + a stat call into object-injection RCE.
Skills You'll Practice
- Spotting and reading a browsable /scripts directory for a token construction
- Recognising a bcrypt/time-blind-SQLi dead end and pivoting off it
- Brute-forcing a short secret from an observed token, then forging another user's token
- phar:// object injection via file_exists and a file-write POP gadget to RCE
What You'll Gain
- Why home-rolled sha256(id + short_secret) tokens are forgeable
- The phar-metadata object-injection technique and its PHP-version nuance (fires on 7.x stat calls)
- Chaining recon -> token forgery -> admin -> deserialization RCE