Last active
December 25, 2017 19:20
-
-
Save Napear/82a5424385242ef02cb9de8172b252b5 to your computer and use it in GitHub Desktop.
An automation script for initial nmap recon of an unknown subnet space.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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