Module: PWN::Plugins::IPInfo
- Defined in:
- lib/pwn/plugins/ip_info.rb
Overview
This plugin leverages ip-api.com’s REST API to discover information about IP addresses 1,000 daily requests are allowed for free
Class Method Summary collapse
-
.authors ⇒ Object
- Author(s)
-
0day Inc.
-
.bruteforce_subdomains(opts = {}) ⇒ Object
- Supported Method Parameters
-
PWN::Plugins::IPInfo.bruteforce_subdomains( parent_domain: ‘required - Parent Domain to brute force’, dictionary: ‘required - Dictionary to use for subdomain brute force’, max_threads: ‘optional - Maximum number of threads to use (default: 9)’, proxy: ‘optional - use a proxy’, tls_port: ‘optional port to check cert for Domain Name (default: 443). Will not execute if proxy parameter is set.’, results_file: ‘optional - File to write results to (default: /tmp/parent_domain-timestamp-pwn_bruteforce_subdomains.txt)’ ).
-
.check_rfc1918(opts = {}) ⇒ Object
- Supported Method Parameters
-
is_rfc1918 = PWN::Plugins::IPInfo.check_rfc1918( ip: ‘required - IP to check’ ).
-
.get(opts = {}) ⇒ Object
- Supported Method Parameters
-
ip_info_struc = PWN::Plugins::IPInfo.get( target: ‘required - IP or Host to lookup’, proxy: ‘optional - use a proxy’, tls_port: ‘optional port to check cert for Domain Name (default: 443). Will not execute if proxy parameter is set.’, skip_api: ‘optional - skip the API call’, dns_server: ‘optional - DNS server to use for lookup (default: your default DNS server)’ ).
-
.help ⇒ Object
Display Usage for this Module.
Class Method Details
.authors ⇒ Object
- Author(s)
-
0day Inc. <[email protected]>
228 229 230 231 232 |
# File 'lib/pwn/plugins/ip_info.rb', line 228 public_class_method def self. "AUTHOR(S): 0day Inc. <[email protected]> " end |
.bruteforce_subdomains(opts = {}) ⇒ Object
- Supported Method Parameters
-
PWN::Plugins::IPInfo.bruteforce_subdomains(
parent_domain: 'required - Parent Domain to brute force', dictionary: 'required - Dictionary to use for subdomain brute force', max_threads: 'optional - Maximum number of threads to use (default: 9)', proxy: 'optional - use a proxy', tls_port: 'optional port to check cert for Domain Name (default: 443). Will not execute if proxy parameter is set.', results_file: 'optional - File to write results to (default: /tmp/parent_domain-timestamp-pwn_bruteforce_subdomains.txt)'
)
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/pwn/plugins/ip_info.rb', line 169 public_class_method def self.bruteforce_subdomains(opts = {}) parent_domain = opts[:parent_domain].to_s.scrub.strip.chomp raise 'ERROR: parent_domain parameter is required' if parent_domain.empty? default_dictionary = '/usr/share/seclists/Discovery/DNS/n0kovo_subdomains.txt' dictionary = opts[:dictionary] ||= default_dictionary raise "ERROR: Dictionary file not found: #{dictionary}" unless File.exist?(dictionary) max_threads = opts[:max_threads] proxy = opts[:proxy] tls_port = opts[:tls_port] = Time.now.strftime('%Y-%m-%d_%H.%M.%S') results_file = opts[:results_file] ||= "/tmp/SUBS.#{parent_domain}-#{}-pwn_bruteforce_subdomains.txt" File.write(results_file, "[\n") # Break up dictonary file into sublines and process each subline in a thread dict_lines = File.readlines(dictionary).shuffle mutex = Mutex.new PWN::Plugins::ThreadPool.fill( enumerable_array: dict_lines, max_threads: max_threads ) do |subline| print '.' subdomain = subline.to_s.scrub.strip.chomp target = parent_domain if subdomain.empty? target = "#{subdomain}.#{parent_domain}" unless subdomain.empty? ip_info_resp = get( target: target, proxy: proxy, tls_port: tls_port, skip_api: true ) mutex.synchronize do File.open(results_file, 'a') do |file| resp_len = ip_info_resp.length next unless resp_len.positive? ip_info_resp.each do |ip_info_hash| file.puts "#{JSON.generate(ip_info_hash)}," end end end end rescue StandardError => e raise e ensure # Strip trailing comma and close JSON array final_results = File.readlines(results_file).uniq # Strip trailing newline and comma from last line last_line = final_results[-1].chomp.chomp(',') final_results[-1] = last_line File.write(results_file, "#{final_results.join}\n]") end |
.check_rfc1918(opts = {}) ⇒ Object
- Supported Method Parameters
-
is_rfc1918 = PWN::Plugins::IPInfo.check_rfc1918(
ip: 'required - IP to check'
)
55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/pwn/plugins/ip_info.rb', line 55 public_class_method def self.check_rfc1918(opts = {}) ip = opts[:ip].to_s.scrub.strip.chomp ip_obj = IPAddress.valid?(ip) ? IPAddress.parse(ip) : nil rfc1918_ranges = [ IPAddress('10.0.0.0/8'), # 10.0.0.0 - 10.255.255.255 IPAddress('172.16.0.0/12'), # 172.16.0.0 - 172.31.255.255 IPAddress('192.168.0.0/16') # 192.168.0.0 - 192.168.255.255 ] rfc1918_ranges.any? { |range| range.include?(ip_obj) } end |
.get(opts = {}) ⇒ Object
- Supported Method Parameters
-
ip_info_struc = PWN::Plugins::IPInfo.get(
target: 'required - IP or Host to lookup', proxy: 'optional - use a proxy', tls_port: 'optional port to check cert for Domain Name (default: 443). Will not execute if proxy parameter is set.', skip_api: 'optional - skip the API call', dns_server: 'optional - DNS server to use for lookup (default: your default DNS server)'
)
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/pwn/plugins/ip_info.rb', line 77 public_class_method def self.get(opts = {}) target = opts[:target].to_s.scrub.strip.chomp.downcase proxy = opts[:proxy] tls_port = opts[:tls_port] ||= 443 skip_api = opts[:skip_api] ||= false ip_info_resp = [] is_ip = IPAddress.valid?(target) hostname = '' if is_ip target_arr = [target] if is_ip unless is_ip begin hostname = target dns_server = opts[:dns_server] dns_resolver = Resolv::DNS.new(nameserver: [dns_server]) if dns_server dns_resolver ||= Resolv::DNS.new target_arr = dns_resolver.getaddresses(target).map(&:to_s).uniq rescue Resolv::ResolvError target_arr = nil end end target_arr.each do |this_target| ip_resp_hash = ip_info_rest_call(ip: this_target, proxy: proxy) unless skip_api ip_resp_hash ||= {} is_rfc1918 = check_rfc1918(ip: this_target) ip_resp_hash[:ip] = this_target ip_resp_hash[:is_rfc1918] = is_rfc1918 ip_resp_hash[:hostname] = hostname ip_info_resp.push(ip_resp_hash) unless target_arr.nil? next unless proxy.nil? ip_info_resp.each do |ip_resp| tls_port_avail = PWN::Plugins::Sock.check_port_in_use( server_ip: this_target, port: tls_port ) ip_resp[:tls_avail] = tls_port_avail ip_resp[:ca_issuer_uris] = nil ip_resp[:cert_subject] = nil ip_resp[:cert_issuer] = nil ip_resp[:cert_serial] = nil ip_resp[:crl_uris] = nil ip_resp[:extensions] = nil ip_resp[:not_before] = nil ip_resp[:not_after] = nil ip_resp[:oscsp_uris] = nil ip_resp[:pem] = nil ip_resp[:signature_algorithm] = nil ip_resp[:version] = nil next unless tls_port_avail cert_obj = PWN::Plugins::Sock.get_tls_cert( target: this_target, port: tls_port ) next unless cert_obj.is_a?(OpenSSL::X509::Certificate) ip_resp[:ca_issuer_uris] = cert_obj.ca_issuer_uris.map(&:to_s) unless cert_obj.ca_issuer_uris.nil? ip_resp[:cert_subject] = cert_obj.subject.to_s ip_resp[:cert_issuer] = cert_obj.issuer.to_s ip_resp[:cert_serial] = cert_obj.serial.to_s ip_resp[:crl_uris] = cert_obj.crl_uris.map(&:to_s) unless cert_obj.crl_uris.nil? ip_resp[:extensions] = cert_obj.extensions.to_h { |ext| [ext.oid.to_s.to_sym, ext.value] } unless cert_obj.extensions.nil? ip_resp[:not_before] = cert_obj.not_before.to_s ip_resp[:not_after] = cert_obj.not_after.to_s ip_resp[:oscsp_uris] = cert_obj.ocsp_uris.map(&:to_s) unless cert_obj.ocsp_uris.nil? ip_resp[:pem] = cert_obj.to_pem.to_s ip_resp[:signature_algorithm] = cert_obj.signature_algorithm.to_s ip_resp[:version] = cert_obj.version.to_s end end ip_info_resp rescue StandardError => e raise e end |
.help ⇒ Object
Display Usage for this Module
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/pwn/plugins/ip_info.rb', line 236 public_class_method def self.help puts "USAGE: is_rfc1918 = #{self}.check_rfc1918( ip: 'required - IP to check' ) ip_info_struc = #{self}.get( target: 'required - IP or Host to lookup', proxy: 'optional - use a proxy', tls_port: 'optional port to check cert for Domain Name (default: 443). Will not execute if proxy parameter is set.', skip_api: 'optional - skip the API call', dns_server: 'optional - DNS server to use for lookup (default: your default DNS server)' ) #{self}.bruteforce_subdomains( parent_domain: 'required - Parent Domain to brute force', dictionary: 'required - Dictionary to use for subdomain brute force', max_threads: 'optional - Maximum number of threads to use (default: 9)', proxy: 'optional - use a proxy', tls_port: 'optional port to check cert for Domain Name (default: 443). Will not execute if proxy parameter is set.', results_file: 'optional - File to write results to (default: /tmp/parent_domain-timestamp-pwn_bruteforce_subdomains.txt)' ) #{self}.authors " end |