ruby-stix2 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +7 -1
- data/README.md +49 -3
- data/lib/stix2/base.rb +7 -0
- data/lib/stix2/common.rb +80 -15
- data/lib/stix2/confidence_scale.rb +106 -0
- data/lib/stix2/custom_object.rb +20 -0
- data/lib/stix2/cyberobservable_objects/email_message.rb +1 -1
- data/lib/stix2/cyberobservable_objects/network_traffic.rb +1 -1
- data/lib/stix2/cyberobservable_objects/process.rb +17 -0
- data/lib/stix2/cyberobservable_objects/user_account.rb +4 -4
- data/lib/stix2/cyberobservable_objects/x509_certificate.rb +3 -1
- data/lib/stix2/domain_objects/malware.rb +1 -1
- data/lib/stix2/enum.rb +59 -0
- data/lib/stix2/extension_definition.rb +10 -0
- data/lib/stix2/extensions/alternate_data_stream_type.rb +9 -0
- data/lib/stix2/extensions/archive_file.rb +8 -0
- data/lib/stix2/extensions/http_request.rb +12 -0
- data/lib/stix2/extensions/icmp.rb +8 -0
- data/lib/stix2/extensions/ntfs.rb +10 -0
- data/lib/stix2/extensions/pdf.rb +11 -0
- data/lib/stix2/extensions/raster_image.rb +10 -0
- data/lib/stix2/extensions/socket.rb +13 -0
- data/lib/stix2/extensions/tcp.rb +8 -0
- data/lib/stix2/extensions/unix_account.rb +10 -0
- data/lib/stix2/extensions/windows_pe_optional_header_type.rb +37 -0
- data/lib/stix2/extensions/windows_pe_section_type.rb +10 -0
- data/lib/stix2/extensions/windows_pebinary.rb +21 -0
- data/lib/stix2/extensions/windows_process.rb +13 -0
- data/lib/stix2/extensions/windows_service.rb +14 -0
- data/lib/stix2/external_reference.rb +1 -5
- data/lib/stix2/identifier.rb +2 -12
- data/lib/stix2/kill_chain_phase.rb +3 -7
- data/lib/stix2/languages.rb +236 -0
- data/lib/stix2/meta_objects/data_markings/base.rb +1 -4
- data/lib/stix2/meta_objects/data_markings/granular_marking.rb +1 -5
- data/lib/stix2/meta_objects/data_markings/object_marking.rb +2 -12
- data/lib/stix2/meta_objects/language_content.rb +1 -1
- data/lib/stix2/ov.rb +6 -0
- data/lib/stix2/relationship_objects/sighting.rb +1 -1
- data/lib/stix2/storage.rb +21 -15
- data/lib/stix2/version.rb +1 -1
- data/lib/stix2.rb +35 -7
- data/ruby-stix2.gemspec +9 -5
- metadata +40 -6
- data/lib/stix2/boolean.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f69ada6e1bf635fb01ca7cfed49ed184447e14e8b85c2b5ff14e1640d1f18738
|
4
|
+
data.tar.gz: 56712374f185dc57787679dd8060eb32320cbff393fada2d5285a924bc48b3a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc04f1a76a4e79f2e57365201e1fdadaa4f29eecb1c61f2e4f7a4be4d9201b238ee36aac3f5c6bd094acc77ae2be8720b41d0e0a8a2b62a52279304c4fc8bb64
|
7
|
+
data.tar.gz: 852ae67a130e1a0338fd0d44af58746caab042d92b7b2bbd3c09c4edba2b0860eb0ff4a2c76a9346c802b8b7a47150e4bfae2b6039b31c082fed9f4da3b7e8ea
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ruby-stix2 (0.1.
|
4
|
+
ruby-stix2 (0.1.1)
|
5
5
|
hashie (~> 5.0.0)
|
6
6
|
|
7
7
|
GEM
|
@@ -11,6 +11,9 @@ GEM
|
|
11
11
|
coderay (1.1.3)
|
12
12
|
docile (1.4.0)
|
13
13
|
hashie (5.0.0)
|
14
|
+
io-console (0.6.0)
|
15
|
+
irb (1.7.0)
|
16
|
+
reline (>= 0.3.0)
|
14
17
|
method_source (1.0.0)
|
15
18
|
minitest (5.18.1)
|
16
19
|
pry (0.13.1)
|
@@ -20,6 +23,8 @@ GEM
|
|
20
23
|
byebug (~> 11.0)
|
21
24
|
pry (>= 0.13, < 0.15)
|
22
25
|
rake (13.0.6)
|
26
|
+
reline (0.3.5)
|
27
|
+
io-console (~> 0.5)
|
23
28
|
simplecov (0.22.0)
|
24
29
|
docile (~> 1.1)
|
25
30
|
simplecov-html (~> 0.11)
|
@@ -32,6 +37,7 @@ PLATFORMS
|
|
32
37
|
|
33
38
|
DEPENDENCIES
|
34
39
|
bundler (~> 2.3)
|
40
|
+
irb (~> 1.7.0)
|
35
41
|
minitest (~> 5.18.1)
|
36
42
|
pry (~> 0.13.0)
|
37
43
|
pry-byebug (~> 3.10.1)
|
data/README.md
CHANGED
@@ -12,7 +12,7 @@ gem install ruby-stix2
|
|
12
12
|
or as part of the bundle
|
13
13
|
|
14
14
|
```
|
15
|
-
bundle add
|
15
|
+
bundle add ruby-stix2
|
16
16
|
```
|
17
17
|
|
18
18
|
# Usage
|
@@ -69,7 +69,7 @@ Stix2 message.
|
|
69
69
|
# Storage
|
70
70
|
|
71
71
|
The Stix2 standard has several object types, some of which are containers of other objects (like `Bundle`). However we
|
72
|
-
may want to save and retrieve Stix2 objects in a fast way. The gem provides a `
|
72
|
+
may want to save and retrieve Stix2 objects in a fast way. The gem provides a `Stix::Storage` support for that.
|
73
73
|
|
74
74
|
For any Stix2 attribute that is an `identifier` (`Stix2::Identifier` in the gem) the class gives one more method called
|
75
75
|
`_instance` to retrieve the actual instance. If we have a `threat-actor` like this
|
@@ -98,7 +98,7 @@ we know that this object has been created by an identity `identity--f431f809-377
|
|
98
98
|
retrieve the other object if already seen
|
99
99
|
|
100
100
|
```ruby
|
101
|
-
Stix2.
|
101
|
+
Stix2::Storage.activate # Activate the storage
|
102
102
|
|
103
103
|
identity = Stix2::DomainObject::Identity.new(id: 'identity--f431f809-377b-45e0-aa1c-6a4751cae5ff', ...)
|
104
104
|
threat_actor = Stix2::DomainObject::ThreatActor.new(created_by_ref: 'identity--f431f809-377b-45e0-aa1c-6a4751cae5ff', ...)
|
@@ -107,6 +107,48 @@ threat_actor.created_by_ref # this gives the identifier => identity--f431f809-37
|
|
107
107
|
threat_actor.created_by_ref_instance # this gives the actual object => Stix2::DomainObject::Identity
|
108
108
|
```
|
109
109
|
|
110
|
+
# Spec versions
|
111
|
+
|
112
|
+
This gem implements the spec version `2.1`. However older version (especially 2.0) can be compatible. To force the gem
|
113
|
+
to accept another spec version, just add them to the `SPEC_VERSIONS` variable.
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
Stix2::SPEC_VERSIONS << '2.0'
|
117
|
+
```
|
118
|
+
|
119
|
+
# Custom Definitions
|
120
|
+
|
121
|
+
The Stix2 standard includes several extensions to base objects. All extensions are widely described in the standard
|
122
|
+
itself, please refer to it. However two of them need more attention for how they are implemented in this gem.
|
123
|
+
|
124
|
+
## Extension Definition
|
125
|
+
|
126
|
+
This object allows the definition of new properties. One special property is `toplevel-property-extension` that allows
|
127
|
+
the definition of properties on the top-level of an object. According to the standard thos properties should be
|
128
|
+
defined solely on the object that is actually using the property. However due to the `hashie`-based implementation
|
129
|
+
the gem declares the new properties on the class itself. This is a known limitation of the current implementation and
|
130
|
+
it may be fixed in the future.
|
131
|
+
|
132
|
+
## Custom Object
|
133
|
+
|
134
|
+
A `CustomObject` can also be used within the Gem. The standard defines the rules that must be fulfilled for a custom
|
135
|
+
object. Since those rules are several, the code stacks all the errors altogether and raises an exception when some
|
136
|
+
errors happen. The exception is RuntimeError, that gives the user a string. It is suboptimal to have multiple errors
|
137
|
+
in a string, and it may be fixed in the future.
|
138
|
+
|
139
|
+
# Confidence
|
140
|
+
|
141
|
+
A Stix2 object can have the property `confidence` set. This value can be expressed according to several conficence
|
142
|
+
scales. To make this conversion smooth, an object offers the method `confidence_scale` that is an instance of
|
143
|
+
`Stix2::ConfidenceScale`. This class offers method for all the scales the standard includes.
|
144
|
+
|
145
|
+
```ruby
|
146
|
+
indicator = Stix2::DomainObject::Indicator.new(confidence: i)
|
147
|
+
indicator.confidence # This is the raw integer
|
148
|
+
indicator.confidence_scale.to_admiralty_credibility # this is a string in this scale
|
149
|
+
indicator.confidence_scale.to_admiralty_credibility_strix # this is a string in stix mode
|
150
|
+
```
|
151
|
+
|
110
152
|
# Contribution
|
111
153
|
|
112
154
|
You can contribute to this project in 2 ways:
|
@@ -114,3 +156,7 @@ You can contribute to this project in 2 ways:
|
|
114
156
|
- with a PR: just follow the standard github workflow
|
115
157
|
- by pointing out missing support: open an issue and please provide a json containing the missing support, to simplify
|
116
158
|
the development
|
159
|
+
|
160
|
+
# See also
|
161
|
+
|
162
|
+
Ruby Stix2: https://github.com/crondaemon/ruby-taxii2
|
data/lib/stix2/base.rb
ADDED
data/lib/stix2/common.rb
CHANGED
@@ -1,44 +1,55 @@
|
|
1
1
|
module Stix2
|
2
|
-
|
3
|
-
include Hashie::Extensions::Dash::PredefinedValues
|
4
|
-
include Hashie::Extensions::IndifferentAccess
|
5
|
-
include Hashie::Extensions::Dash::Coercion
|
2
|
+
SPEC_VERSIONS = ['2.1']
|
6
3
|
|
4
|
+
class Common < Stix2::Base
|
7
5
|
property :type, required: true, coerce: String
|
8
|
-
property :spec_version, coerce: String, values:
|
6
|
+
property :spec_version, coerce: String, values: Stix2::SPEC_VERSIONS
|
9
7
|
property :id, coerce: Identifier
|
10
8
|
property :created_by_ref, coerce: Identifier
|
11
9
|
property :created, coerce: Time
|
12
10
|
property :modified, coerce: Time
|
13
|
-
property :revoked, coerce: Stix2
|
11
|
+
property :revoked, coerce: ->(value){ Stix2.to_bool(value) }
|
14
12
|
property :labels, coerce: Array[String]
|
15
|
-
property :confidence, coerce: Integer
|
13
|
+
property :confidence, coerce: ->(value){ int = Integer(value) ; [0..100].include?(int) ; int }
|
16
14
|
property :lang, coerce: String
|
17
15
|
property :external_references, coerce: Array[ExternalReference]
|
18
16
|
property :object_marking_refs, coerce: Array[Stix2::MetaObject::DataMarking::ObjectMarking]
|
19
17
|
property :granular_markings, coerce: Array[MetaObject::DataMarking::GranularMarking]
|
20
|
-
property :defanged, coerce: Stix2
|
18
|
+
property :defanged, coerce: ->(value){ Stix2.to_bool(value) }
|
21
19
|
property :extensions, coerce: Hash
|
22
20
|
|
23
21
|
def initialize(options = {})
|
24
22
|
Hashie.symbolize_keys!(options)
|
25
23
|
type = to_dash(self.class.name.split('::').last)
|
26
24
|
if options[:type]
|
27
|
-
|
25
|
+
if !options[:type].start_with?('x-') && options[:type] != type
|
26
|
+
raise("Property 'type' must be '#{type}'")
|
27
|
+
end
|
28
28
|
else
|
29
29
|
options[:type] = type
|
30
30
|
end
|
31
|
+
process_toplevel_property_extension(options[:extensions])
|
31
32
|
super(options)
|
32
|
-
|
33
|
+
process_extensions(options)
|
34
|
+
Stix2::Storage.add(self)
|
33
35
|
end
|
34
36
|
|
35
37
|
def method_missing(m, *args, &block)
|
36
|
-
|
38
|
+
if !m.to_s.end_with?('_instance')
|
39
|
+
# :nocov:
|
40
|
+
super(m, args, block)
|
41
|
+
return
|
42
|
+
# :nocov:
|
43
|
+
end
|
37
44
|
# Retrieve the original method
|
38
45
|
ref_method = m.to_s.gsub(/_instance$/, '')
|
39
46
|
obj = send(ref_method)
|
40
47
|
raise("Can't get a Stix2::Identifier from #{ref_method}") if !obj.is_a?(Stix2::Identifier)
|
41
|
-
Stix2.
|
48
|
+
Stix2::Storage.find(obj)
|
49
|
+
end
|
50
|
+
|
51
|
+
def confidence_scale
|
52
|
+
Stix2::ConfidenceScale.new(confidence)
|
42
53
|
end
|
43
54
|
|
44
55
|
private
|
@@ -48,15 +59,69 @@ module Stix2
|
|
48
59
|
end
|
49
60
|
|
50
61
|
def self.validate_array(list, valid_values)
|
51
|
-
excess = (Array(list) - valid_values)
|
62
|
+
excess = (Array(list).map(&:to_s) - valid_values.map(&:to_s))
|
52
63
|
excess.empty? || raise("Invalid values: #{excess}")
|
53
64
|
list
|
54
65
|
end
|
55
66
|
|
56
67
|
def self.hash_dict(hsh)
|
57
|
-
|
58
|
-
invalids.empty? || raise("Invalid values: #{invalids}")
|
68
|
+
validate_array(hsh.keys, HASH_ALGORITHM_OV)
|
59
69
|
hsh
|
60
70
|
end
|
71
|
+
|
72
|
+
def process_toplevel_property_extension(extensions)
|
73
|
+
extension_definition = extensions&.find{ |key, val| key.to_s.start_with?('extension-definition') }
|
74
|
+
return if !extension_definition
|
75
|
+
|
76
|
+
id = extension_definition.first
|
77
|
+
type = extension_definition.last[:extension_type]
|
78
|
+
if type == 'toplevel-property-extension'
|
79
|
+
Stix2::Storage.active? || raise('Stix.storage must be active to use toplevel-property-extension')
|
80
|
+
ext = Stix2::Storage.find(id)
|
81
|
+
ext.extension_properties.each do |prop|
|
82
|
+
self.class.class_eval do
|
83
|
+
property prop
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def process_extensions(options)
|
90
|
+
options[:extensions]&.each do |id, value|
|
91
|
+
case id.to_s
|
92
|
+
when /[A-Z]/
|
93
|
+
raise('Invalid extension name format.')
|
94
|
+
when 'archive-ext'
|
95
|
+
extensions[id] = Stix2::Extensions::ArchiveFile.new(value)
|
96
|
+
when /^extension-definition/
|
97
|
+
# Ignore it, already processes
|
98
|
+
when 'socket-ext'
|
99
|
+
extensions[id] = Stix2::Extensions::Socket.new(value)
|
100
|
+
when 'icmp-ext'
|
101
|
+
extensions[id] = Stix2::Extensions::Icmp.new(value)
|
102
|
+
when 'http-request-ext'
|
103
|
+
extensions[id] = Stix2::Extensions::HttpRequest.new(value)
|
104
|
+
when 'ntfs-ext'
|
105
|
+
extensions[id] = Stix2::Extensions::Ntfs.new(value)
|
106
|
+
when 'tcp-ext'
|
107
|
+
extensions[id] = Stix2::Extensions::Tcp.new(value)
|
108
|
+
when 'windows-process-ext'
|
109
|
+
extensions[id] = Stix2::Extensions::WindowsProcess.new(value)
|
110
|
+
when 'windows-service-ext'
|
111
|
+
extensions[id] = Stix2::Extensions::WindowsService.new(value)
|
112
|
+
when 'unix-account-ext'
|
113
|
+
extensions[id] = Stix2::Extensions::UnixAccount.new(value)
|
114
|
+
when 'pdf-ext'
|
115
|
+
extensions[id] = Stix2::Extensions::Pdf.new(value)
|
116
|
+
when 'raster-image-ext'
|
117
|
+
extensions[id] = Stix2::Extensions::RasterImage.new(value)
|
118
|
+
when 'windows-pebinary-ext'
|
119
|
+
extensions[id] = Stix2::Extensions::WindowsPebinary.new(value)
|
120
|
+
else
|
121
|
+
# Ensure we have a hash
|
122
|
+
value.is_a?(Hash) || raise("Custom extension must be Hash: #{value}")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
61
126
|
end
|
62
127
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Stix2
|
2
|
+
class ConfidenceScale
|
3
|
+
SCALE_NONE_LOW_MED_HIGH = {
|
4
|
+
0..0 => { scale: 'None', stix: 0 },
|
5
|
+
1..29 => { scale: 'Low', stix: 15 },
|
6
|
+
30..69 => { scale: 'Med', stix: 50 },
|
7
|
+
70..100 => { scale: 'High', stix: 85 }
|
8
|
+
}.freeze
|
9
|
+
|
10
|
+
SCALE_0_10 = {
|
11
|
+
0..4 => { scale: 0, stix: 0 },
|
12
|
+
5..14 => { scale: 1, stix: 10 },
|
13
|
+
15..24 => { scale: 2, stix: 20 },
|
14
|
+
25..34 => { scale: 3, stix: 30 },
|
15
|
+
35..44 => { scale: 4, stix: 40 },
|
16
|
+
45..54 => { scale: 5, stix: 50 },
|
17
|
+
55..64 => { scale: 6, stix: 60 },
|
18
|
+
65..74 => { scale: 7, stix: 70 },
|
19
|
+
75..84 => { scale: 8, stix: 80 },
|
20
|
+
85..94 => { scale: 9, stix: 90 },
|
21
|
+
95..100 => { scale: 10, stix: 100 }
|
22
|
+
}.freeze
|
23
|
+
|
24
|
+
SCALE_ADMIRALTY_CREDIBILITY = {
|
25
|
+
0..19 => { scale: 5, stix: 10 },
|
26
|
+
20..39 => { scale: 4, stix: 30 },
|
27
|
+
40..59 => { scale: 3, stix: 50 },
|
28
|
+
60..79 => { scale: 2, stix: 70 },
|
29
|
+
80..100 => { scale: 1, stix: 90 }
|
30
|
+
}.freeze
|
31
|
+
|
32
|
+
SCALE_WEP = {
|
33
|
+
0..0 => { scale: 'Impossible', stix: 0 },
|
34
|
+
1..19 => { scale: 'Highly Unlikely/Almost Certainly Not', stix: 10 },
|
35
|
+
20..39 => { scale: 'Unlikely/Probably Not', stix: 30 },
|
36
|
+
40..59 => { scale: 'Even Chance', stix: 50 },
|
37
|
+
60..79 => { scale: 'Likely/Probable', stix: 70 },
|
38
|
+
80..99 => { scale: 'Highly likely/Almost Certain', stix: 90 },
|
39
|
+
100..100 => { scale: 'Certain', stix: 100 }
|
40
|
+
}.freeze
|
41
|
+
|
42
|
+
SCALE_DNI = {
|
43
|
+
0..9 => { scale: 'Almost No Chance / Remote' , stix: 5 },
|
44
|
+
10..19 => { scale: 'Very Unlikely / Highly Improbable', stix: 15 },
|
45
|
+
20..39 => { scale: 'Unlikely / Improbable', stix: 30 },
|
46
|
+
40..59 => { scale: 'Roughly Even Chance / Roughly Even Odds', stix: 50 },
|
47
|
+
60..79 => { scale: 'Likely / Probable', stix: 70 },
|
48
|
+
80..89 => { scale: 'Very Likely / Highly Probable', stix: 85 },
|
49
|
+
90..100 => { scale: 'Almost Certain / Nearly Certain', stix: 95 }
|
50
|
+
}.freeze
|
51
|
+
|
52
|
+
def initialize(value = nil)
|
53
|
+
@value = value
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_none_low_med_high
|
57
|
+
!@value && 'Not Specified'
|
58
|
+
find_range(SCALE_NONE_LOW_MED_HIGH, :scale)
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_none_low_med_high_stix
|
62
|
+
!@value && 'Not Specified'
|
63
|
+
find_range(SCALE_NONE_LOW_MED_HIGH, :stix)
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_0_10
|
67
|
+
!@value && 6
|
68
|
+
find_range(SCALE_0_10, :scale)
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_0_10_stix
|
72
|
+
find_range(SCALE_0_10, :stix)
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_admiralty_credibility
|
76
|
+
find_range(SCALE_ADMIRALTY_CREDIBILITY, :scale)
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_admiralty_credibility_stix
|
80
|
+
find_range(SCALE_ADMIRALTY_CREDIBILITY, :stix)
|
81
|
+
end
|
82
|
+
|
83
|
+
def to_wep
|
84
|
+
find_range(SCALE_WEP, :scale)
|
85
|
+
end
|
86
|
+
|
87
|
+
def to_wep_stix
|
88
|
+
find_range(SCALE_WEP, :stix)
|
89
|
+
end
|
90
|
+
|
91
|
+
def to_dni_scale
|
92
|
+
find_range(SCALE_DNI, :scale)
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_dni_scale_stix
|
96
|
+
find_range(SCALE_DNI, :stix)
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def find_range(constant, type)
|
102
|
+
!@value || 'Not Specified'
|
103
|
+
constant.find{ |k,v| k.cover?(@value) }.last[type]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Stix2
|
2
|
+
class CustomObject < Stix2::Common
|
3
|
+
include Hashie::Extensions::IgnoreUndeclared
|
4
|
+
|
5
|
+
property :id, coerce: Identifier
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
Hashie.symbolize_keys!(options)
|
9
|
+
raise('A CustomObject must have at least one property') if options[:type] && options.count == 1
|
10
|
+
errors = Hash.new{ |k, v| k[v] = [] }
|
11
|
+
options.each do |key, value|
|
12
|
+
errors['Too short'] << key if key != :id && key.size < 3
|
13
|
+
errors['Invalid name'] << key if !key.match?(/^[a-z0-9_]*$/)
|
14
|
+
errors['Too long'] << key if key.size > 250
|
15
|
+
end
|
16
|
+
raise("Error creating CustomObject: #{errors}") if !errors.empty?
|
17
|
+
super(options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Stix2
|
2
2
|
module CyberobservableObject
|
3
3
|
class EmailMessage < Base
|
4
|
-
property :is_multipart, required: true, coerce: Stix2
|
4
|
+
property :is_multipart, required: true, coerce: ->(value){ Stix2.to_bool(value) }
|
5
5
|
property :date, coerce: Time
|
6
6
|
property :content_type, coerce: String
|
7
7
|
property :from_ref, coerce: Identifier
|
@@ -3,7 +3,7 @@ module Stix2
|
|
3
3
|
class NetworkTraffic < Base
|
4
4
|
property :start, coerce: Time
|
5
5
|
property :end, coerce: Time
|
6
|
-
property :is_active, coerce: ->(v){
|
6
|
+
property :is_active, coerce: ->(v){ Stix2.to_bool(v) }
|
7
7
|
property :src_ref, coerce: Identifier
|
8
8
|
property :dst_ref, coerce: Identifier
|
9
9
|
property :src_port, coerce: Integer
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Stix2
|
2
|
+
module CyberobservableObject
|
3
|
+
class Process < Base
|
4
|
+
property :is_hidden, coerce: ->(value){ Stix2.to_bool(value) }
|
5
|
+
property :pid, coerce: Integer
|
6
|
+
property :created_time, coerce: Time
|
7
|
+
property :cwd, coerce: String
|
8
|
+
property :command_line, coerce: String
|
9
|
+
property :environment_variables, coerce: Hash
|
10
|
+
property :opened_connection_refs, coerce: Array[Identifier]
|
11
|
+
property :creator_user_ref, coerce: Identifier
|
12
|
+
property :image_ref, coerce: Identifier
|
13
|
+
property :parent_ref, coerce: Identifier
|
14
|
+
property :child_refs, coerce: Array[Identifier]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -6,10 +6,10 @@ module Stix2
|
|
6
6
|
property :account_login, coerce: String
|
7
7
|
property :account_type, values: ACCOUNT_TYPE_OV
|
8
8
|
property :display_name, coerce: String
|
9
|
-
property :is_service_account, coerce: Stix2
|
10
|
-
property :is_privileged, coerce: Stix2
|
11
|
-
property :can_escalate_privs, coerce: Stix2
|
12
|
-
property :is_disabled, coerce: Stix2
|
9
|
+
property :is_service_account, coerce: ->(value){ Stix2.to_bool(value) }
|
10
|
+
property :is_privileged, coerce: ->(value){ Stix2.to_bool(value) }
|
11
|
+
property :can_escalate_privs, coerce: ->(value){ Stix2.to_bool(value) }
|
12
|
+
property :is_disabled, coerce: ->(value){ Stix2.to_bool(value) }
|
13
13
|
property :account_created, coerce: Time
|
14
14
|
property :account_expires, coerce: Time
|
15
15
|
property :credential_last_changed, coerce: Time
|
@@ -1,7 +1,9 @@
|
|
1
|
+
require 'stix2/cyberobservable_objects/x509_v3_extension_type'
|
2
|
+
|
1
3
|
module Stix2
|
2
4
|
module CyberobservableObject
|
3
5
|
class X509Certificate < Base
|
4
|
-
property :is_self_signed, coerce: ->(v){
|
6
|
+
property :is_self_signed, coerce: ->(v){ Stix2.to_bool(v) }
|
5
7
|
property :hashes, coerce: ->(hsh){ hash_dict(hsh) }
|
6
8
|
property :version, coerce: String
|
7
9
|
property :serial_number, coerce: String
|
@@ -4,7 +4,7 @@ module Stix2
|
|
4
4
|
property :name, coerce: String
|
5
5
|
property :description, coerce: String
|
6
6
|
property :malware_types, coerce: ->(v){ validate_array(v, Stix2::MALWARE_TYPE_OV) }
|
7
|
-
property :is_family, coerce: ->(v){
|
7
|
+
property :is_family, coerce: ->(v){ Stix2.to_bool(v) }
|
8
8
|
property :aliases, coerce: Array[String]
|
9
9
|
property :kill_chain_phases, coerce: Array[KillChainPhase]
|
10
10
|
property :first_seen, coerce: Time
|
data/lib/stix2/enum.rb
CHANGED
@@ -29,4 +29,63 @@ module Stix2
|
|
29
29
|
'REG_QWORD',
|
30
30
|
'REG_INVALID_TYPE'
|
31
31
|
].freeze
|
32
|
+
|
33
|
+
EXTENSION_TYPE_ENUM = [
|
34
|
+
'new-sdo',
|
35
|
+
'new-sco',
|
36
|
+
'new-sro',
|
37
|
+
'property-extension',
|
38
|
+
'toplevel-property-extension'
|
39
|
+
].freeze
|
40
|
+
|
41
|
+
NETWORK_SOCKET_ADDRESS_FAMILY_ENUM = [
|
42
|
+
'AF_UNSPEC',
|
43
|
+
'AF_INET',
|
44
|
+
'AF_IPX',
|
45
|
+
'AF_APPLETALK',
|
46
|
+
'AF_NETBIOS',
|
47
|
+
'AF_INET6',
|
48
|
+
'AF_IRDA',
|
49
|
+
'AF_BTH'
|
50
|
+
].freeze
|
51
|
+
|
52
|
+
NETWORK_SOCKET_TYPE_ENUM = [
|
53
|
+
'SOCK_STREAM',
|
54
|
+
'AF_ISOCK_DGRAMNET',
|
55
|
+
'SOCK_RAW',
|
56
|
+
'SOCK_RDM',
|
57
|
+
'SOCK_SEQPACKET'
|
58
|
+
].freeze
|
59
|
+
|
60
|
+
WINDOWS_INTEGRITY_LEVEL_ENUM = [
|
61
|
+
'low',
|
62
|
+
'medium',
|
63
|
+
'high',
|
64
|
+
'system'
|
65
|
+
].freeze
|
66
|
+
|
67
|
+
WINDOWS_SERVICE_START_TYPE_ENUM = [
|
68
|
+
'SERVICE_AUTO_START',
|
69
|
+
'SERVICE_BOOT_START',
|
70
|
+
'SERVICE_DEMAND_START',
|
71
|
+
'SERVICE_DISABLED',
|
72
|
+
'SERVICE_SYSTEM_ALERT'
|
73
|
+
].freeze
|
74
|
+
|
75
|
+
WINDOWS_SERVICE_TYPE_ENUM = [
|
76
|
+
'SERVICE_KERNEL_DRIVER',
|
77
|
+
'SERVICE_FILE_SYSTEM_DRIVER',
|
78
|
+
'SERVICE_WIN32_OWN_PROCESS',
|
79
|
+
'SERVICE_WIN32_SHARE_PROCESS'
|
80
|
+
].freeze
|
81
|
+
|
82
|
+
WINDOWS_SERVICE_STATUS_ENUM = [
|
83
|
+
'SERVICE_CONTINUE_PENDING',
|
84
|
+
'SERVICE_PAUSE_PENDING',
|
85
|
+
'SERVICE_PAUSED',
|
86
|
+
'SERVICE_RUNNING',
|
87
|
+
'SERVICE_START_PENDING',
|
88
|
+
'SERVICE_STOP_PENDING',
|
89
|
+
'SERVICE_STOPPED'
|
90
|
+
].freeze
|
32
91
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Stix2
|
2
|
+
class ExtensionDefinition < Stix2::Common
|
3
|
+
property :name, required: true, coerce: String
|
4
|
+
property :description, coerce: String
|
5
|
+
property :schema, required: true, coerce: String
|
6
|
+
property :version, required: true, coerce: String
|
7
|
+
property :extension_types, required: true, coerce: ->(values){ validate_array(values, EXTENSION_TYPE_ENUM) }
|
8
|
+
property :extension_properties, coerce: Array[String]
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Stix2
|
2
|
+
module Extensions
|
3
|
+
class HttpRequest < Stix2::Base
|
4
|
+
property :request_method, required: true, coerce: String
|
5
|
+
property :request_value, required: true, coerce: String
|
6
|
+
property :request_version, coerce: String
|
7
|
+
property :request_header, coerce: Hash
|
8
|
+
property :message_body_length, coerce: Integer
|
9
|
+
property :message_body_data_ref, coerce: Identifier
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Stix2
|
2
|
+
module Extensions
|
3
|
+
class Pdf < Stix2::Base
|
4
|
+
property :version, coerce: String
|
5
|
+
property :is_optimized, coerce: ->(value){ Stix2.to_bool(value) }
|
6
|
+
property :document_info_dict, Hash[String => String]
|
7
|
+
property :pdfid0, coerce: String
|
8
|
+
property :pdfid1, coerce: String
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Stix2
|
2
|
+
module Extensions
|
3
|
+
class Socket < Stix2::Base
|
4
|
+
property :address_family, required: true, values: NETWORK_SOCKET_ADDRESS_FAMILY_ENUM
|
5
|
+
property :is_blocking, coerce: ->(value){ Stix2.to_bool(value) }
|
6
|
+
property :is_listening, coerce: ->(value){ Stix2.to_bool(value) }
|
7
|
+
property :options, coerce: ->(hsh){ hsh.keys.all?{ |k| k.is_a?(Integer) } && hsh }
|
8
|
+
property :socket_type, values: NETWORK_SOCKET_TYPE_ENUM
|
9
|
+
property :socket_descriptor, coerce: Integer
|
10
|
+
property :socket_handle, coerce: Integer
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|