Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
85 lines (70 sloc) 2.85 KB
require 'resolv'
module Intrigue
module Task
class SearchQuad9Dns < BaseTask
def self.metadata
:name => "search_quad9_dns",
:pretty_name => "Search Quad9 DNS",
:authors => ["Anas Ben Salah"],
:description => "This task looks up whether hosts are blocked by Quad9 DNS (",
:references => [""],
:type => "discovery",
:passive => true,
:allowed_types => ["Domain", "DnsRecord"],
:example_entities => [{"type" => "Domain", "details" => {"name" => ""}}],
:allowed_options => [],
:created_types => []
## Default method, subclasses must override this
def run
res = []
entity_name = _get_entity_name
# skip cdns
if !{ |x| entity_name =~ /#{x}/}.empty? ||
!{ |x| entity_name =~ /#{x}/}.empty?
_log "This domain resolves to a known cdn or internal host, skipping"
# check that it resolves
resolves_to = resolve_names entity_name
unless resolves_to.first
_log "No resolution for this record, unable to check"
# Query quad9 nameservers
nameservers = ['']
_log "Querying #{nameservers}"
dns_obj = nameservers)
# Try twice, just in case (avoid FP's)
res = dns_obj.getaddresses(entity_name)
res.concat(dns_obj.getresources(entity_name, Resolv::DNS::Resource::IN::CNAME)).flatten
# Detected only if there's no resolution
if res.any?
_log "Resolves to #{{|x| "#{x.to_s}" }}. Seems we're good!"
source = "Quad9"
description = "Quad9 routes your DNS queries through a secure network of servers around the " +
"globe. The system uses threat intelligence from more than a dozen of the industry’s leading " +
"cyber security companies to give a real-time perspective on what websites are safe and what " +
"sites are known to include malware or other threats. If the system detects that the site you " +
"want to reach is known to be infected, you’ll automatically be blocked from entry – keeping " +
"your data and computer safe."
_create_linked_issue("blocked_by_dns", {
status: "confirmed",
additional_description: description,
source: source,
proof: "Resolved to the following address(es) outside of #{source} (#{nameservers}): #{resolves_to.join(", ")}",
to_reproduce: "dig #{entity_name} @#{nameservers.first}",
references: [{type: "remediation", uri: "" }]
# Also store it on the entity
blocked_list = @entity.get_detail("detected_malicious") || []
@entity.set_detail("detected_malicious", blocked_list.concat([{source: source}]))
end #end run
You can’t perform that action at this time.