|
| 1 | +# -*- coding: binary -*- |
| 2 | + |
| 3 | +class Msf::Ui::Console::CommandDispatcher::DNS |
| 4 | + |
| 5 | + include Msf::Ui::Console::CommandDispatcher |
| 6 | + |
| 7 | + @@add_opts = Rex::Parser::Arguments.new( |
| 8 | + ['-r', '--rule'] => [true, 'Set a DNS wildcard entry to match against' ], |
| 9 | + ['-s', '--session'] => [true, 'Force the DNS request to occur over a particular channel (override routing rules)' ], |
| 10 | + ) |
| 11 | + |
| 12 | + def initialize(driver) |
| 13 | + super |
| 14 | + end |
| 15 | + |
| 16 | + def name |
| 17 | + 'DNS' |
| 18 | + end |
| 19 | + |
| 20 | + def commands |
| 21 | + commands = {} |
| 22 | + |
| 23 | + if framework.features.enabled?(Msf::FeatureManager::DNS_FEATURE) |
| 24 | + commands = { |
| 25 | + 'dns' => "Manage Metasploit's DNS resolving behaviour" |
| 26 | + } |
| 27 | + end |
| 28 | + commands |
| 29 | + end |
| 30 | + |
| 31 | + def cmd_dns_help |
| 32 | + print_line 'Usage: dns' |
| 33 | + print_line |
| 34 | + print_line "Manage Metasploit's DNS resolution behaviour" |
| 35 | + print_line |
| 36 | + print_line "Usage:" |
| 37 | + print_line " dns [add/remove] [--session <session_id>] [--rule <wildcard DNS entry>] <IP Address> <IP Address> ..." |
| 38 | + print_line " dns [get] <hostname>" |
| 39 | + print_line " dns [flush]" |
| 40 | + print_line " dns [print]" |
| 41 | + print_line |
| 42 | + print_line "Subcommands:" |
| 43 | + print_line " add - add a DNS resolution entry to resolve certain domain names through a particular DNS server" |
| 44 | + print_line " remove - delete a DNS resolution entry; 'del' is an alias" |
| 45 | + print_line " flush - remove all DNS resolution entries" |
| 46 | + print_line " get - display the DNS server(s) and communication channel that would be used for a given target" |
| 47 | + print_line " print - show all active DNS resolution entries" |
| 48 | + print_line |
| 49 | + print_line "Examples:" |
| 50 | + print_line " Set the DNS server to be used for *.metasploit.com to 192.168.1.10" |
| 51 | + print_line " route add --rule *.metasploit.com 192.168.1.10" |
| 52 | + print_line |
| 53 | + print_line " Set the DNS server to be used for *.metasploit.com to 192.168.1.10, but specifically to go through session 2" |
| 54 | + print_line " route add --session 2 --rule *.metasploit.com 192.168.1.10" |
| 55 | + print_line |
| 56 | + print_line " Delete the above DNS resolution rule" |
| 57 | + print_line " route remove --session 2 --rule *.metasploit.com 192.168.1.10" |
| 58 | + print_line |
| 59 | + print_line " Set the DNS server to be used for all requests that match no rules" |
| 60 | + print_line " route add 8.8.8.8 8.8.4.4" |
| 61 | + print_line |
| 62 | + print_line " Display the DNS server that would be used for the given domain name" |
| 63 | + print_line " route get subdomain.metasploit.com" |
| 64 | + print_line |
| 65 | + end |
| 66 | + |
| 67 | + # |
| 68 | + # Manage Metasploit's DNS resolution rules |
| 69 | + # |
| 70 | + def cmd_dns(*args) |
| 71 | + args << 'print' if args.length == 0 |
| 72 | + # Short-circuit help |
| 73 | + if args.delete("-h") || args.delete("--help") |
| 74 | + cmd_dns_help |
| 75 | + return |
| 76 | + end |
| 77 | + |
| 78 | + action = args.shift |
| 79 | + begin |
| 80 | + case action |
| 81 | + when "add" |
| 82 | + add_dns(*args) |
| 83 | + when "remove", "del" |
| 84 | + remove_dns(*args) |
| 85 | + when "purge" |
| 86 | + purge_dns(*args) |
| 87 | + when "print" |
| 88 | + print_dns(*args) |
| 89 | + when "help" |
| 90 | + cmd_dns_help |
| 91 | + end |
| 92 | + rescue ::ArgumentError => e |
| 93 | + print_error(e.message) |
| 94 | + end |
| 95 | + end |
| 96 | + |
| 97 | + def add_dns(*args) |
| 98 | + rules = [] |
| 99 | + comm = nil |
| 100 | + servers = [] |
| 101 | + @@add_opts.parse(args) do |opt, idx, val| |
| 102 | + unless servers.empty? || opt.nil? |
| 103 | + raise ::ArgumentError.new("Invalid command near #{opt}") |
| 104 | + end |
| 105 | + case opt |
| 106 | + when '--rule', '-r' |
| 107 | + if val.nil? |
| 108 | + raise ::ArgumentError.new('No rule specified') |
| 109 | + end |
| 110 | + |
| 111 | + rules << val |
| 112 | + when '--session', '-s' |
| 113 | + if val.nil? |
| 114 | + raise ::ArgumentError.new('No session specified') |
| 115 | + end |
| 116 | + |
| 117 | + unless comm.nil? |
| 118 | + raise ::ArgumentError.new('Only one session can be specified') |
| 119 | + end |
| 120 | + |
| 121 | + comm = val |
| 122 | + when nil |
| 123 | + servers << val |
| 124 | + else |
| 125 | + raise ::ArgumentError.new("Unknown flag: #{opt}") |
| 126 | + end |
| 127 | + end |
| 128 | + |
| 129 | + # The remaining args should be the DNS servers |
| 130 | + |
| 131 | + if servers.length < 1 |
| 132 | + raise ::ArgumentError.new("You must specify at least one DNS server") |
| 133 | + end |
| 134 | + |
| 135 | + servers.each do |host| |
| 136 | + unless host =~ Resolv::IPv4::Regex || |
| 137 | + host =~ Resolv::IPv6::Regex |
| 138 | + raise ::ArgumentError.new("Invalid DNS server: #{host}") |
| 139 | + end |
| 140 | + end |
| 141 | + end |
| 142 | + |
| 143 | + def remove_dns(*args) |
| 144 | + end |
| 145 | + |
| 146 | + def purge_dns(*args) |
| 147 | + end |
| 148 | + |
| 149 | + def print_dns(*args) |
| 150 | + end |
| 151 | +end |
0 commit comments