Skip to content

Instantly share code, notes, and snippets.

@picatz
Last active July 16, 2019 02:52
Show Gist options
  • Save picatz/631e1eae1528294f2a09e0b53118834b to your computer and use it in GitHub Desktop.
Save picatz/631e1eae1528294f2a09e0b53118834b to your computer and use it in GitHub Desktop.
require 'json'
require 'async'
require 'async/http/internet'
require 'base64'
module RESTEasy
class Failure < StandardError
end
class Client
def self.internet
@internet ||= Async::HTTP::Internet.new
end
def self.auth(user, pass)
header 'Authorization', 'Basic %s' % Base64.strict_encode64([user , ':', pass].join)
end
def self.auth_bearer(token)
header 'Authorization', 'Bearer %s' % token
end
def self.url(value=nil)
return @url if value.nil?
@url = value
end
def self.default_url_param(key, value, downcase_key: true)
key = key.downcase
@default_url_params = {} if @default_url_params.nil?
@default_url_params[key] = value
end
def self.default_url_params
@default_url_params ||= {}
end
def self.default_data_param(key, value, downcase_key: true)
key = key.downcase
@default_data_params = {} if @default_data_params.nil?
@default_data_params[key] = value
end
def self.default_data_params
@default_data_params ||= {}
end
def self.headers
@headers || {}
end
def self.header(key, value)
@headers = {} if @headers.nil?
@headers[key] = value
end
def self.get(path, url_params: {}, data_params: {}, special_headers: nil)
url_path = @url+path
url_params = default_url_params.merge(url_params)
url_path += "?#{URI.encode_www_form(url_params)}"
if special_headers
case special_headers
when :url_encoded_form
get_headers = { 'content-type' => 'application/x-www-form-urlencoded' }
when :json_encoded_form
get_headers = { 'content-type' => 'application/json' }
else
get_headers = special_headers
end
else
get_headers = headers
end
if get_headers && get_headers['content-type'] == 'application/x-www-form-urlencoded'
body = URI.encode_www_form(data_params) unless data_params.empty?
else
body = data_params.empty? ? nil : JSON.dump(data_params)
end
resp = internet.get(url_path, get_headers, body)
raise Failure.new("server responded with #{resp.status}") if resp.failure?
JSON.parse(resp.read)
ensure
resp&.close
end
def self.post(path, url_params: {}, data_params: {}, special_headers: nil)
url_path = @url+path
url_params = default_url_params.merge(url_params)
url_path += "?#{URI.encode_www_form(url_params)}"
if special_headers
case special_headers
when :url_encoded_form
post_headers = { 'content-type' => 'application/x-www-form-urlencoded' }
when :json_encoded_form
post_headers = { 'content-type' => 'application/json' }
else
post_headers = special_headers
end
else
post_headers = headers
end
if post_headers && post_headers['content-type'] == 'application/x-www-form-urlencoded'
body = URI.encode_www_form(data_params) unless data_params.empty?
else
body = JSON.dump(data_params)
end
resp = internet.post(url_path, post_headers, body)
raise Failure.new("server responded with #{resp.status}") if resp.failure?
JSON.parse(resp.read)
ensure
resp&.close
end
def self.resource(name, &block)
define_method name do |*values|
block.call(*values)
end
end
end
end
@picatz
Copy link
Author

picatz commented Jul 16, 2019

class VirusTotal < RESTEasy::Client
  url 'https://www.virustotal.com/vtapi/v2'
  
  header 'accept', 'application/json'
  
  default_url_param 'apikey', ENV['VIRUS_TOTAL_API_KEY']
  
  resource :domain_report do |params|
    get('/domain/report', url_params: params)
  end
  
  resource :url_scan do |params|
    post('/url/scan', data_params: params, special_headers: :url_encoded_form)
  end
end

client = VirusTotal.new

client.url_scan(url: "google.com")
# =>{"permalink"=>"", "resource"=>"http://google.com/", "url"=>"http://google.com/", "response_code"=>1, "scan_date"=>"", "scan_id"=>"", "verbose_msg"=>"Scan request successfully queued, come back later for the report"}

client.domain_report(domain: "google.com")
# => { ... }

@picatz
Copy link
Author

picatz commented Jul 16, 2019

class Hunter < RESTEasy::Client
  url 'https://api.hunter.io/v2'

  header 'accept', 'application/json'
  
  default_url_param 'api_key', ENV['HUNTER_API_KEY']

  resource :domain_search do |params|
    get('/domain-search', url_params: params)
  end
end

client = Hunter.new

client.domain_search(domain: "google.com")
# => { ... } 

@picatz
Copy link
Author

picatz commented Jul 16, 2019

class Censys < RESTEasy::Client
  url 'https://censys.io/api/v1'

  header 'accept', 'application/json'

  auth ENV['CENYSYS_ID'], ENV['CENYSYS_SECRET'] 

  resource :account do
    get('/account')
  end
  
  resource :view do |index, id|
    get("/view/#{index}/#{id}")
  end
  
  resource :report do |index, params|
    post("/report/#{index}", data_params: params)
  end
end

client = Censys.new

client.account
# => { ... }

@picatz
Copy link
Author

picatz commented Jul 16, 2019

class Shodan < RESTEasy::Client
  url 'https://api.shodan.io/shodan'

  header "accept", "application/json"
  
  default_url_param 'key', ENV['SHODAN_API_KEY']

  resource :host do |ip|
    get("/host/#{ip}")
  end
  
  resource :scan do |ips|
    post("/scan", ips: ips.join(","))
  end
end

client = Shodan.new

client.host("8.8.8.8")
# => { ... }

client.scan(["8.8.8.8", "1.1.1.1"])
# => { ... }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment