Skip to content

Instantly share code, notes, and snippets.

@Napear
Last active December 25, 2017 19:20
Show Gist options
  • Save Napear/82a5424385242ef02cb9de8172b252b5 to your computer and use it in GitHub Desktop.
Save Napear/82a5424385242ef02cb9de8172b252b5 to your computer and use it in GitHub Desktop.
An automation script for initial nmap recon of an unknown subnet space.
require 'ipaddr'
require 'nokogiri'
# Helper functions
def debug_message(output)
puts "[##] Debug: #{output}"
end
def pluralize(subject)
's' if subject.size > 1
end
# Define Scans
def ping_sweep(range)
Nokogiri::XML(`sudo nmap -sP -oX - #{range}`).xpath('//host//address')
end
def fast_scan(ip)
puts "[*] Starting quick scan of #{ip}"
findings = Nokogiri::XML(`sudo nmap -F -sU -sS -oX - #{ip}`)
found_ports = findings.xpath('//ports//port')
.select {|x| x.xpath('//state')[0]['state'] == 'open'}
.map {|x| x['portid']}
.uniq
if found_ports.size == 0
puts "[*] No standard ports open on #{ip}"
else
puts "[*] #{found_ports.size} open ports identified on #{ip}..."
puts "[*] Ports identified #{found_ports.join('; ')} " if found_ports.size < 10
end
findings
end
def deep_scan(ip, ports)
puts "[*] Starting version scan of services on #{ip}"
findings = Nokogiri::XML(`sudo nmap -sV -sU -sS -O -p #{ports.join(',')} -oX - -oG #{ip}_nmap.txt #{ip}`)
begin
hostname = findings.xpath('//hostname')[0]['name']
rescue NoMethodError
hostname = 'unknown'
end
begin
os = findings.xpath('//osmatch')[0]['name']
rescue NoMethodError
os = 'unknown'
end
os_acc = findings.xpath('//osmatch')[0]['accuracy'] unless os == 'unknown'
puts "[*] Scan completed: Identified systems hostname as '#{hostname}'"
puts "[*] Best Guest for OS: #{os} #{"with #{os_acc}% certainty" unless os == 'unknown'}"
findings
end
# Summary method
def print_summary(data)
# TODO:// implement nice tables and stuff
puts "[@] Whatever dingus wrote this hasn't implemented a summary..."
puts "[@] So... the scans are done... found #{data.size} interesting hosts.."
puts "[@] Probably a bunch of services too... check the files"
end
# Check command line arguments
if ARGV.empty?
puts '[!!] Please enter a valid IP address or range'
exit
end
ip_range = ARGV[0].chomp
begin
IPAddr.new ip_range
rescue
puts '[!!] Please enter a valid IP address or range'
exit
end
# Begin scanning script
puts "[*] Beginning ping sweep against #{ip_range}"
ips = ip_range.include?('/') ? ping_sweep(ip_range)
.select {|x| x['addrtype'] == 'ipv4'}
.map {|x| x['addr']} : [ip_range]
if ips.empty?
puts '[!] No responses detected'
exit
else
puts "[*] Found #{ips.size} IP#{pluralize(ips)}."
puts "[*] Beginning fast scan#{pluralize(ips)}"
end
fscan_data = ips.map do |ip|
fast_scan (ip)
end
puts "[*] Beginning OS and version detection scan#{pluralize(ips)}"
dscan_data = fscan_data.map do |host|
open_ports = host.xpath('//ports//port')
.select {|x| x.xpath('//state')[0]['state'] == 'open'}
.map {|x| x['portid']}
.uniq
ip = host.xpath('//address')[0]['addr']
deep_scan(ip, open_ports) unless open_ports.empty?
end
print_summary dscan_data.compact
nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment