ruby-masscan 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.document +3 -0
- data/.editorconfig +11 -0
- data/.github/workflows/ruby.yml +29 -0
- data/.gitignore +11 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +6 -0
- data/Gemfile +15 -0
- data/LICENSE.txt +20 -0
- data/README.md +139 -0
- data/Rakefile +23 -0
- data/gemspec.yml +28 -0
- data/lib/masscan/banner.rb +11 -0
- data/lib/masscan/output_file.rb +100 -0
- data/lib/masscan/parsers/binary.rb +591 -0
- data/lib/masscan/parsers/json.rb +106 -0
- data/lib/masscan/parsers/list.rb +84 -0
- data/lib/masscan/parsers/plain_text.rb +151 -0
- data/lib/masscan/parsers.rb +3 -0
- data/lib/masscan/program.rb +100 -0
- data/lib/masscan/status.rb +7 -0
- data/lib/masscan/task.rb +179 -0
- data/lib/masscan/version.rb +4 -0
- data/lib/masscan.rb +2 -0
- data/ruby-masscan.gemspec +61 -0
- data/spec/fixtures/masscan.bin +0 -0
- data/spec/fixtures/masscan.json +17 -0
- data/spec/fixtures/masscan.list +10 -0
- data/spec/fixtures/masscan.ndjson +8 -0
- data/spec/fixtures/masscan.xml +17 -0
- data/spec/output_file_spec.rb +135 -0
- data/spec/parsers/binary_spec.rb +224 -0
- data/spec/parsers/json_spec.rb +157 -0
- data/spec/parsers/list_spec.rb +109 -0
- data/spec/parsers/parser_examples.rb +58 -0
- data/spec/parsers/plain_text_spec.rb +116 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/task_spec.rb +121 -0
- metadata +117 -0
data/lib/masscan/task.rb
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
require 'rprogram/task'
|
2
|
+
|
3
|
+
module Masscan
|
4
|
+
#
|
5
|
+
# ## `masscan` options:
|
6
|
+
#
|
7
|
+
# * `--range` - `masscan.range`
|
8
|
+
# * `-p` - `masscan.ports`
|
9
|
+
# * `--banners` - `masscan.banners`
|
10
|
+
# * `--rate` - `masscan.rate`
|
11
|
+
# * `--conf` - `masscan.config_file`
|
12
|
+
# * `--resume` - `masscan.resume`
|
13
|
+
# * `--echo` - `masscan.echo`
|
14
|
+
# * `--adapter` - `masscan.adapter`
|
15
|
+
# * `--adapter-ip` - `masscan.adapter_ip`
|
16
|
+
# * `--adapter-port` - `masscan.adapter_port`
|
17
|
+
# * `--adapter-mac` - `masscan.adapter_mac`
|
18
|
+
# * `--adapter-vlan` - `masscan.adapter_vlan`
|
19
|
+
# * `--router-mac` - `masscan.router_mac`
|
20
|
+
# * `--ping` - `masscan.ping`
|
21
|
+
# * `--exclude` - `masscan.exclude`
|
22
|
+
# * `--excludefile` - `masscan.exclude_file`
|
23
|
+
# * `--includefile` - `masscan.include_file`
|
24
|
+
# * `--append-output` - `masscan.append_output`
|
25
|
+
# * `--iflist` - `masscan.list_interfaces`
|
26
|
+
# * `--retries` - `masscan.retries`
|
27
|
+
# * `--nmap` - `masscan.nmap_help`
|
28
|
+
# * `--pcap-payloads` - `masscan.pcap_payloads`
|
29
|
+
# * `--nmap-payloads` - `masscan.nmap_payloads`
|
30
|
+
# * `--http-method` - `masscan.http_method`
|
31
|
+
# * `--http-url` - `masscan.http_url`
|
32
|
+
# * `--http-version` - `masscan.http_version`
|
33
|
+
# * `--http-host` - `masscan.http_host`
|
34
|
+
# * `--http-user-agent` - `masscan.http_user_agent`
|
35
|
+
# * `--http-field` - `masscan.http_field`
|
36
|
+
# * `--http-field-remove` - `masscan.http_field_remove`
|
37
|
+
# * `--http-cookie` - `masscan.http_cookie`
|
38
|
+
# * `--http-payload` - `masscan.http_payload`
|
39
|
+
# * `--show` - `masscan.show`
|
40
|
+
# * `--noshow` - `masscan.hide`
|
41
|
+
# * `--pcap` - `masscan.pcap`
|
42
|
+
# * `--packet-trace` - `masscan.packet_trace`
|
43
|
+
# * `--pfring` - `masscan.pfring`
|
44
|
+
# * `--resume-index` - `masscan.resume_index`
|
45
|
+
# * `--resume-count` - `masscan.resume_count`
|
46
|
+
# * `--shards` - `masscan.shards`
|
47
|
+
# * `--rotate` - `masscan.rotate`
|
48
|
+
# * `--rotate-offset` - `masscan.rotate_offset`
|
49
|
+
# * `--rotate-size` - `masscan.rotate_size`
|
50
|
+
# * `--rotate-dir` - `masscan.rotate_dir`
|
51
|
+
# * `--seed` - `masscan.seed`
|
52
|
+
# * `--regress` - `masscan.regress`
|
53
|
+
# * `--ttl` - `masscan.ttl`
|
54
|
+
# * `--wait` - `masscan.wait`
|
55
|
+
# * `--offline` - `masscan.offline`
|
56
|
+
# * `-sL` - `masscan.print_list`
|
57
|
+
# * `--interactive` - `masscan.interactive`
|
58
|
+
# * `--output-format` - `masscan.output_format`
|
59
|
+
# * `--output-filename` - `masscan.output_file`
|
60
|
+
# * `-oB` - `masscan.output_binary`
|
61
|
+
# * `-oX` - `masscan.output_xml`
|
62
|
+
# * `-oG` - `masscan.output_grepable`
|
63
|
+
# * ` -oJ` - `masscan.output_json`
|
64
|
+
# * `-oL` - `masscan.output_list`
|
65
|
+
# * `--readscan` - `masscan.read_scan`
|
66
|
+
# * `-V` - `masscan.version`
|
67
|
+
# * `-h` - `masscan.help`
|
68
|
+
#
|
69
|
+
# @see https://github.com/robertdavidgraham/masscan/blob/master/doc/masscan.8.markdown
|
70
|
+
#
|
71
|
+
class Task < RProgram::Task
|
72
|
+
|
73
|
+
long_option flag: '--range', name: :range, separator: ','
|
74
|
+
short_option flag: '-p', name: :ports do |opt,value|
|
75
|
+
unless value.empty?
|
76
|
+
[opt.flag, format_port_list(value)]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
long_option flag: '--banners', name: :banners
|
80
|
+
long_option flag: '--rate', name: :rate
|
81
|
+
long_option flag: '--conf', name: :config_file
|
82
|
+
long_option flag: '--resume', name: :resume
|
83
|
+
long_option flag: '--echo', name: :echo
|
84
|
+
long_option flag: '--adapter', name: :adapter
|
85
|
+
long_option flag: '--adapter-ip', name: :adapter_ip
|
86
|
+
long_option flag: '--adapter-port', name: :adapter_port
|
87
|
+
long_option flag: '--adapter-mac', name: :adapter_mac
|
88
|
+
long_option flag: '--adapter-vlan', name: :adapter_vlan
|
89
|
+
long_option flag: '--router-mac', name: :router_mac
|
90
|
+
long_option flag: '--ping', name: :ping
|
91
|
+
long_option flag: '--exclude', name: :exclude, separator: ','
|
92
|
+
long_option flag: '--excludefile', name: :exclude_file
|
93
|
+
long_option flag: '--includefile', name: :include_file
|
94
|
+
long_option flag: '--append-output', name: :append_output
|
95
|
+
long_option flag: '--iflist', name: :list_interfaces
|
96
|
+
long_option flag: '--retries', name: :retries
|
97
|
+
long_option flag: '--nmap', name: :nmap_help
|
98
|
+
long_option flag: '--pcap-payloads', name: :pcap_payloads
|
99
|
+
long_option flag: '--nmap-payloads', name: :nmap_payloads
|
100
|
+
|
101
|
+
long_option flag: '--http-method', name: :http_method
|
102
|
+
long_option flag: '--http-url', name: :http_url
|
103
|
+
long_option flag: '--http-version', name: :http_version
|
104
|
+
long_option flag: '--http-host', name: :http_host
|
105
|
+
long_option flag: '--http-user-agent', name: :http_user_agent
|
106
|
+
|
107
|
+
long_option flag: '--http-field', multiple: true do |opt,value|
|
108
|
+
name, value = value.first
|
109
|
+
|
110
|
+
[opt.flag, "#{name}:#{value}"]
|
111
|
+
end
|
112
|
+
|
113
|
+
long_option flag: '--http-field-remove', name: :http_field_remove
|
114
|
+
long_option flag: '--http-cookie', name: :http_cookie
|
115
|
+
long_option flag: '--http-payload', name: :http_payload
|
116
|
+
|
117
|
+
long_option flag: '--show', name: :show
|
118
|
+
long_option flag: '--noshow', name: :hide
|
119
|
+
long_option flag: '--pcap', name: :pcap
|
120
|
+
long_option flag: '--packet-trace', name: :packet_trace
|
121
|
+
long_option flag: '--pfring', name: :pfring
|
122
|
+
long_option flag: '--resume-index', name: :resume_index
|
123
|
+
long_option flag: '--resume-count', name: :resume_count
|
124
|
+
long_option flag: '--shards', name: :shards do |opt,value|
|
125
|
+
case value.length
|
126
|
+
when 2 then [opt.flag, "#{value[0]}/#{value[1]}"]
|
127
|
+
when 1 then [opt.flag, "#{value[0]}"]
|
128
|
+
else
|
129
|
+
raise(ArgumentError,"#{self}#shards= does not accept more than two values")
|
130
|
+
end
|
131
|
+
end
|
132
|
+
long_option flag: '--rotate', name: :rotate
|
133
|
+
long_option flag: '--rotate-offset', name: :rotate_offset
|
134
|
+
long_option flag: '--rotate-size', name: :rotate_size
|
135
|
+
long_option flag: '--rotate-dir', name: :rotate_dir
|
136
|
+
long_option flag: '--seed', name: :seed
|
137
|
+
long_option flag: '--regress', name: :regress
|
138
|
+
long_option flag: '--ttl', name: :ttl
|
139
|
+
long_option flag: '--wait', name: :wait
|
140
|
+
long_option flag: '--offline', name: :offline
|
141
|
+
short_option flag: '-sL', name: :print_list
|
142
|
+
long_option flag: '--interactive', name: :interactive
|
143
|
+
long_option flag: '--output-format', name: :output_format
|
144
|
+
long_option flag: '--output-filename', name: :output_file
|
145
|
+
short_option flag: '-oB', name: :output_binary
|
146
|
+
short_option flag: '-oX', name: :output_xml
|
147
|
+
short_option flag: '-oG', name: :output_grepable
|
148
|
+
short_option flag:' -oJ', name: :output_json
|
149
|
+
short_option flag: '-oL', name: :output_list
|
150
|
+
long_option flag: '--readscan', name: :read_scan
|
151
|
+
short_option :flag => '-V', :name => :version
|
152
|
+
short_option :flag => '-h', :name => :help
|
153
|
+
|
154
|
+
non_option :tailing => true, :name => :ips
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
#
|
159
|
+
# Formats a port list.
|
160
|
+
#
|
161
|
+
# @param [Array<Integer,Range>] ports
|
162
|
+
# The port ranges.
|
163
|
+
#
|
164
|
+
# @return [String]
|
165
|
+
# Comma separated string.
|
166
|
+
#
|
167
|
+
def self.format_port_list(ports)
|
168
|
+
ports.map { |port|
|
169
|
+
case port
|
170
|
+
when Range
|
171
|
+
"#{port.first}-#{port.last}"
|
172
|
+
else
|
173
|
+
port.to_s
|
174
|
+
end
|
175
|
+
}.join(',')
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|
data/lib/masscan.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gemspec = YAML.load_file('gemspec.yml')
|
7
|
+
|
8
|
+
gem.name = gemspec.fetch('name')
|
9
|
+
gem.version = gemspec.fetch('version') do
|
10
|
+
lib_dir = File.join(File.dirname(__FILE__),'lib')
|
11
|
+
$LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
|
12
|
+
|
13
|
+
require 'masscan/version'
|
14
|
+
Masscan::VERSION
|
15
|
+
end
|
16
|
+
|
17
|
+
gem.summary = gemspec['summary']
|
18
|
+
gem.description = gemspec['description']
|
19
|
+
gem.licenses = Array(gemspec['license'])
|
20
|
+
gem.authors = Array(gemspec['authors'])
|
21
|
+
gem.email = gemspec['email']
|
22
|
+
gem.homepage = gemspec['homepage']
|
23
|
+
gem.metadata = gemspec['metadata'] if gemspec['metadata']
|
24
|
+
|
25
|
+
glob = lambda { |patterns| gem.files & Dir[*patterns] }
|
26
|
+
|
27
|
+
gem.files = `git ls-files`.split($/)
|
28
|
+
gem.files = glob[gemspec['files']] if gemspec['files']
|
29
|
+
|
30
|
+
gem.executables = gemspec.fetch('executables') do
|
31
|
+
glob['bin/*'].map { |path| File.basename(path) }
|
32
|
+
end
|
33
|
+
gem.default_executable = gem.executables.first if Gem::VERSION < '1.7.'
|
34
|
+
|
35
|
+
gem.extensions = glob[gemspec['extensions'] || 'ext/**/extconf.rb']
|
36
|
+
gem.test_files = glob[gemspec['test_files'] || '{test/{**/}*_test.rb']
|
37
|
+
gem.extra_rdoc_files = glob[gemspec['extra_doc_files'] || '*.{txt,md}']
|
38
|
+
|
39
|
+
gem.require_paths = Array(gemspec.fetch('require_paths') {
|
40
|
+
%w[ext lib].select { |dir| File.directory?(dir) }
|
41
|
+
})
|
42
|
+
|
43
|
+
gem.requirements = Array(gemspec['requirements'])
|
44
|
+
gem.required_ruby_version = gemspec['required_ruby_version']
|
45
|
+
gem.required_rubygems_version = gemspec['required_rubygems_version']
|
46
|
+
gem.post_install_message = gemspec['post_install_message']
|
47
|
+
|
48
|
+
split = lambda { |string| string.split(/,\s*/) }
|
49
|
+
|
50
|
+
if gemspec['dependencies']
|
51
|
+
gemspec['dependencies'].each do |name,versions|
|
52
|
+
gem.add_dependency(name,split[versions])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if gemspec['development_dependencies']
|
57
|
+
gemspec['development_dependencies'].each do |name,versions|
|
58
|
+
gem.add_development_dependency(name,split[versions])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
Binary file
|
@@ -0,0 +1,17 @@
|
|
1
|
+
[
|
2
|
+
{ "ip": "93.184.216.34", "timestamp": "1629960621", "ports": [ {"port": 80, "proto": "tcp", "status": "open", "reason": "syn-ack", "ttl": 54} ] }
|
3
|
+
,
|
4
|
+
{ "ip": "93.184.216.34", "timestamp": "1629960621", "ports": [ {"port": 443, "proto": "tcp", "status": "open", "reason": "syn-ack", "ttl": 54} ] }
|
5
|
+
,
|
6
|
+
{ "ip": "93.184.216.34", "timestamp": "1629960622", "ports": [ {"port": 0, "proto": "icmp", "status": "open", "reason": "none", "ttl": 54} ] }
|
7
|
+
,
|
8
|
+
{ "ip": "93.184.216.34", "timestamp": "1629960624", "ports": [ {"port": 80, "proto": "tcp", "service": {"name": "http.server", "banner": "ECS (sec/974D)"} } ] }
|
9
|
+
,
|
10
|
+
{ "ip": "93.184.216.34", "timestamp": "1629960624", "ports": [ {"port": 80, "proto": "tcp", "service": {"name": "title", "banner": "404 - Not Found"} } ] }
|
11
|
+
,
|
12
|
+
{ "ip": "93.184.216.34", "timestamp": "1629960624", "ports": [ {"port": 80, "proto": "tcp", "service": {"name": "http", "banner": "HTTP/1.0 404 Not Found\u000d\u000aContent-Type: text/html\u000d\u000aDate: Thu, 26 Aug 2021 06:50:24 GMT\u000d\u000aServer: ECS (sec/974D)\u000d\u000aContent-Length: 345\u000d\u000aConnection: close\u000d\u000a\u000d"} } ] }
|
13
|
+
,
|
14
|
+
{ "ip": "93.184.216.34", "timestamp": "1629960633", "ports": [ {"port": 443, "proto": "tcp", "service": {"name": "ssl", "banner": "TLS/1.1 cipher:0xc013, www.example.org, www.example.org, example.com, example.edu, example.net, example.org, www.example.com, www.example.edu, www.example.net"} } ] }
|
15
|
+
,
|
16
|
+
{ "ip": "93.184.216.34", "timestamp": "1629960633", "ports": [ {"port": 443, "proto": "tcp", "service": {"name": "X509", "banner": "MIIG1TCCBb2gAwIBAgIQD74IsIVNBXOKsMzhya/uyTANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSkwJwYDVQQDEyBEaWdpQ2VydCBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTAeFw0yMDExMjQwMDAwMDBaFw0yMTEyMjUyMzU5NTlaMIGQMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLTG9zIEFuZ2VsZXMxPDA6BgNVBAoTM0ludGVybmV0IENvcnBvcmF0aW9uIGZvciBBc3NpZ25lZCBOYW1lcyBhbmQgTnVtYmVyczEYMBYGA1UEAxMPd3d3LmV4YW1wbGUub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuvzuzMoKCP8Okx2zvgucA5YinrFPEK5RQP1TX7PEYUAoBO6i5hIAsIKFmFxtW2sghERilU5rdnxQcF3fEx3sY4OtY6VSBPLPhLrbKozHLrQ8ZN/rYTb+hgNUeT7NA1mP78IEkxAj4qG5tli4Jq41aCbUlCt7equGXokImhC+UY5IpQEZS0tKD4vu2ksZ04Qetp0k8jWdAvMA27W3EwgHHNeVGWbJPC0Dn7RqPw13r7hFyS5TpleywjdY1nB7ad6kcZXZbEcaFZ7ZuerA6RkPGE+PsnZRb1oFJkYoXimsuvkVFhWeHQXCGC1cuDWSrM3cpQvOzKH2vS7d15+zGls4IwIDAQABo4IDaTCCA2UwHwYDVR0jBBgwFoAUt2ui6qiqhIx56rTaD5iyxZV2ufQwHQYDVR0OBBYEFCYa+OSxsHKEztqBBtInmPvtOj0XMIGBBgNVHREEejB4gg93d3cuZXhhbXBsZS5vcmeCC2V4YW1wbGUuY29tggtleGFtcGxlLmVkdYILZXhhbXBsZS5uZXSCC2V4YW1wbGUub3Jngg93d3cuZXhhbXBsZS5jb22CD3d3dy5leGFtcGxlLmVkdYIPd3d3LmV4YW1wbGUubmV0MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwgYsGA1UdHwSBgzCBgDA+oDygOoY4aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VExTUlNBU0hBMjU2MjAyMENBMS5jcmwwPqA8oDqGOGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNv"} } ] }
|
17
|
+
]
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#masscan
|
2
|
+
open tcp 443 93.184.216.34 1629960470
|
3
|
+
open tcp 80 93.184.216.34 1629960470
|
4
|
+
open icmp 0 93.184.216.34 1629960470
|
5
|
+
banner tcp 443 93.184.216.34 1629960472 ssl TLS/1.1 cipher:0xc013, www.example.org, www.example.org, example.com, example.edu, example.net, example.org, www.example.com, www.example.edu, www.example.net
|
6
|
+
banner tcp 443 93.184.216.34 1629960472 X509 MIIG1TCCBb2gAwIBAgIQD74IsIVNBXOKsMzhya/uyTANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSkwJwYDVQQDEyBEaWdpQ2VydCBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTAeFw0yMDExMjQwMDAwMDBaFw0yMTEyMjUyMzU5NTlaMIGQMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLTG9zIEFuZ2VsZXMxPDA6BgNVBAoTM0ludGVybmV0IENvcnBvcmF0aW9uIGZvciBBc3NpZ25lZCBOYW1lcyBhbmQgTnVtYmVyczEYMBYGA1UEAxMPd3d3LmV4YW1wbGUub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuvzuzMoKCP8Okx2zvgucA5YinrFPEK5RQP1TX7PEYUAoBO6i5hIAsIKFmFxtW2sghERilU5rdnxQcF3fEx3sY4OtY6VSBPLPhLrbKozHLrQ8ZN/rYTb+hgNUeT7NA1mP78IEkxAj4qG5tli4Jq41aCbUlCt7equGXokImhC+UY5IpQEZS0tKD4vu2ksZ04Qetp0k8jWdAvMA27W3EwgHHNeVGWbJPC0Dn7RqPw13r7hFyS5TpleywjdY1nB7ad6kcZXZbEcaFZ7ZuerA6RkPGE+PsnZRb1oFJkYoXimsuvkVFhWeHQXCGC1cuDWSrM3cpQvOzKH2vS7d15+zGls4IwIDAQABo4IDaTCCA2UwHwYDVR0jBBgwFoAUt2ui6qiqhIx56rTaD5iyxZV2ufQwHQYDVR0OBBYEFCYa+OSxsHKEztqBBtInmPvtOj0XMIGBBgNVHREEejB4gg93d3cuZXhhbXBsZS5vcmeCC2V4YW1wbGUuY29tggtleGFtcGxlLmVkdYILZXhhbXBsZS5uZXSCC2V4YW1wbGUub3Jngg93d3cuZXhhbXBsZS5jb22CD3d3dy5leGFtcGxlLmVkdYIPd3d3LmV4YW1wbGUubmV0MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwgYsGA1UdHwSBgzCBgDA+oDygOoY4aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VExTUlNBU0hBMjU2MjAyMENBMS5jcmwwPqA8oDqGOGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNv
|
7
|
+
banner tcp 80 93.184.216.34 1629960472 http.server ECS (sec/974D)
|
8
|
+
banner tcp 80 93.184.216.34 1629960472 title 404 - Not Found
|
9
|
+
banner tcp 80 93.184.216.34 1629960472 http HTTP/1.0 404 Not Found\x0d\x0aContent-Type: text/html\x0d\x0aDate: Thu, 26 Aug 2021 06:47:52 GMT\x0d\x0aServer: ECS (sec/974D)\x0d\x0aContent-Length: 345\x0d\x0aConnection: close\x0d\x0a\x0d
|
10
|
+
# end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
{"ip":"93.184.216.34","timestamp":"1630156508","port":80,"proto":"tcp","rec_type":"status","data":{"status":"open","reason":"syn-ack","ttl":54}}
|
2
|
+
{"ip":"93.184.216.34","timestamp":"1630156508","port":0,"proto":"icmp","rec_type":"status","data":{"status":"open","reason":"none","ttl":54}}
|
3
|
+
{"ip":"93.184.216.34","timestamp":"1630156508","port":443,"proto":"tcp","rec_type":"status","data":{"status":"open","reason":"syn-ack","ttl":54}}
|
4
|
+
{"ip":"93.184.216.34","timestamp":"1630156512","port":443,"proto":"tcp","rec_type":"banner","data":{"service_name":"ssl","banner":"TLS/1.1 cipher:0xc013, www.example.org, www.example.org, example.com, example.edu, example.net, example.org, www.example.com, www.example.edu, www.example.net"}}
|
5
|
+
{"ip":"93.184.216.34","timestamp":"1630156512","port":443,"proto":"tcp","rec_type":"banner","data":{"service_name":"X509","banner":"MIIG1TCCBb2gAwIBAgIQD74IsIVNBXOKsMzhya/uyTANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSkwJwYDVQQDEyBEaWdpQ2VydCBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTAeFw0yMDExMjQwMDAwMDBaFw0yMTEyMjUyMzU5NTlaMIGQMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLTG9zIEFuZ2VsZXMxPDA6BgNVBAoTM0ludGVybmV0IENvcnBvcmF0aW9uIGZvciBBc3NpZ25lZCBOYW1lcyBhbmQgTnVtYmVyczEYMBYGA1UEAxMPd3d3LmV4YW1wbGUub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuvzuzMoKCP8Okx2zvgucA5YinrFPEK5RQP1TX7PEYUAoBO6i5hIAsIKFmFxtW2sghERilU5rdnxQcF3fEx3sY4OtY6VSBPLPhLrbKozHLrQ8ZN/rYTb+hgNUeT7NA1mP78IEkxAj4qG5tli4Jq41aCbUlCt7equGXokImhC+UY5IpQEZS0tKD4vu2ksZ04Qetp0k8jWdAvMA27W3EwgHHNeVGWbJPC0Dn7RqPw13r7hFyS5TpleywjdY1nB7ad6kcZXZbEcaFZ7ZuerA6RkPGE+PsnZRb1oFJkYoXimsuvkVFhWeHQXCGC1cuDWSrM3cpQvOzKH2vS7d15+zGls4IwIDAQABo4IDaTCCA2UwHwYDVR0jBBgwFoAUt2ui6qiqhIx56rTaD5iyxZV2ufQwHQYDVR0OBBYEFCYa+OSxsHKEztqBBtInmPvtOj0XMIGBBgNVHREEejB4gg93d3cuZXhhbXBsZS5vcmeCC2V4YW1wbGUuY29tggtleGFtcGxlLmVkdYILZXhhbXBsZS5uZXSCC2V4YW1wbGUub3Jngg93d3cuZXhhbXBsZS5jb22CD3d3dy5leGFtcGxlLmVkdYIPd3d3LmV4YW1wbGUubmV0MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwgYsGA1UdHwSBgzCBgDA+oDygOoY4aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VExTUlNBU0hBMjU2MjAyMENBMS5jcmwwPqA8oDqGOGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNv"}}
|
6
|
+
{"ip":"93.184.216.34","timestamp":"1630156512","port":80,"proto":"tcp","rec_type":"banner","data":{"service_name":"http.server","banner":"ECS (sec/96ED)"}}
|
7
|
+
{"ip":"93.184.216.34","timestamp":"1630156512","port":80,"proto":"tcp","rec_type":"banner","data":{"service_name":"title","banner":"404 - Not Found"}}
|
8
|
+
{"ip":"93.184.216.34","timestamp":"1630156512","port":80,"proto":"tcp","rec_type":"banner","data":{"service_name":"http","banner":"HTTP/1.0 404 Not Found\u000d\u000aContent-Type: text/html\u000d\u000aDate: Sat, 28 Aug 2021 13:15:12 GMT\u000d\u000aServer: ECS (sec/96ED)\u000d\u000aContent-Length: 345\u000d\u000aConnection: close\u000d\u000a\u000d"}}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<!-- masscan v1.0 scan -->
|
3
|
+
<nmaprun scanner="masscan" start="1629960654" version="1.0-BETA" xmloutputversion="1.03">
|
4
|
+
<scaninfo type="syn" protocol="tcp" />
|
5
|
+
<host endtime="1629960654"><address addr="93.184.216.34" addrtype="ipv4"/><ports><port protocol="icmp" portid="0"><state state="open" reason="none" reason_ttl="54"/></port></ports></host>
|
6
|
+
<host endtime="1629960654"><address addr="93.184.216.34" addrtype="ipv4"/><ports><port protocol="tcp" portid="443"><state state="open" reason="syn-ack" reason_ttl="54"/></port></ports></host>
|
7
|
+
<host endtime="1629960654"><address addr="93.184.216.34" addrtype="ipv4"/><ports><port protocol="tcp" portid="80"><state state="open" reason="syn-ack" reason_ttl="54"/></port></ports></host>
|
8
|
+
<host endtime="1629960657"><address addr="93.184.216.34" addrtype="ipv4"/><ports><port protocol="tcp" portid="80"><state state="open" reason="response" reason_ttl="54" /><service name="http.server" banner="ECS (sec/973B)"></service></port></ports></host>
|
9
|
+
<host endtime="1629960657"><address addr="93.184.216.34" addrtype="ipv4"/><ports><port protocol="tcp" portid="80"><state state="open" reason="response" reason_ttl="54" /><service name="title" banner="404 - Not Found"></service></port></ports></host>
|
10
|
+
<host endtime="1629960657"><address addr="93.184.216.34" addrtype="ipv4"/><ports><port protocol="tcp" portid="80"><state state="open" reason="response" reason_ttl="54" /><service name="http" banner="HTTP/1.0 404 Not Found\x0d\x0aContent-Type: text/html\x0d\x0aDate: Thu, 26 Aug 2021 06:50:57 GMT\x0d\x0aServer: ECS (sec/973B)\x0d\x0aContent-Length: 345\x0d\x0aConnection: close\x0d\x0a\x0d"></service></port></ports></host>
|
11
|
+
<host endtime="1629960657"><address addr="93.184.216.34" addrtype="ipv4"/><ports><port protocol="tcp" portid="443"><state state="open" reason="response" reason_ttl="54" /><service name="ssl" banner="TLS/1.1 cipher:0xc013, www.example.org, www.example.org, example.com, example.edu, example.net, example.org, www.example.com, www.example.edu, www.example.net"></service></port></ports></host>
|
12
|
+
<host endtime="1629960657"><address addr="93.184.216.34" addrtype="ipv4"/><ports><port protocol="tcp" portid="443"><state state="open" reason="response" reason_ttl="54" /><service name="X509" banner="MIIG1TCCBb2gAwIBAgIQD74IsIVNBXOKsMzhya/uyTANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSkwJwYDVQQDEyBEaWdpQ2VydCBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTAeFw0yMDExMjQwMDAwMDBaFw0yMTEyMjUyMzU5NTlaMIGQMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLTG9zIEFuZ2VsZXMxPDA6BgNVBAoTM0ludGVybmV0IENvcnBvcmF0aW9uIGZvciBBc3NpZ25lZCBOYW1lcyBhbmQgTnVtYmVyczEYMBYGA1UEAxMPd3d3LmV4YW1wbGUub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuvzuzMoKCP8Okx2zvgucA5YinrFPEK5RQP1TX7PEYUAoBO6i5hIAsIKFmFxtW2sghERilU5rdnxQcF3fEx3sY4OtY6VSBPLPhLrbKozHLrQ8ZN/rYTb+hgNUeT7NA1mP78IEkxAj4qG5tli4Jq41aCbUlCt7equGXokImhC+UY5IpQEZS0tKD4vu2ksZ04Qetp0k8jWdAvMA27W3EwgHHNeVGWbJPC0Dn7RqPw13r7hFyS5TpleywjdY1nB7ad6kcZXZbEcaFZ7ZuerA6RkPGE+PsnZRb1oFJkYoXimsuvkVFhWeHQXCGC1cuDWSrM3cpQvOzKH2vS7d15+zGls4IwIDAQABo4IDaTCCA2UwHwYDVR0jBBgwFoAUt2ui6qiqhIx56rTaD5iyxZV2ufQwHQYDVR0OBBYEFCYa+OSxsHKEztqBBtInmPvtOj0XMIGBBgNVHREEejB4gg93d3cuZXhhbXBsZS5vcmeCC2V4YW1wbGUuY29tggtleGFtcGxlLmVkdYILZXhhbXBsZS5uZXSCC2V4YW1wbGUub3Jngg93d3cuZXhhbXBsZS5jb22CD3d3dy5leGFtcGxlLmVkdYIPd3d3LmV4YW1wbGUubmV0MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwgYsGA1UdHwSBgzCBgDA+oDygOoY4aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VExTUlNBU0hBMjU2MjAyMENBMS5jcmwwPqA8oDqGOGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNv"></service></port></ports></host>
|
13
|
+
<runstats>
|
14
|
+
<finished time="1629960666" timestr="2021-08-25 23:51:06" elapsed="12" />
|
15
|
+
<hosts up="2" down="0" total="2" />
|
16
|
+
</runstats>
|
17
|
+
</nmaprun>
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'masscan/output_file'
|
3
|
+
|
4
|
+
describe Masscan::OutputFile do
|
5
|
+
describe ".infer_format" do
|
6
|
+
subject { described_class.infer_format(path) }
|
7
|
+
|
8
|
+
context "when the path ends in .json" do
|
9
|
+
let(:path) { '/path/to/file.json' }
|
10
|
+
|
11
|
+
it { expect(subject).to eq(:json) }
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when the path ends in .ndjson" do
|
15
|
+
let(:path) { '/path/to/file.ndjson' }
|
16
|
+
|
17
|
+
it { expect(subject).to eq(:ndjson) }
|
18
|
+
end
|
19
|
+
|
20
|
+
context "when the path ends in .list" do
|
21
|
+
let(:path) { '/path/to/file.list' }
|
22
|
+
|
23
|
+
it { expect(subject).to eq(:list) }
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when the path ends in .txt" do
|
27
|
+
let(:path) { '/path/to/file.txt' }
|
28
|
+
|
29
|
+
it { expect(subject).to eq(:list) }
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when the path ends in .bin" do
|
33
|
+
let(:path) { '/path/to/file.bin' }
|
34
|
+
|
35
|
+
it { expect(subject).to eq(:binary) }
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when the path ends in .dat" do
|
39
|
+
let(:path) { '/path/to/file.dat' }
|
40
|
+
|
41
|
+
it { expect(subject).to eq(:binary) }
|
42
|
+
end
|
43
|
+
|
44
|
+
context "when the path ends in .xml" do
|
45
|
+
let(:path) { '/path/to/file.xml' }
|
46
|
+
|
47
|
+
it { expect(subject).to eq(:xml) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "PARSERS" do
|
52
|
+
subject { described_class::PARSERS }
|
53
|
+
|
54
|
+
describe ":binary" do
|
55
|
+
it { expect(subject[:binary]).to eq(Masscan::Parsers::Binary) }
|
56
|
+
end
|
57
|
+
|
58
|
+
describe ":list" do
|
59
|
+
it { expect(subject[:list]).to eq(Masscan::Parsers::List) }
|
60
|
+
end
|
61
|
+
|
62
|
+
describe ":json" do
|
63
|
+
it { expect(subject[:json]).to eq(Masscan::Parsers::JSON) }
|
64
|
+
end
|
65
|
+
|
66
|
+
describe ":ndjson" do
|
67
|
+
it { expect(subject[:ndjson]).to eq(Masscan::Parsers::JSON) }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#initialize" do
|
72
|
+
let(:path) { "/path/to/file.json" }
|
73
|
+
|
74
|
+
subject { described_class.new(path) }
|
75
|
+
|
76
|
+
it "must set #path" do
|
77
|
+
expect(subject.path).to eq(path)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "must infer the format from the file's extname" do
|
81
|
+
expect(subject.format).to eq(:json)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "must set #parser based on #format" do
|
85
|
+
expect(subject.parser).to eq(described_class::PARSERS[subject.format])
|
86
|
+
end
|
87
|
+
|
88
|
+
context "when given an format: keyword" do
|
89
|
+
let(:format) { :list }
|
90
|
+
|
91
|
+
subject { described_class.new(path, format: format) }
|
92
|
+
|
93
|
+
it "must set #format" do
|
94
|
+
expect(subject.format).to be(format)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "must set #parser based on the given format:" do
|
98
|
+
expect(subject.parser).to eq(described_class::PARSERS[format])
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
subject { described_class.new(Fixtures.join('masscan.list')) }
|
104
|
+
|
105
|
+
describe "#each" do
|
106
|
+
context "when given a block" do
|
107
|
+
it "must yield Masscan::Status and Masscan::Banner objects" do
|
108
|
+
yielded_record_classes = []
|
109
|
+
|
110
|
+
subject.each do |record|
|
111
|
+
yielded_record_classes << record.class
|
112
|
+
end
|
113
|
+
|
114
|
+
expect(yielded_record_classes.uniq).to eq([
|
115
|
+
Masscan::Status,
|
116
|
+
Masscan::Banner
|
117
|
+
])
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "when given no block" do
|
122
|
+
let(:expected_records) do
|
123
|
+
[].tap do |yielded_records|
|
124
|
+
subject.each do |record|
|
125
|
+
yielded_records << record
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
it "must return an Enumerator" do
|
131
|
+
expect(subject.each.to_a).to eq(expected_records)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|