Exploit-DB is pretty famous for their collection of exploits and papers and if you are not familiar with them then then you should use some Google-fu to check up on them. They should be a bookmark found in pretty much any hackers handbook. In the past they had made their full archive available for download over HTTP, which was shaky at best and unless you scheduled it with cron or something you never knew if you had the latest and greatest and updating from a scripted manner was not always reliable (for me anyways). I had previously coded this tool in the past for the old archive methods, but today I noticed on Reddit they have moved to Github - w00t! This makes things much easier for everyone, well most people anyway.
Now they have had their archive collection for some time and the searchsploit bash script works just fine, however it can be too simplistic at times and not yield the results we want, unless you match your search syntax to its janky search method. It also lacks color and output logging. I had some time this morning so I decided to update my old script to take advantage of the simplicity of Github to allow easy fetching of new copies and/or updating existing ones. I also added a bit of color to the presentation of the results. It's very helpful for me so thought I would share with the rest of you...
To download exploit-db archives on your own from command line using normal git client:
COMMAND: git clone https://github.com/offensive-security/exploit-database.git
Then to update from command line when you want, you simply pull:
COMMAND: git pull
This can all be done from within my tool so now you can update and search from one place :) Here is a quick overview and a link to my Github page where you can find it.
Help Menu:
If it can't find the archive setup, it will offer to download via git for you:
Search by a range of options with option to log results to file:
NOTE: this can be handy when you get a lot of results (SQL Injection searches mostly...)
Easy peazy updating now that things can leverage Github:
You can find things on my Github page:
git clone https://github.com/Hood3dRob1n/Exploit-DB-Local-Archive-Search-Tool.git
Should only need to install the 'colorize' gem to get things started with ruby:
sudo gem install colorize
Special thanks to everyone on the Offesive Security
team that helps to make exploit-db and all of their other awesome projects possible!
Until next time, enjoy!
Monday, January 13, 2014
Wednesday, January 8, 2014
Shodan Search Tool w/My Ruby API Class
Today I just wanted to share a little something I made for Shodan. If you don't know what Shodan is, then I highly recommend you check them out and do some quick googling to see what others have done with its help. I initially tried using their published ruby gem and published API documentation but it failed miserably (likely could just be me, but seems their code is outdated with how their site provides output now, idk). I really like Shodan though so I decided to create my own version of their API so I could get started on making a cool search assistant I can run from the command line with some basic logging for analysis after. Once I finished redoing the API class, I made a little CLI based search tool to make quick Shodan research a snap and am now sharing with the rest of the world, hope its helpful for others.
Prerequisites:
sudo gem install colorize curb json nokogiri
NOTE: curb uses libcurl under the hood so you might need to install this if not already included on your OS
Basic Help Menu:
You can run a basic Shodan search and display the results, which are also logged to the results folder.
The logged results are overwritten on each search so you need to rename it or move it if you want to use it later and plan to run multiple searches.
I also made option for quick search which runs a Shodan search and returns the list of IP addresses from results, skipping all the details. I typically run a normal search, then a follow up quick search on same keywords to pass of lists to other tools in a speedy fashion while manual review is more involved with the full search results...
Shodan also offers up a nice search feature to search for exploits which leverages multiple exploit databases. I currently have the Exploit-db and Metasploit search engines available and fully working. This means you can easily search for known exploits with variety of keywords and get matching results displayed and logged for you.
You can even download the exploit/poc code from search results by referencing the ID number from results.
ToDo List:
Include options to search tool for premium search options (somewhat built into my API Class already but not in tool). Include a Gemfile for easy installs for bundler lovers. Also I have not uploaded things to Github yet as I fried my old box and lost a lot of stuff, working on recovery still but should have it updated soon. Until then you can find things on Pastebin, available for a long while...
My Shodan API Standalone Class:
Direct link: http://pastebin.com/q6LZJqcD
My Shodan API Search Tool, Source Code:
Direct Link: http://pastebin.com/B0SdmmrX
Helpful for me, hope it is for you too!
Until next time, Enjoy!
Prerequisites:
sudo gem install colorize curb json nokogiri
NOTE: curb uses libcurl under the hood so you might need to install this if not already included on your OS
Basic Help Menu:
You can run a basic Shodan search and display the results, which are also logged to the results folder.
The logged results are overwritten on each search so you need to rename it or move it if you want to use it later and plan to run multiple searches.
I also made option for quick search which runs a Shodan search and returns the list of IP addresses from results, skipping all the details. I typically run a normal search, then a follow up quick search on same keywords to pass of lists to other tools in a speedy fashion while manual review is more involved with the full search results...
Shodan also offers up a nice search feature to search for exploits which leverages multiple exploit databases. I currently have the Exploit-db and Metasploit search engines available and fully working. This means you can easily search for known exploits with variety of keywords and get matching results displayed and logged for you.
You can even download the exploit/poc code from search results by referencing the ID number from results.
ToDo List:
Include options to search tool for premium search options (somewhat built into my API Class already but not in tool). Include a Gemfile for easy installs for bundler lovers. Also I have not uploaded things to Github yet as I fried my old box and lost a lot of stuff, working on recovery still but should have it updated soon. Until then you can find things on Pastebin, available for a long while...
My Shodan API Standalone Class:
Direct link: http://pastebin.com/q6LZJqcD
My Shodan API Search Tool, Source Code:
- #!/usr/bin/env ruby
- #
- # Shodan API Search Assistant
- # By: Hood3dRob1n
- #
- ########### ENTER API KEY HERE ###########
- APIKEY='YOURAPIKEYNEEDS2GORIGHTINHEREYO!' #
- ###########################################
- ##### STD GEMS #######
- require 'fileutils' #
- require 'optparse' #
- require 'resolv' #
- #### NON-STD GEMS ####
- require 'rubygems' #
- require 'colorize' #
- require 'curb' #
- require 'json' #
- require 'nokogiri' #
- ######################
- HOME=File.expand_path(File.dirname(__FILE__))
- RESULTS = HOME + '/results/'
- # Banner
- def banner
- puts
- puts "Shodan API Search Assistant".light_green
- puts "By".light_green + ": Hood3dRob1n".white
- end
- # Clear Terminal
- def cls
- if RUBY_PLATFORM =~ /win32|win64|\.NET|windows|cygwin|mingw32/i
- system('cls')
- else
- system('clear')
- end
- end
- # Custom ShodanAPI Class :)
- # The pre-built option is broken and doesn't work in several places....
- # So we re-wrote it!
- class ShodanAPI
- # Initialize ShodanAPI via passed API Key
- def initialize(apikey)
- @url="http://www.shodanhq.com/api/"
- if shodan_connect(apikey)
- @key=apikey
- end
- end
- # Check API Key against API Info Query
- # Return True on success, False on Error or Failure
- def shodan_connect(apikey)
- url = @url + "info?key=#{apikey}"
- begin
- c = Curl::Easy.perform(url)
- if c.body_str =~ /"unlocked_left": \d+, "telnet": .+, "plan": ".+", "https": .+, "unlocked": .+/i
- results = JSON.parse(c.body_str)
- @plan = results['plan']
- @unlocked = results['unlocked']
- @unlocks = results['unlocked_left']
- @https = results['https']
- @telnet = results['telnet']
- return true
- elsif c.body_str =~ /"error": "API access denied"/i
- puts "Access Denied using API Key '#{apikey}'".light_red + "!".white
- puts "Check Key & Try Again".light_red + "....".white
- return false
- else
- puts "Unknown Problem with Connection to Shodan API".light_green + "!".white
- return false
- end
- rescue => e
- puts "Problem with Connection to Shodan API".light_red + "!".white
- puts "\t=> #{e}"
- return false
- end
- end
- # Just checks our key is working (re-using shodan_connect so updates @unlocks)
- # Returns True or False
- def connected?
- if shodan_connect(@key)
- return true
- else
- return false
- end
- end
- # Return the number of unlocks remaining
- def unlocks
- if shodan_connect(@key)
- return @unlocks.to_i
- else
- return nil
- end
- end
- # Check if HTTPS is Enabled
- def https?
- if shodan_connect(@key)
- if @https
- return true
- else
- return false
- end
- else
- return false
- end
- end
- # Check if Telnet is Enabled
- def telnet?
- if shodan_connect(@key)
- if @telnet
- return true
- else
- return false
- end
- else
- return false
- end
- end
- # Actually display Basic Info for current API Key
- def info
- url = @url + 'info?key=' + @key
- begin
- c = Curl::Easy.perform(url)
- results = JSON.parse(c.body_str)
- puts
- puts "Shodan API Key Confirmed".light_green + "!".white
- puts "API Key".light_green + ": #{@key}".white
- puts "Plan Type".light_green + ": #{results['plan']}".white
- puts "Unlocked".light_green + ": #{results['unlocked']}".white
- puts "Unlocks Remaining".light_green + ": #{results['unlocked_left']}".white
- puts "HTTPS Enabled".light_green + ": #{results['https']}".white
- puts "Telnet Enabled".light_green + ": #{results['telnet']}".white
- return true
- rescue => e
- puts "Problem with Connection to Shodan API".light_red + "!".white
- puts "\t=> #{e}".white
- return false
- end
- end
- # Lookup all available information for a specific IP address
- # Returns results hash or nil
- def host(ip)
- url = @url + 'host?ip=' + ip + '&key=' + @key
- begin
- c = Curl::Easy.perform(url)
- results = JSON.parse(c.body_str)
- return results
- rescue => e
- puts "Problem running Host Search".light_red + "!".white
- puts "\t=> #{e}".white
- return nil
- end
- end
- # Returns the number of devices that a search query found
- # Unrestricted usage of all advanced filters
- # Return results count or nil on failure
- def count(string)
- url = @url + 'count?q=' + string + '&key=' + @key
- begin
- c = Curl::Easy.perform(url)
- results = JSON.parse(c.body_str)
- return results['total']
- rescue => e
- puts "Problem grabbing results count".light_red + "!".white
- puts "\t=> #{e}".white
- return nil
- end
- end
- # Search Shodan for devices using a search query
- # Returns results hash or nil
- def search(string, filters={})
- prem_filters = [ 'city', 'country', 'geo', 'net', 'before', 'after', 'org', 'isp', 'title', 'html' ]
- cheap_filters = [ 'hostname', 'os', 'port' ]
- url = @url + 'search?q=' + string
- if not filters.empty?
- filters.each do |k, v|
- if cheap_filters.include?(k)
- url += ' ' + k + ":\"#{v}\""
- end
- if prem_filters.include?(k)
- if @unlocks.to_i > 1
- url += ' ' + k + ":\"#{v}\""
- @unlocks = @unlocks.to_i - 1 # Remove an unlock for use of filter
- else
- puts "Not Enough Unlocks Left to run Premium Filter Search".light_red + "!".white
- puts "Try removing '#{k}' filter and trying again".light_red + "....".white
- return nil
- end
- end
- end
- end
- url += '&key=' + @key
- begin
- c = Curl::Easy.perform(url)
- results = JSON.parse(c.body_str)
- return results
- rescue => e
- puts "Problem running Shodan Search".light_red + "!".white
- puts "\t=> #{e}".white
- return nil
- end
- end
- # Quick Search Shodan for devices using a search query
- # Results are limited to only the IP addresses
- # Returns results array or nil
- def quick_search(string, filters={})
- prem_filters = [ 'city', 'country', 'geo', 'net', 'before', 'after', 'org', 'isp', 'title', 'html' ]
- cheap_filters = [ 'hostname', 'os', 'port' ]
- url = @url + 'search?q=' + string
- if not filters.empty?
- filters.each do |k, v|
- if cheap_filters.include?(k)
- url += ' ' + k + ":\"#{v}\""
- end
- if prem_filters.include?(k)
- if @unlocks.to_i > 1
- url += ' ' + k + ":\"#{v}\""
- @unlocks = @unlocks.to_i - 1
- else
- puts "Not Enough Unlocks Left to run Premium Filter Search".light_red + "!".white
- puts "Try removing '#{k}' filter and trying again".light_red + "....".white
- return nil
- end
- end
- end
- end
- url += '&key=' + @key
- begin
- ips=[]
- c = Curl::Easy.perform(url)
- results = JSON.parse(c.body_str)
- results['matches'].each do |host|
- ips << host['ip']
- end
- return ips
- rescue => e
- puts "Problem running Shodan Quick Search".light_red + "!".white
- puts "\t=> #{e}".white
- return nil
- end
- end
- # Perform Shodan Exploit Search as done on Web
- # Provide Search String and source
- # Source can be: metasploit, exploitdb, or cve
- # Returns results hash array on success: { downloadID => { link => description } }
- # Returns nil on failure
- def sploit_search(string, source)
- sources = [ "metasploit", "exploitdb", "cve" ]
- if sources.include?(source.downcase)
- sploits = 'https://exploits.shodan.io/?q=' + string + ' source:"' + source.downcase + '"'
- begin
- results={}
- c = Curl::Easy.perform(sploits)
- page = Nokogiri::HTML(c.body_str) # Parsable doc object now
- # Enumerate target section, parse out link & description
- page.css('div[class="search-result well"]').each do |linematch|
- if linematch.to_s =~ /<div class="search-result well">\s+<a href="(.+)"\s/
- link=$1
- end
- if linematch.to_s =~ /class="title">(.+)\s+<\/a>/
- desc=$1.gsub('<em>', '').gsub('</em>', '')
- end
- case source.downcase
- when 'cve'
- dl_id = 'N/A for CVE Search'
- when 'exploitdb'
- dl_id = link.split('/')[-1] unless link.nil?
- when 'metasploit'
- dl_id = link.sub('http://www.metasploit.com/', '').sub(/\/$/, '') unless link.nil?
- end
- results.store(dl_id, { link => desc}) unless (link.nil? or link == '') or (desc.nil? or desc == '') or (dl_id.nil? or dl_id == 'N/A for CVE Search')
- end
- return results
- rescue Curl::Err::ConnectionFailedError => e
- puts "Shitty connection yo".light_red + ".....".white
- return nil
- rescue => e
- puts "Unknown connection problem".light_red + ".....".white
- puts "\t=> #{e}".white
- return nil
- end
- else
- puts "Invalid Search Source Requested".light_red + "!".white
- return nil
- end
- end
- # Download Exploit Code from Exploit-DB or MSF Github Page
- # By passing in the Download ID (which can be seen in sploit_search() results)
- # Return { 'Download' => dl_link, 'Viewing' => v_link, 'Exploit' => c.body_str }
- # or nil on failure
- def sploit_download(id, source)
- sources = [ "metasploit", "exploitdb" ]
- if sources.include?(source.downcase)
- case source.downcase
- when 'exploitdb'
- dl_link = "http://www.exploit-db.com/download/#{id}/"
- v_link = "http://www.exploit-db.com/exploits/#{id}/"
- when 'metasploit'
- dl_link = "https://raw.github.com/rapid7/metasploit-framework/master/#{id.sub('/exploit/', '/exploits/')}.rb"
- v_link = "http://www.rapid7.com/db/#{id}/"
- end
- begin
- c = Curl::Easy.perform(dl_link)
- page = Nokogiri::HTML(c.body_str) # Parsable doc object now
- results = { 'Download' => dl_link, 'Viewing' => v_link, 'Exploit' => c.body_str }
- return results
- rescue Curl::Err::ConnectionFailedError => e
- puts "Shitty connection yo".light_red + ".....".white
- return false
- rescue => e
- puts "Unknown connection problem".light_red + ".....".white
- puts "#{e}".light_red
- return false
- end
- else
- puts "Invalid Download Source Requested".light_red + "!".white
- return false
- end
- end
- end
- ### MAIN ###
- options = {}
- optparse = OptionParser.new do |opts|
- opts.banner = "Usage:".light_green + "#{$0} ".white + "[".light_green + "OPTIONS".white + "]".light_green
- opts.separator ""
- opts.separator "EX:".light_green + " #{$0} -s cisco-ios".white
- opts.separator "EX:".light_green + " #{$0} -h 217.140.75.46".white
- opts.separator "EX:".light_green + " #{$0} --quick-search IIS/5.1".white
- opts.separator "EX:".light_green + " #{$0} -S exploitdb -x udev".white
- opts.separator "EX:".light_green + " #{$0} -d 8678 -S exploitdb".white
- opts.separator "EX:".light_green + " #{$0} --source metasploit --exploit-search udev".white
- opts.separator "EX:".light_green + " #{$0} -S metasploit -d modules/exploit/linux/local/udev_netlink".white
- opts.separator ""
- opts.separator "Options: ".light_green
- opts.on('-q', '--quick-search STRING', "\n\tShodan Quick Search".white) do |search_str|
- options[:method] = 3 # 1=> Normal, 2=> IP, 3=> Quick, 4=>Exploit Search, 5=>Exploit Download
- options[:search] = search_str.chomp
- end
- opts.on('-s', '--shodan-search STRING', "\n\tShodan Search".white) do |search_str|
- options[:method] = 1 # 1=> Normal, 2=> IP, 3=> Quick, 4=>Exploit Search, 5=>Exploit Download
- options[:search] = search_str.chomp
- end
- opts.on('-h', '--host-search HOST', "\n\tShodan Host Search against IP".white) do |search_str|
- options[:method] = 2 # 1=> Normal, 2=> IP, 3=> Quick, 4=>Exploit Search, 5=>Exploit Download
- if search_str.chomp =~ /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/
- options[:search] = search_str.chomp
- else
- begin
- ip = Resolv.getaddress(search_str.chomp) # Resolve Host Domain to IP
- options[:search] = ip
- rescue Resolv::ResolvError => e
- cls
- banner
- puts
- puts "Unable to Resolve Host to IP".light_red + "!".white
- puts
- puts opts
- puts
- exit 69;
- end
- end
- end
- opts.on('-S', '--source SOURCE', "\n\tSet Exploit Source: exploitdb or metasploit".white) do |source|
- sources=["metasploit", "exploitdb"]
- if sources.include?(source.downcase.chomp)
- options[:source] = source.downcase.chomp
- else
- cls
- banner
- puts
- puts "Invalid Search Source Requested".light_red + "!".white
- puts "\t=> #{source}".light_red
- puts
- puts opts
- puts
- exit 69;
- end
- end
- opts.on('-x', '--exploit-search STRING', "\n\tShodan Exploit Search for String (requires -S)".white) do |search_str|
- options[:method] = 4 # 1=> Normal, 2=> IP, 3=> Quick, 4=>Exploit Search, 5=>Exploit Download
- options[:search] = search_str.chomp
- end
- opts.on('-d', '--download-id ID', "\n\tDownload Exploit by Exploit ID (requires -S)".white) do |search_str|
- options[:method] = 5 # 1=> Normal, 2=> IP, 3=> Quick, 4=>Exploit-DB Search, 5=>Exploit-DB Download
- options[:search] = search_str.chomp
- end
- opts.on('-H', '--help', "\n\tHelp Menu".white) do
- cls
- banner
- puts
- puts opts
- puts
- exit 69;
- end
- end
- begin
- foo = ARGV[0] || ARGV[0] = "-H"
- optparse.parse!
- mandatory = [:method,:search]
- missing = mandatory.select{ |param| options[param].nil? }
- if not missing.empty?
- cls
- banner
- puts
- puts "Missing options: ".red + " #{missing.join(', ')}".white
- puts optparse
- exit 666;
- end
- rescue OptionParser::InvalidOption, OptionParser::MissingArgument, OptionParser::AmbiguousOption
- cls
- banner
- puts
- puts $!.to_s.red
- puts
- puts optparse
- puts
- exit 666;
- end
- banner
- shodan = ShodanAPI.new(APIKEY)
- if shodan.connected?
- # Display Basic API Key Info
- shodan.info
- puts
- # Create Results Dir if it doesnt exist
- Dir.mkdir(RESULTS) unless File.exists?(RESULTS) and File.directory?(RESULTS)
- # Now run as requested....
- case options[:method].to_i
- when 1
- results = shodan.search(options[:search].to_s)
- if not results.nil?
- puts "Shodan Search".light_green + ": #{options[:search].to_s}".white
- f=File.open(RESULTS + "shodan_search_results.txt", 'w+')
- f.puts "Shodan Search: #{options[:search].to_s}"
- puts "Total Results Found".light_green + ": #{results['total']}".white
- f.puts "Total Results Found: #{results['total']}"
- results['countries'].each do |country|
- puts " #{country['name']}".light_green + ": #{country['count']}".white
- f.puts " #{country['name']}: #{country['count']}"
- end
- puts
- f.puts
- results['matches'].each do |host|
- puts "Host IP".light_green + ": #{host['ip']}".white
- f.puts "Host IP: #{host['ip']}"
- puts "#{host['data']}".white
- f.puts host['data']
- end
- f.puts
- f.close
- else
- puts "No Results Found for ".light_red + "#{string}".white + " via Shodan Search".light_red + "!".white
- end
- puts
- when 2
- # Check Host Results
- results = shodan.host(options[:search].to_s)
- if not results.nil?
- f=File.open(RESULTS + "shodan_host_search_results.txt", 'w+')
- puts "Host IP".light_green + ": #{results['ip']}".white unless results['ip'].nil?
- f.puts "Host IP: #{results['ip']}" unless results['ip'].nil?
- puts "ISP".light_green + ": #{results['data'][0]['isp']}".white unless results['data'][0]['isp'].nil?
- f.puts "ISP: #{results['data'][0]['isp']}" unless results['data'][0]['isp'].nil?
- puts "Hostname(s)".light_green + ": #{results['hostnames'].join(',')}".white unless results['hostnames'].empty?
- f.puts "Hostname(s): #{results['hostnames'].join(',')}" unless results['hostnames'].empty?
- puts "Host OS".light_green + ": #{results['os']}".white unless results['os'].nil?
- f.puts "Host OS: #{results['os']}" unless results['os'].nil?
- puts "Country".light_green + ": #{results['country_name']}".white unless results['country_name'].nil?
- f.puts "Country: #{results['country_name']}" unless results['country_name'].nil?
- puts "City".light_green + ": #{results['city']}".white unless results['city'].nil?
- f.puts "City: #{results['city']}" unless results['city'].nil?
- puts "Longitude".light_green + ": #{results['longitude']}".white unless results['longitude'].nil? or results['longitude'].nil?
- f.puts "Longitude: #{results['longitude']}" unless results['longitude'].nil? or results['longitude'].nil?
- puts "Latitude".light_green + ": #{results['latitude']}".white unless results['longitude'].nil? or results['longitude'].nil?
- f.puts "Latitude: #{results['latitude']}" unless results['longitude'].nil? or results['longitude'].nil?
- f.puts
- puts
- # We need to split and re-pair up the ports & banners as ports comes after banners in results iteration
- ban=nil
- port_banners={}
- results['data'][0].each do |k, v|
- if k == 'port'
- port=v
- if not ban.nil?
- port_banners.store(port, ban) # store them in hash so we pair them up properly
- ban=nil
- end
- elsif k == 'banner'
- ban=v
- end
- end
- # Now we can display them in proper pairs
- port_banners.each do |port, ban|
- puts "Port".light_green + ": #{port}".white
- f.puts "Port: #{port}"
- puts "Banner".light_green + ": \n#{ban}".white
- f.puts "Banner: \n#{ban}"
- end
- f.puts
- f.close
- else
- puts "No results found for host".light_red + "!".white
- end
- puts
- when 3
- # Perform Quick Shodan Search
- string = options[:search].to_s
- ips = shodan.quick_search(string)
- if not ips.nil?
- puts "Shodan Search".light_green + ": #{string}".white
- puts "Total Results".light_green + ": #{ips.size}".white
- puts "IP Addresses Returned".light_green + ": ".white
- f=File.open(RESULTS + 'quick_search-ips.lst', 'w+')
- ips.each {|x| puts " #{x}".white; f.puts x }
- f.close
- else
- puts "No Results Found for ".light_red + "#{string}".white + " via Shodan Quick Search".light_red + "!".white
- end
- puts
- when 4
- # Search for Exploits
- string = options[:search].to_s
- source = options[:source].to_s
- results = shodan.sploit_search(string, source)
- if not results.nil?
- f=File.open(RESULTS + "shodan_#{source}_search_results.txt", 'w+')
- puts "Shodan Exploit Search".light_green + ": #{string}".white
- f.puts "Shodan Exploit Search: #{string}"
- results.each do |id, stuff|
- puts "ID".light_green + ": #{id}".white unless id.nil?
- f.puts "ID: #{id}" unless id.nil?
- stuff.each do |link, desc|
- puts "View".light_green + ": #{link.sub('http://www.metasploit.com/', 'http://www.rapid7.com/db/')}".white unless link.nil?
- f.puts "View: #{link.sub('http://www.metasploit.com/', 'http://www.rapid7.com/db/')}" unless link.nil?
- if not link.nil? and source.downcase == 'metasploit'
- puts "Github Link".light_green + ": https://raw.github.com/rapid7/metasploit-framework/master/#{link.sub('http://www.metasploit.com/', '').sub('/exploit/', '/exploits/').sub(/\/$/, '')}.rb".white
- f.puts "Github Link: https://raw.github.com/rapid7/metasploit-framework/master/#{link.sub('http://www.metasploit.com/', '').sub('/exploit/', '/exploits/').sub(/\/$/, '')}.rb"
- end
- puts "Exploit Description".light_green + ": \n#{desc}".white unless desc.nil?
- f.puts "Exploit Description: \n#{desc}" unless desc.nil?
- f.puts
- puts
- end
- end
- f.close
- else
- puts "No Results Found for ".light_red + "#{string}".white + " via Shodan Exploit Search".light_red + "!".white
- end
- puts
- when 5
- # Now download one of the exploits you found....
- id=options[:search].to_s
- source = options[:source].to_s
- results = shodan.sploit_download(id, source)
- if not results.nil?
- downloads = RESULTS + 'downloads/'
- Dir.mkdir(downloads) unless File.exists?(downloads) and File.directory?(downloads)
- f=File.open(downloads + "#{source}-#{id}.code", 'w+')
- results.each do |k, v|
- if k == 'Exploit'
- puts "Saved to".light_green + ": #{downloads}#{source}-#{id}.code".white
- puts "#{k}".light_green + ": \n#{v}".white
- f.puts v
- else
- puts "#{k}".light_green + ": #{v}".white
- end
- end
- f.close
- else
- puts "No Download Results Found for ID".light_red + "#: #{id}".white
- end
- end
- else
- exit 666;
- end
- #EOF
Helpful for me, hope it is for you too!
Until next time, Enjoy!
Subscribe to:
Posts (Atom)