dap 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +55 -0
- data/LICENSE +20 -0
- data/README.md +15 -0
- data/bin/dap +137 -0
- data/dap.gemspec +42 -0
- data/data/.gitkeep +0 -0
- data/lib/dap.rb +101 -0
- data/lib/dap/filter.rb +8 -0
- data/lib/dap/filter/base.rb +37 -0
- data/lib/dap/filter/geoip.rb +72 -0
- data/lib/dap/filter/http.rb +173 -0
- data/lib/dap/filter/names.rb +151 -0
- data/lib/dap/filter/openssl.rb +53 -0
- data/lib/dap/filter/recog.rb +23 -0
- data/lib/dap/filter/simple.rb +340 -0
- data/lib/dap/filter/udp.rb +401 -0
- data/lib/dap/input.rb +74 -0
- data/lib/dap/input/csv.rb +60 -0
- data/lib/dap/input/warc.rb +81 -0
- data/lib/dap/output.rb +117 -0
- data/lib/dap/proto/addp.rb +0 -0
- data/lib/dap/proto/dtls.rb +21 -0
- data/lib/dap/proto/ipmi.rb +94 -0
- data/lib/dap/proto/natpmp.rb +19 -0
- data/lib/dap/proto/wdbrpc.rb +58 -0
- data/lib/dap/utils/oui.rb +16586 -0
- data/lib/dap/version.rb +3 -0
- data/samples/http_get_reply.ic12.bz2 +0 -0
- data/samples/http_get_reply.ic12.sh +1 -0
- data/samples/http_get_reply_iframes.json.bz2 +0 -0
- data/samples/http_get_reply_iframes.json.sh +1 -0
- data/samples/http_get_reply_links.json.sh +1 -0
- data/samples/iawide.warc.bz2 +0 -0
- data/samples/iawide_warc.sh +1 -0
- data/samples/ipmi_chan_auth_replies.crd.bz2 +0 -0
- data/samples/ipmi_chan_auth_replies.sh +1 -0
- data/samples/ssl_certs.bz2 +0 -0
- data/samples/ssl_certs_geo.sh +1 -0
- data/samples/ssl_certs_names.sh +1 -0
- data/samples/ssl_certs_names_expanded.sh +1 -0
- data/samples/ssl_certs_org.sh +1 -0
- data/samples/udp-netbios.csv.bz2 +0 -0
- data/samples/udp-netbios.sh +1 -0
- data/spec/dap/proto/ipmi_spec.rb +19 -0
- data/tools/geo-ip-summary.rb +149 -0
- data/tools/ipmi-vulns.rb +27 -0
- data/tools/json-summarize.rb +81 -0
- data/tools/netbios-counts.rb +271 -0
- data/tools/upnp-vulns.rb +35 -0
- data/tools/value-counts-to-md-table.rb +23 -0
- metadata +264 -0
data/lib/dap/input.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
module Dap
|
2
|
+
module Input
|
3
|
+
|
4
|
+
require 'oj'
|
5
|
+
|
6
|
+
#
|
7
|
+
# Error codes for failed reads
|
8
|
+
#
|
9
|
+
module Error
|
10
|
+
EOF = :eof
|
11
|
+
Empty = :empty
|
12
|
+
end
|
13
|
+
|
14
|
+
module FileSource
|
15
|
+
|
16
|
+
attr_accessor :fd
|
17
|
+
|
18
|
+
def open(file_name)
|
19
|
+
close
|
20
|
+
self.fd = ['-', 'stdin', nil].include?(file_name) ?
|
21
|
+
$stdin : ::File.open(file_name, "rb")
|
22
|
+
end
|
23
|
+
|
24
|
+
def close
|
25
|
+
self.close if self.fd
|
26
|
+
self.fd = nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Line Input
|
32
|
+
#
|
33
|
+
class InputLines
|
34
|
+
|
35
|
+
include FileSource
|
36
|
+
|
37
|
+
def initialize(args)
|
38
|
+
self.open(args.first)
|
39
|
+
end
|
40
|
+
|
41
|
+
def read_record
|
42
|
+
line = self.fd.readline rescue nil
|
43
|
+
return Error::EOF unless line
|
44
|
+
{ 'line' => line.chomp("\n") }
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# JSON Input (line-delimited records)
|
51
|
+
#
|
52
|
+
class InputJSON
|
53
|
+
|
54
|
+
include FileSource
|
55
|
+
|
56
|
+
def initialize(args)
|
57
|
+
self.open(args.first)
|
58
|
+
end
|
59
|
+
|
60
|
+
def read_record
|
61
|
+
line = self.fd.readline rescue nil
|
62
|
+
return Error::EOF unless line
|
63
|
+
json = Oj.load(line.strip) rescue nil
|
64
|
+
return Error::Empty unless json
|
65
|
+
json
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
require 'dap/input/warc'
|
74
|
+
require 'dap/input/csv'
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Dap
|
2
|
+
module Input
|
3
|
+
|
4
|
+
require 'csv'
|
5
|
+
|
6
|
+
#
|
7
|
+
# CSV
|
8
|
+
#
|
9
|
+
class InputCSV
|
10
|
+
|
11
|
+
include FileSource
|
12
|
+
|
13
|
+
attr_accessor :has_header, :headers
|
14
|
+
|
15
|
+
def initialize(args)
|
16
|
+
self.headers = []
|
17
|
+
|
18
|
+
fname = args.shift
|
19
|
+
self.open(fname)
|
20
|
+
|
21
|
+
args.each do |arg|
|
22
|
+
if arg =~ /^header=(.*)/
|
23
|
+
val =$1
|
24
|
+
self.has_header = !! (val =~ /^y|t|1/i)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
if self.has_header
|
29
|
+
data = read_record
|
30
|
+
unless (data == :eof or data == :empty)
|
31
|
+
self.headers = data.values.map{|x| x.to_s.strip }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def read_record
|
37
|
+
res = {}
|
38
|
+
line = self.fd.readline rescue nil
|
39
|
+
return Error::EOF unless line
|
40
|
+
|
41
|
+
# Short-circuit the slow CSV parser if the data does not contain double quotes
|
42
|
+
arr = line.index('"') ?
|
43
|
+
( CSV.parse(line) rescue nil ) :
|
44
|
+
[ line.split(',').map{|x| x.strip } ]
|
45
|
+
|
46
|
+
return Error::Empty unless arr
|
47
|
+
cnt = 0
|
48
|
+
arr.first.each do |x|
|
49
|
+
cnt += 1
|
50
|
+
if x.to_s.length > 0
|
51
|
+
res[headers[cnt-1] || cnt.to_s] = x
|
52
|
+
end
|
53
|
+
end
|
54
|
+
res
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Dap
|
2
|
+
module Input
|
3
|
+
|
4
|
+
#
|
5
|
+
# WARC
|
6
|
+
#
|
7
|
+
class InputWARC
|
8
|
+
|
9
|
+
include FileSource
|
10
|
+
|
11
|
+
attr_accessor :header, :info
|
12
|
+
|
13
|
+
def initialize(args)
|
14
|
+
self.open(args.first)
|
15
|
+
read_warc_header
|
16
|
+
end
|
17
|
+
|
18
|
+
def read_warc_header
|
19
|
+
self.header = read_record
|
20
|
+
|
21
|
+
if self.header == Error::EOF
|
22
|
+
raise RuntimeError, "Invalid WARC header"
|
23
|
+
end
|
24
|
+
|
25
|
+
unless self.header['warc_type'].to_s == "warcinfo"
|
26
|
+
raise RuntimeError, "Invalid WARC header (missing warcinfo)"
|
27
|
+
end
|
28
|
+
|
29
|
+
self.info = {}
|
30
|
+
self.header['content'].to_s.split("\n").each do |line|
|
31
|
+
k, v = line.strip.split(/\s*:\s*/, 2)
|
32
|
+
next unless v
|
33
|
+
self.info[k] = v
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def read_record
|
38
|
+
begin
|
39
|
+
|
40
|
+
version = self.fd.readline
|
41
|
+
unless version and version =~ /^WARC\/\d+\.\d+/
|
42
|
+
return Error::EOF
|
43
|
+
end
|
44
|
+
warc = {}
|
45
|
+
|
46
|
+
loop do
|
47
|
+
line = self.fd.readline
|
48
|
+
|
49
|
+
unless line.strip.length == 0
|
50
|
+
k, v = line.strip.split(/\s*:\s*/, 2)
|
51
|
+
k = k.downcase.gsub('-', '_')
|
52
|
+
warc[k] = v.to_s
|
53
|
+
next
|
54
|
+
end
|
55
|
+
|
56
|
+
unless warc['content_length']
|
57
|
+
return Error::EOF
|
58
|
+
end
|
59
|
+
|
60
|
+
warc['content'] = self.fd.read(warc['content_length'].to_i)
|
61
|
+
skip = self.fd.readline
|
62
|
+
skip = self.fd.readline
|
63
|
+
|
64
|
+
unless skip.strip.length == 0
|
65
|
+
return Error::EOF
|
66
|
+
end
|
67
|
+
|
68
|
+
break
|
69
|
+
end
|
70
|
+
|
71
|
+
return warc
|
72
|
+
|
73
|
+
rescue ::EOFError
|
74
|
+
return Error::EOF
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
data/lib/dap/output.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
module Dap
|
2
|
+
module Output
|
3
|
+
|
4
|
+
require 'oj'
|
5
|
+
|
6
|
+
module FileDestination
|
7
|
+
|
8
|
+
attr_accessor :fd
|
9
|
+
|
10
|
+
def open(file_name)
|
11
|
+
close
|
12
|
+
self.fd = ['-', 'stdout', nil].include?(file_name) ?
|
13
|
+
$stdout : ::File.open(file_name, "wb")
|
14
|
+
end
|
15
|
+
|
16
|
+
def close
|
17
|
+
self.close if self.fd
|
18
|
+
self.fd = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
# Overload this to add headers
|
22
|
+
def start
|
23
|
+
end
|
24
|
+
|
25
|
+
# Overload this to add footers
|
26
|
+
def stop
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
#
|
33
|
+
# Line Output (CSV, TSV, etc)
|
34
|
+
# XXX: Quoted field handling is not supported, CSV should be a new output type
|
35
|
+
#
|
36
|
+
class OutputLines
|
37
|
+
|
38
|
+
attr_accessor :fields, :delimiter
|
39
|
+
FIELD_WILDCARD = '_'
|
40
|
+
|
41
|
+
include FileDestination
|
42
|
+
|
43
|
+
def initialize(args)
|
44
|
+
file = nil
|
45
|
+
self.delimiter = ","
|
46
|
+
self.fields = FIELD_WILDCARD
|
47
|
+
|
48
|
+
header = false
|
49
|
+
|
50
|
+
args.each do |str|
|
51
|
+
k,v = str.split('=', 2)
|
52
|
+
case k
|
53
|
+
when 'file'
|
54
|
+
file = v
|
55
|
+
when 'header'
|
56
|
+
header = ( v =~ /^[ty1]/i ? true : false )
|
57
|
+
when 'fields'
|
58
|
+
self.fields = v.split(',')
|
59
|
+
when 'delimiter'
|
60
|
+
self.delimiter =
|
61
|
+
case v.to_s
|
62
|
+
when 'tab'
|
63
|
+
"\t"
|
64
|
+
when 'null'
|
65
|
+
"\x00"
|
66
|
+
else
|
67
|
+
v
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
self.open(file)
|
72
|
+
|
73
|
+
if header and not fields.include?(FIELD_WILDCARD)
|
74
|
+
self.fd.puts self.fields.join(self.delimiter)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
def write_record(doc)
|
80
|
+
out = []
|
81
|
+
|
82
|
+
if self.fields.include?(FIELD_WILDCARD)
|
83
|
+
doc.each_pair do |k,v|
|
84
|
+
out << v.to_s
|
85
|
+
end
|
86
|
+
else
|
87
|
+
self.fields.each do |k|
|
88
|
+
out << doc[k].to_s
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
return unless out.length > 0
|
93
|
+
|
94
|
+
self.fd.puts out.join(self.delimiter)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
# JSON Output (line-delimited records)
|
101
|
+
#
|
102
|
+
class OutputJSON
|
103
|
+
|
104
|
+
include FileDestination
|
105
|
+
|
106
|
+
def initialize(args)
|
107
|
+
self.open(args.first)
|
108
|
+
end
|
109
|
+
|
110
|
+
def write_record(doc)
|
111
|
+
self.fd.puts Oj.dump(doc)
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
module Dap
|
3
|
+
module Proto
|
4
|
+
module DTLS
|
5
|
+
|
6
|
+
|
7
|
+
class RecordLayer < BitStruct
|
8
|
+
unsigned :content_type, 8, 'Content type'
|
9
|
+
unsigned :version, 16, 'Version'
|
10
|
+
unsigned :epoch, 16, 'Epoch'
|
11
|
+
unsigned :sequence, 48, 'Sequence number'
|
12
|
+
unsigned :payload_length, 16, 'Payload length'
|
13
|
+
rest :payload
|
14
|
+
|
15
|
+
def valid?
|
16
|
+
payload_length == payload.length
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
module Dap
|
3
|
+
module Proto
|
4
|
+
module IPMI
|
5
|
+
|
6
|
+
class Channel_Auth_Reply < BitStruct
|
7
|
+
|
8
|
+
unsigned :rmcp_version, 8, "RMCP Version"
|
9
|
+
unsigned :rmcp_padding, 8, "RMCP Padding"
|
10
|
+
unsigned :rmcp_sequence, 8, "RMCP Sequence"
|
11
|
+
unsigned :rmcp_mtype, 1, "RMCP Message Type"
|
12
|
+
unsigned :rmcp_class, 7, "RMCP Message Class"
|
13
|
+
|
14
|
+
unsigned :session_auth_type, 8, "Session Auth Type"
|
15
|
+
unsigned :session_sequence, 32, "Session Sequence Number"
|
16
|
+
unsigned :session_id, 32, "Session ID"
|
17
|
+
unsigned :message_length, 8, "Message Length"
|
18
|
+
|
19
|
+
unsigned :ipmi_tgt_address, 8, "IPMI Target Address"
|
20
|
+
unsigned :ipmi_tgt_lun, 8, "IPMI Target LUN"
|
21
|
+
unsigned :ipmi_header_checksum, 8, "IPMI Header Checksum"
|
22
|
+
unsigned :ipmi_src_address, 8, "IPMI Source Address"
|
23
|
+
unsigned :ipmi_src_lun, 8, "IPMI Source LUN"
|
24
|
+
unsigned :ipmi_command, 8, "IPMI Command"
|
25
|
+
unsigned :ipmi_completion_code, 8, "IPMI Completion Code"
|
26
|
+
|
27
|
+
unsigned :ipmi_channel, 8, "IPMI Channel"
|
28
|
+
|
29
|
+
unsigned :ipmi_compat_20, 1, "IPMI Version Compatibility: IPMI 2.0+"
|
30
|
+
unsigned :ipmi_compat_reserved1, 1, "IPMI Version Compatibility: Reserved 1"
|
31
|
+
unsigned :ipmi_compat_oem_auth, 1, "IPMI Version Compatibility: OEM Authentication"
|
32
|
+
unsigned :ipmi_compat_password, 1, "IPMI Version Compatibility: Straight Password"
|
33
|
+
unsigned :ipmi_compat_reserved2, 1, "IPMI Version Compatibility: Reserved 2"
|
34
|
+
unsigned :ipmi_compat_md5, 1, "IPMI Version Compatibility: MD5"
|
35
|
+
unsigned :ipmi_compat_md2, 1, "IPMI Version Compatibility: MD2"
|
36
|
+
unsigned :ipmi_compat_none, 1, "IPMI Version Compatibility: None"
|
37
|
+
|
38
|
+
unsigned :ipmi_user_reserved1, 2, "IPMI User Compatibility: Reserved 1"
|
39
|
+
unsigned :ipmi_user_kg, 1, "IPMI User Compatibility: KG Set to Default"
|
40
|
+
unsigned :ipmi_user_disable_message_auth, 1, "IPMI User Compatibility: Disable Per-Message Authentication"
|
41
|
+
unsigned :ipmi_user_disable_user_auth, 1, "IPMI User Compatibility: Disable User-Level Authentication"
|
42
|
+
unsigned :ipmi_user_non_null, 1, "IPMI User Compatibility: Non-Null Usernames Enabled"
|
43
|
+
unsigned :ipmi_user_null, 1, "IPMI User Compatibility: Null Usernames Enabled"
|
44
|
+
unsigned :ipmi_user_anonymous, 1, "IPMI User Compatibility: Anonymous Login Enabled"
|
45
|
+
|
46
|
+
unsigned :ipmi_conn_reserved1, 6, "IPMI Connection Compatibility: Reserved 1"
|
47
|
+
unsigned :ipmi_conn_20, 1, "IPMI Connection Compatibility: 2.0"
|
48
|
+
unsigned :ipmi_conn_15, 1, "IPMI Connection Compatibility: 1.5"
|
49
|
+
|
50
|
+
unsigned :ipmi_oem_id, 24, "IPMI OEM ID", :endian => 'little'
|
51
|
+
|
52
|
+
rest :ipm_oem_data, "IPMI OEM Data + Checksum Byte"
|
53
|
+
|
54
|
+
|
55
|
+
def valid?
|
56
|
+
(rmcp_version == 6) && (message_length == 16)
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_banner
|
60
|
+
info = self
|
61
|
+
banner = "#{(info.ipmi_compat_20 == 1) ? "IPMI-2.0" : "IPMI-1.5"} "
|
62
|
+
|
63
|
+
pass_info = []
|
64
|
+
pass_info << "oem_auth" if info.ipmi_compat_oem_auth == 1
|
65
|
+
pass_info << "password" if info.ipmi_compat_password == 1
|
66
|
+
pass_info << "md5" if info.ipmi_compat_md5 == 1
|
67
|
+
pass_info << "md2" if info.ipmi_compat_md2 == 1
|
68
|
+
pass_info << "null" if info.ipmi_compat_none == 1
|
69
|
+
|
70
|
+
user_info = []
|
71
|
+
user_info << "kg_default" if (info.ipmi_compat_20 == 1 and info.ipmi_user_kg == 1)
|
72
|
+
user_info << "auth_msg" unless info.ipmi_user_disable_message_auth == 1
|
73
|
+
user_info << "auth_user" unless info.ipmi_user_disable_user_auth == 1
|
74
|
+
user_info << "non_null_user" if info.ipmi_user_non_null == 1
|
75
|
+
user_info << "null_user" if info.ipmi_user_null == 1
|
76
|
+
user_info << "anonymous_user" if info.ipmi_user_anonymous == 1
|
77
|
+
|
78
|
+
conn_info = []
|
79
|
+
conn_info << "1.5" if info.ipmi_conn_15 == 1
|
80
|
+
conn_info << "2.0" if info.ipmi_conn_20 == 1
|
81
|
+
|
82
|
+
if info.ipmi_oem_id != 0
|
83
|
+
banner << "OEMID:#{info.ipmi_oem_id} "
|
84
|
+
end
|
85
|
+
|
86
|
+
banner << "UserAuth(#{user_info.join(", ")}) PassAuth(#{pass_info.join(", ")}) Level(#{conn_info.join(", ")}) "
|
87
|
+
banner
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|