-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathnmap2docx
More file actions
executable file
·144 lines (120 loc) · 3.49 KB
/
nmap2docx
File metadata and controls
executable file
·144 lines (120 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
#!/usr/bin/env ruby
$stderr.sync = true
begin
require 'nmap/xml'
rescue LoadError
puts "The ruby-nmap gem could not be loaded, is it installed?"
puts "-> gem install ruby-nmap"
exit
end
begin
require 'sablon'
rescue LoadError
puts "The sablon gem could not be loaded, is it installed?"
puts "-> gem install sablon"
exit
end
begin
require "docopt"
rescue LoadError
puts "The docopt gem could not be loaded, is it installed?"
puts "-> gem install docopt"
exit
end
require 'csv'
require "set"
doc = <<DOCOPT
This script accepts nmap generated xml files and generates a Word document
that contains a table with four columns: IP address, hostname, port, and
service. Only hosts with accessible ports are included. A CSV file
containing additional IP address and hostname pairs can also be specified.
Usage:
#{__FILE__} -o <docx> [-n <hostnames>] <xml>...
#{__FILE__} -h | --help
Options:
-o, --output=<docx> The generated document.
-n, --hostnames=<hostnames> CSV file containing IP addresses and hostnames.
-h, --help Show this output.
DOCOPT
begin
options = Docopt::docopt(doc)
rescue Docopt::Exit => e
STDERR.puts e.message
exit
end
# check arguments
options['<xml>'].each do |file|
if not File.exists?(file)
STDERR.puts "[!] #{file} does not exist!"
exit 1
end
end
if options['--hostnames'] and not File.exists?(options['--hostnames'])
STDERR.puts "#{options['--hostnames']} does not exist!"
exit 1
end
# variables
hosts = Hash.new
hostnames = Hash.new
results = Array.new
# process hostnames csv file
if options['--hostnames']
puts "[+] Processing hostnames in #{options['--hostnames']}"
CSV.foreach(options['--hostnames']) do |row|
ip = row[0].strip
hostname = row[1].strip.downcase
unless hostname.empty?
unless hostnames.key? ip
hostnames[ip] = SortedSet.new
end
hostnames[ip] << hostname
end
end
end
# process nmap xml files
options['<xml>'].each do |nmap|
puts "[+] Processing nmap results in #{nmap}"
Nmap::XML.new(nmap) do |xml|
xml.each_host do |host|
host.each_hostname do |hostname|
unless hostnames.key? host.ip
hostnames[host.ip] = SortedSet.new
end
hostnames[host.ip] << hostname.name.strip.downcase
end
host.each_port do |port|
if port.state == :open
unless port.service.nil?
if port.service.ssl?
name = "ssl/#{port.service.name}"
else
name = port.service.name
end
unless name.include? 'tcpwrapped'
unless hosts.key? host.ip
hosts[host.ip] = Array.new
end
hosts[host.ip] << { :port => port.number, :proto => port.protocol, :name => name }
end
else
hosts[host.ip] << { :port => port.number, :proto => port.protocol, :name => 'unknown' }
end
end
end
end
end
end
# build data array ready for import
hosts.each do |ip, services|
if hostnames.key? ip
names = hostnames[ip].to_a
else
names = Array.new
end
results << { :ip => ip, :hostnames => names, :services => services.sort_by { |service| service[:port] } }
end
# import data into word document template
puts "[+] Generating document #{options['--output']} ..."
context = { :hosts => results }
template = Sablon.template(File.expand_path(File.dirname(__FILE__) + "/nmap2docx.docx"))
template.render_to_file File.expand_path(options['--output']), context