dap 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/.gitignore +6 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +15 -0
  4. data/Gemfile.lock +55 -0
  5. data/LICENSE +20 -0
  6. data/README.md +15 -0
  7. data/bin/dap +137 -0
  8. data/dap.gemspec +42 -0
  9. data/data/.gitkeep +0 -0
  10. data/lib/dap.rb +101 -0
  11. data/lib/dap/filter.rb +8 -0
  12. data/lib/dap/filter/base.rb +37 -0
  13. data/lib/dap/filter/geoip.rb +72 -0
  14. data/lib/dap/filter/http.rb +173 -0
  15. data/lib/dap/filter/names.rb +151 -0
  16. data/lib/dap/filter/openssl.rb +53 -0
  17. data/lib/dap/filter/recog.rb +23 -0
  18. data/lib/dap/filter/simple.rb +340 -0
  19. data/lib/dap/filter/udp.rb +401 -0
  20. data/lib/dap/input.rb +74 -0
  21. data/lib/dap/input/csv.rb +60 -0
  22. data/lib/dap/input/warc.rb +81 -0
  23. data/lib/dap/output.rb +117 -0
  24. data/lib/dap/proto/addp.rb +0 -0
  25. data/lib/dap/proto/dtls.rb +21 -0
  26. data/lib/dap/proto/ipmi.rb +94 -0
  27. data/lib/dap/proto/natpmp.rb +19 -0
  28. data/lib/dap/proto/wdbrpc.rb +58 -0
  29. data/lib/dap/utils/oui.rb +16586 -0
  30. data/lib/dap/version.rb +3 -0
  31. data/samples/http_get_reply.ic12.bz2 +0 -0
  32. data/samples/http_get_reply.ic12.sh +1 -0
  33. data/samples/http_get_reply_iframes.json.bz2 +0 -0
  34. data/samples/http_get_reply_iframes.json.sh +1 -0
  35. data/samples/http_get_reply_links.json.sh +1 -0
  36. data/samples/iawide.warc.bz2 +0 -0
  37. data/samples/iawide_warc.sh +1 -0
  38. data/samples/ipmi_chan_auth_replies.crd.bz2 +0 -0
  39. data/samples/ipmi_chan_auth_replies.sh +1 -0
  40. data/samples/ssl_certs.bz2 +0 -0
  41. data/samples/ssl_certs_geo.sh +1 -0
  42. data/samples/ssl_certs_names.sh +1 -0
  43. data/samples/ssl_certs_names_expanded.sh +1 -0
  44. data/samples/ssl_certs_org.sh +1 -0
  45. data/samples/udp-netbios.csv.bz2 +0 -0
  46. data/samples/udp-netbios.sh +1 -0
  47. data/spec/dap/proto/ipmi_spec.rb +19 -0
  48. data/tools/geo-ip-summary.rb +149 -0
  49. data/tools/ipmi-vulns.rb +27 -0
  50. data/tools/json-summarize.rb +81 -0
  51. data/tools/netbios-counts.rb +271 -0
  52. data/tools/upnp-vulns.rb +35 -0
  53. data/tools/value-counts-to-md-table.rb +23 -0
  54. 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