lib/mihari/analyzers/censys.rb in mihari-2.4.0 vs lib/mihari/analyzers/censys.rb in mihari-3.0.0

- old
+ new

@@ -1,88 +1,51 @@ # frozen_string_literal: true -require "censu" +require "censysx" module Mihari module Analyzers class Censys < Base - attr_reader :title, :description, :query, :tags, :type + param :query + option :title, default: proc { "Censys search" } + option :description, default: proc { "query = #{query}" } + option :tags, default: proc { [] } - def initialize(query, title: nil, description: nil, tags: [], type: "ipv4") - super() - - @query = query - @title = title || "Censys lookup" - @description = description || "query = #{query}" - @tags = tags - @type = type - end - def artifacts - case type - when "ipv4" - ipv4_lookup - when "websites" - websites_lookup - when "certificates" - certificates_lookup - else - raise InvalidInputError, "#{type} type is not supported." unless valid_type? - end + search end private - def valid_type? - %w[ipv4 websites certificates].include? type - end - - def normalize(domain) - return domain unless domain.start_with?("*.") - - domain.sub("*.", "") - end - - def ipv4_lookup + def search ipv4s = [] - res = api.ipv4.search(query: query) - res.each_page do |page| - ipv4s << page.map(&:ip) + cursor = nil + loop do + response = api.search(query, cursor: cursor) + ipv4s << response_to_ipv4s(response) + + links = response.dig("result", "links") + cursor = links["next"] + break if cursor == "" end ipv4s.flatten end - def websites_lookup - domains = [] - - res = api.websites.search(query: query) - res.each_page do |page| - domains << page.map(&:domain) - end - - domains.flatten + # + # Extract IPv4s from Censys search API response + # + # @param [Hash] response + # + # @return [Array<String>] + # + def response_to_ipv4s(response) + hits = response.dig("result", "hits") || [] + hits.map { |hit| hit["ip"] } end - def certificates_lookup - domains = [] - - res = api.certificates.search(query: query) - res.each_page do |page| - page.each do |result| - subject_dn = result.subject_dn - names = subject_dn.scan(/CN=(.+)/).flatten.first - next unless names - - domains << names.split(",").map { |domain| normalize(domain) } - end - end - - domains.flatten - end - - def config_keys + def configuration_keys %w[censys_id censys_secret] end def api @api ||= ::Censys::API.new(Mihari.config.censys_id, Mihari.config.censys_secret)