Metasploit Module: GL.iNet Unauthenticated Remote Command Execution via the logread module.
Type: exploit
Path: modules/exploits/linux/http/glinet_unauth_rce_cve_2023_50445.rb
Platform: unix
Disclosure date: 2023-12-10
References: CVE-2023-50445, CVE-2023-50919, URL-https://attackerkb.com/topics/3LmJ0d7rzC/cve-2023-50445, URL-https://attackerkb.com/topics/LdqSuqHKOj/cve-2023-50919, URL-https://libdzonerzy.so/articles/from-zero-to-botnet-glinet.html, URL-https://github.com/gl-inet/CVE-issues/blob/main/4.0.0/Using%20Shell%20Metacharacter%20Injection%20via%20API.md
Targets: Unix Command, Linux Dropper

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.

Check method (fingerprinting):
print_status("Checking if #{peer} can be exploited.")
    # Check if target is a GL.iNet network device and the firmware version is vulnerable
    return CheckCode::Vulnerable("Product info: #{@glinet['model']}|#{@glinet['firmware']}|#{@glinet['arch']}") if vuln_version?

    unless @glinet['firmware'].nil?
      # GL.iNet network devices with firmware version 3.x that are safe from this exploit
      return CheckCode::Safe("Product info: #{@glinet['model']}|#{@glinet['firmware']}|#{@glinet['arch']}") if Rex::Version.new(@glinet['firmware']) < Rex::Version.new('4.0.0')

      # GL.iNet network devices with a firmware version 4.x or higher which still could be vulnerable unless the architecture is not available (n/a)
      if @glinet['arch'] != 'n/a' && (Rex::Version.new(@glinet['firmware']) >= Rex::Version.new('4.0.0'))
        return CheckCode::Safe("Product info: #{@glinet['model']}|#{@glinet['firmware']}|#{@glinet['arch']}")
      end
      return CheckCode::Detected("Product info: #{@glinet['model']}|#{@glinet['firmware']}|#{@glinet['arch']}") if Rex::Version.new(@glinet['firmware']) >= Rex::Version.new('4.0.0')
    end
    # No GL.iNet network device or not reachable
    CheckCode::Unknown('No GL.iNet network device or device is not responding.')
  end