Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/rex/proto/dns/upstream_rule.rb
Views: 11704
# -*- coding: binary -*-12require 'json'3require 'rex/socket'45module Rex6module Proto7module DNS8##9# This represents a configuration rule for how names should be resolved. It matches a single wildcard which acts as a10# matching condition and maps it to 0 or more resolvers to use for lookups.11##12class UpstreamRule1314attr_reader :wildcard, :resolvers, :comm15# @param [String] wildcard The wildcard pattern to use for conditionally matching hostnames.16# @param [Array] resolvers The resolvers to use when this rule is applied.17# @param [Msf::Session::Comm] comm The communication channel to use when creating network connections.18def initialize(wildcard: '*', resolvers: [], comm: nil)19::ArgumentError.new("Invalid wildcard text: #{wildcard}") unless self.class.valid_wildcard?(wildcard)20@wildcard = wildcard21socket_options = {}22socket_options['Comm'] = comm unless comm.nil?23@resolvers = resolvers.map do |resolver|24if resolver.is_a?(String) && !Rex::Socket.is_ip_addr?(resolver)25resolver = resolver.downcase.to_sym26end2728case resolver29when UpstreamResolver30resolver31when UpstreamResolver::Type::BLACK_HOLE32UpstreamResolver.create_black_hole33when UpstreamResolver::Type::STATIC34UpstreamResolver.create_static35when UpstreamResolver::Type::SYSTEM36UpstreamResolver.create_system37else38if Rex::Socket.is_ip_addr?(resolver)39UpstreamResolver.create_dns_server(resolver, socket_options: socket_options)40else41raise ::ArgumentError.new("Invalid upstream DNS resolver: #{resolver}")42end43end44end45@comm = comm46end4748# Check whether or not the defined resolver is valid.49#50# @param [String] resolver The resolver string to check.51# @rtype Boolean52def self.valid_resolver?(resolver)53return true if Rex::Socket.is_ip_addr?(resolver)5455resolver = resolver.downcase.to_sym56[57UpstreamResolver::Type::BLACK_HOLE,58UpstreamResolver::Type::STATIC,59UpstreamResolver::Type::SYSTEM60].include?(resolver)61end6263# Perform a spell check on resolver to suggest corrections.64#65# @param [String] resolver The resolver string to check.66# @rtype [Nil, Array<String>] The suggestions if resolver is invalid.67def self.spell_check_resolver(resolver)68return nil if Rex::Socket.is_ip_addr?(resolver)6970suggestions = DidYouMean::SpellChecker.new(dictionary: [71UpstreamResolver::Type::BLACK_HOLE,72UpstreamResolver::Type::STATIC,73UpstreamResolver::Type::SYSTEM74]).correct(resolver).map(&:to_s)75return nil if suggestions.empty?7677suggestions78end7980# Check whether or not the defined wildcard is a valid pattern.81#82# @param [String] wildcard The wildcard text to check.83# @rtype Boolean84def self.valid_wildcard?(wildcard)85wildcard == '*' || wildcard =~ /^(\*\.)?([a-z\d][a-z\d-]*[a-z\d]\.)+[a-z]+$/86end8788# Check whether or not the currently configured wildcard pattern will match all names.89#90# @rtype Boolean91def matches_all?92wildcard == '*'93end9495# Check whether or not the specified name matches the currently configured wildcard pattern.96#97# @rtype Boolean98def matches_name?(name)99if matches_all?100true101elsif wildcard.start_with?('*.')102name.downcase.end_with?(wildcard[1..-1].downcase)103else104name.casecmp?(wildcard)105end106end107108def eql?(other)109return false unless other.is_a?(self.class)110return false unless other.wildcard == wildcard111return false unless other.resolvers == resolvers112return false unless other.comm == comm113true114end115116alias == eql?117end118end119end120end121122123