class Fofa::API
Public Class Methods
new(email, apikey, options={})
click to toggle source
# File lib/fofa.rb, line 9 def initialize(email, apikey, options={}) @options = {debug:false}.merge options @api_server = ENV['FOFA_API_SERVER'] || 'https://fofa.so' @email = email || ENV['FOFA_EMAIL'] @apikey = apikey || ENV['FOFA_KEY'] end
Public Instance Methods
check_app(host, options={})
click to toggle source
Check applications of asset
Example:
>> Fofa::API.new(email,apikey).checkapp("mail.tsinghua.edu.cn", category:"邮件系统") => ["Coremail"]
Arguments:
host: (String) Category name options: (Hash) category: Category name, application: Application name, all: return all applications or break when match first
# File lib/fofa.rb, line 144 def check_app(host, options={}) options = {all:false}.merge(options) url = "#{@api_server}/api/v1/search/checkapp?key=#{@apikey}&email=#{@email}&host=#{host}" url += "&all=#{options[:all]}" if options[:all] url += "&application=#{URI.escape(options[:application])}" if options[:application] url += "&category=#{URI.escape(options[:category])}" if options[:category] puts url if @options[:debug] uri = URI.parse(url) http = http_new(uri) req = Net::HTTP::Get.new(uri.request_uri) resp = http.request(req) JSON.parse(resp.body) rescue => e {"error"=>"Error: #{e.to_s}"} end
import_service(file, options={})
click to toggle source
Import asset into fofa
Example:
>> Fofa::API.new(email,apikey).import("./http80.txt") => {size:1, results:['1.1.1.1:80']}
Arguments:
file: (String) assets file options: (Hash) page
# File lib/fofa.rb, line 101 def import_service(file, options={}) options = {port:80, split_size:100}.merge(options) url = "#{@api_server}/api/v1/import/services?key=#{@apikey}&email=#{@email}&port=#{options[:port]}" puts url if @options[:debug] uri = URI.parse(url) http = http_new(uri) File.open(file) do |f| results = [] f.each_line.lazy.each_with_index do |line, i| line = line.strip if m = /Discovered open port (?<port>.*?)\/tcp on (?<host>.*?)$/.match(line) hostinfo = "#{m[:host]}:#{m[:port]}" elsif line.include?(':') hostinfo = line else hostinfo = "#{line}:#{options[:port]}" end results << line if i % split_size == 0 req = Net::HTTP::Post.new(uri.request_uri) req.body = results.join("\n") resp = http.request(req) puts resp if @options[:debug] results = [] end end end rescue => e {"error"=>"Error: #{e.to_s}"} end
search(query, options={})
click to toggle source
Search page results from fofa
Example 1:
>> Fofa::API.new(email,apikey).search("host=baidu.com") => {size:1, results:['1.1.1.1']}
Example 2:
>> Fofa::API.new(email,apikey).search("host=baidu.com", fields:'host,title,ip') => {size:1, results:[['1.1.1.1:81', 'title', '1.1.1.1']]}
Arguments:
query: (String) fofa query string options: (Hash) page(default 1, only fetch one page), size(defualt 100)
# File lib/fofa.rb, line 29 def search(query, options={}) options = {page:1, size:100, fields:'host'}.merge(options) url = "#{@api_server}/api/v1/search/all?key=#{@apikey}&email=#{@email}&page=#{options[:page]}&size=#{options[:size]}&fields=#{options[:fields]}" url += "&qbase64=#{Base64.encode64(query)}" unless options[:post] puts url if @options[:debug] uri = URI.parse(url) http = http_new(uri) if options[:post] req = Net::HTTP::Post.new(uri.request_uri) req.body = query else req = Net::HTTP::Get.new(uri.request_uri) end resp = http.request(req) JSON.parse(resp.body) rescue => e $stderr.puts "[WARNING]: #{e.to_s}" {"error"=>"Error: #{e.to_s}"} end
search_all(query, options={}) { |res, page, to_i| ... }
click to toggle source
Search all results from fofa
Example:
>> Fofa::API.new(email,apikey).search_all("domain==baidu.com") {|results, page| ... } => {size:1, results:['1.1.1.1:80']}
Example:
>> Fofa::API.new(email,apikey).search_all("domain==baidu.com", fields:'host,title,ip') {|results, page| ... } => {size:1, results:[['1.1.1.1:81', 'title', '1.1.1.1']]}
Arguments:
query: (String) fofa query string
# File lib/fofa.rb, line 64 def search_all(query, options={}) all_size = options.delete :size if options.has_key?(:size)# do not pass to search if options.has_key?(:page_size) options[:size] = options.delete :page_size end all_res = [] page = 0 loop do page += 1 res = search(query, {page:page}.merge(options)) if !res['error'] && res['results'].size > 0 all_res += res['results'] yield(res['results'], page, res['size'].to_i) if block_given? if all_size && all_res.size > all_size.to_i all_res = all_res[0..all_size-1] break end break if all_res.size >= res['size'].to_i else raise res['errmsg'] if res['errmsg'] break end end all_res end
tag_info(task_id)
click to toggle source
Check ip_tags
's task state, progress, and download_url
Example:
>> Fofa::API.new(email,apikey).tag_info(1) => {"state"=>"success", "progress"=>100, "download_url"=>"https://host/xxx/56af409c1c55762a7b9e9a39a801f80d.json"}
Arguments:
task_id: (Integer) task id
# File lib/fofa.rb, line 206 def tag_info(task_id) url = "#{@api_server}/api/v1/ip_tags/info?key=#{@apikey}&email=#{@email}&task_id=#{task_id}" puts url if @options[:debug] uri = URI.parse(url) http = http_new(uri) req = Net::HTTP::Get.new(uri.request_uri) resp = http.request(req) JSON.parse(resp.body) rescue => e $stderr.puts "[WARNING]: #{e.to_s}" {"error"=>"Error: #{e.to_s}"} end
Private Instance Methods
http_new(uri)
click to toggle source
# File lib/fofa.rb, line 221 def http_new(uri) http = Net::HTTP.new(uri.host, uri.port) if uri.scheme == 'https' http.use_ssl = true end http.set_debug_output $stderr if @options[:debug] http end