ronin-db-activerecord 0.1.0.beta1
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 +5 -0
- data/.github/workflows/ruby.yml +31 -0
- data/.gitignore +13 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/COPYING.txt +165 -0
- data/ChangeLog.md +39 -0
- data/Gemfile +27 -0
- data/README.md +143 -0
- data/Rakefile +72 -0
- data/db/migrate/0001_create_ronin_ip_address_mac_addresses_table.rb +43 -0
- data/db/migrate/0002_create_ronin_vulnerabilities_table.rb +61 -0
- data/db/migrate/0003_create_ronin_url_schemes_table.rb +32 -0
- data/db/migrate/0004_create_ronin_url_query_param_names_table.rb +32 -0
- data/db/migrate/0005_create_ronin_user_names_table.rb +33 -0
- data/db/migrate/0006_create_ronin_software_vendors_table.rb +32 -0
- data/db/migrate/0007_create_ronin_advisories_table.rb +42 -0
- data/db/migrate/0008_create_ronin_host_name_ip_addresses_table.rb +43 -0
- data/db/migrate/0009_create_ronin_host_names_table.rb +34 -0
- data/db/migrate/0010_create_ronin_arches_table.rb +37 -0
- data/db/migrate/0011_create_ronin_email_addresses_table.rb +44 -0
- data/db/migrate/0012_create_ronin_oses_table.rb +36 -0
- data/db/migrate/0013_create_ronin_organizations_table.rb +31 -0
- data/db/migrate/0014_create_ronin_ip_addresses_table.rb +35 -0
- data/db/migrate/0015_create_ronin_os_guesses_table.rb +40 -0
- data/db/migrate/0016_create_ronin_url_query_params_table.rb +42 -0
- data/db/migrate/0017_create_ronin_passwords_table.rb +32 -0
- data/db/migrate/0018_create_ronin_open_ports_table.rb +46 -0
- data/db/migrate/0019_create_ronin_urls_table.rb +50 -0
- data/db/migrate/0020_create_ronin_softwares_table.rb +39 -0
- data/db/migrate/0021_create_ronin_mac_addresses_table.rb +33 -0
- data/db/migrate/0022_create_ronin_countries_table.rb +34 -0
- data/db/migrate/0023_create_ronin_services_table.rb +32 -0
- data/db/migrate/0024_create_ronin_credentials_table.rb +44 -0
- data/db/migrate/0025_create_ronin_ports_table.rb +33 -0
- data/db/migrate/0026_create_ronin_asns_table.rb +44 -0
- data/db/migrate/0027_create_ronin_http_query_param_names_table.rb +32 -0
- data/db/migrate/0028_create_ronin_http_query_params_table.rb +42 -0
- data/db/migrate/0029_create_ronin_http_header_names_table.rb +31 -0
- data/db/migrate/0030_create_ronin_http_request_headers_table.rb +41 -0
- data/db/migrate/0031_create_ronin_http_response_headers_table.rb +41 -0
- data/db/migrate/0032_create_ronin_http_requests_table.rb +41 -0
- data/db/migrate/0033_create_ronin_http_responses_table.rb +36 -0
- data/db/migrate/0034_create_ronin_service_credentials_table.rb +41 -0
- data/db/migrate/0035_create_ronin_web_credentials_table.rb +41 -0
- data/gemspec.yml +28 -0
- data/lib/ronin/db/address.rb +105 -0
- data/lib/ronin/db/advisory.rb +169 -0
- data/lib/ronin/db/arch.rb +160 -0
- data/lib/ronin/db/asn.rb +212 -0
- data/lib/ronin/db/credential.rb +248 -0
- data/lib/ronin/db/email_address.rb +225 -0
- data/lib/ronin/db/host_name.rb +224 -0
- data/lib/ronin/db/host_name_ip_address.rb +65 -0
- data/lib/ronin/db/http_header_name.rb +75 -0
- data/lib/ronin/db/http_query_param.rb +79 -0
- data/lib/ronin/db/http_query_param_name.rb +76 -0
- data/lib/ronin/db/http_request.rb +120 -0
- data/lib/ronin/db/http_request_header.rb +78 -0
- data/lib/ronin/db/http_response.rb +91 -0
- data/lib/ronin/db/http_response_header.rb +78 -0
- data/lib/ronin/db/ip_address.rb +351 -0
- data/lib/ronin/db/ip_address_mac_address.rb +62 -0
- data/lib/ronin/db/mac_address.rb +91 -0
- data/lib/ronin/db/migrations.rb +137 -0
- data/lib/ronin/db/model/has_name.rb +102 -0
- data/lib/ronin/db/model/has_unique_name.rb +82 -0
- data/lib/ronin/db/model/importable.rb +85 -0
- data/lib/ronin/db/model/last_scanned_at.rb +48 -0
- data/lib/ronin/db/model.rb +37 -0
- data/lib/ronin/db/models.rb +108 -0
- data/lib/ronin/db/open_port.rb +148 -0
- data/lib/ronin/db/organization.rb +50 -0
- data/lib/ronin/db/os.rb +183 -0
- data/lib/ronin/db/os_guess.rb +67 -0
- data/lib/ronin/db/password.rb +167 -0
- data/lib/ronin/db/port.rb +123 -0
- data/lib/ronin/db/root.rb +28 -0
- data/lib/ronin/db/schema_migration.rb +34 -0
- data/lib/ronin/db/service.rb +48 -0
- data/lib/ronin/db/service_credential.rb +66 -0
- data/lib/ronin/db/software.rb +85 -0
- data/lib/ronin/db/software_vendor.rb +42 -0
- data/lib/ronin/db/url.rb +497 -0
- data/lib/ronin/db/url_query_param.rb +79 -0
- data/lib/ronin/db/url_query_param_name.rb +76 -0
- data/lib/ronin/db/url_scheme.rb +80 -0
- data/lib/ronin/db/user_name.rb +96 -0
- data/lib/ronin/db/vulnerability.rb +81 -0
- data/lib/ronin/db/web_credential.rb +69 -0
- data/ronin-db-activerecord.gemspec +61 -0
- data/spec/advisory_spec.rb +277 -0
- data/spec/arch_spec.rb +228 -0
- data/spec/asn_spec.rb +504 -0
- data/spec/credential_spec.rb +362 -0
- data/spec/email_address_spec.rb +372 -0
- data/spec/host_name_ip_address_spec.rb +8 -0
- data/spec/host_name_spec.rb +207 -0
- data/spec/http_header_name_spec.rb +25 -0
- data/spec/http_query_param_name_spec.rb +25 -0
- data/spec/http_query_param_spec.rb +104 -0
- data/spec/http_request_header_spec.rb +72 -0
- data/spec/http_request_spec.rb +168 -0
- data/spec/http_response_header_spec.rb +74 -0
- data/spec/http_response_spec.rb +103 -0
- data/spec/ip_address_mac_addresses_spec.rb +8 -0
- data/spec/ip_address_spec.rb +386 -0
- data/spec/mac_address_spec.rb +67 -0
- data/spec/migrations_spec.rb +122 -0
- data/spec/model/has_name_spec.rb +65 -0
- data/spec/model/has_unique_name_spec.rb +61 -0
- data/spec/model/importable_spec.rb +105 -0
- data/spec/models_spec.rb +60 -0
- data/spec/open_port_spec.rb +87 -0
- data/spec/organization_spec.rb +10 -0
- data/spec/os_guess_spec.rb +43 -0
- data/spec/os_spec.rb +114 -0
- data/spec/password_spec.rb +81 -0
- data/spec/port_spec.rb +102 -0
- data/spec/schema_migration_spec.rb +8 -0
- data/spec/service_credential_spec.rb +43 -0
- data/spec/service_spec.rb +39 -0
- data/spec/software_spec.rb +76 -0
- data/spec/software_vendor_spec.rb +33 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/url_query_param_name_spec.rb +25 -0
- data/spec/url_query_param_spec.rb +110 -0
- data/spec/url_scheme_spec.rb +39 -0
- data/spec/url_spec.rb +951 -0
- data/spec/user_name_spec.rb +54 -0
- data/spec/vulnerability_spec.rb +8 -0
- data/spec/web_credential_spec.rb +72 -0
- metadata +266 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
3
|
+
# ronin-db-activerecord - ActiveRecord backend for the Ronin Database.
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
|
6
|
+
#
|
|
7
|
+
# ronin-db-activerecord is free software: you can redistribute it and/or modify
|
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
# (at your option) any later version.
|
|
11
|
+
#
|
|
12
|
+
# ronin-db-activerecord is distributed in the hope that it will be useful,
|
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
# GNU Lesser General Public License for more details.
|
|
16
|
+
#
|
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
|
18
|
+
# along with ronin-db-activerecord. If not, see <https://www.gnu.org/licenses/>.
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
require 'ronin/db/model'
|
|
22
|
+
require 'ronin/db/model/importable'
|
|
23
|
+
require 'ronin/db/model/last_scanned_at'
|
|
24
|
+
|
|
25
|
+
require 'active_record'
|
|
26
|
+
|
|
27
|
+
module Ronin
|
|
28
|
+
module DB
|
|
29
|
+
#
|
|
30
|
+
# A base model which represents an Internet Address, such as:
|
|
31
|
+
#
|
|
32
|
+
# * {MACAddress}
|
|
33
|
+
# * {IPAddress}
|
|
34
|
+
# * {HostName}
|
|
35
|
+
#
|
|
36
|
+
class Address < ActiveRecord::Base
|
|
37
|
+
|
|
38
|
+
include Model
|
|
39
|
+
include Model::Importable
|
|
40
|
+
include Model::LastScannedAt
|
|
41
|
+
|
|
42
|
+
self.abstract_class = true
|
|
43
|
+
|
|
44
|
+
# @!attribute [rw] id
|
|
45
|
+
# The primary key of the Address
|
|
46
|
+
#
|
|
47
|
+
# @return [Integer]
|
|
48
|
+
attribute :id, :integer
|
|
49
|
+
|
|
50
|
+
# @!attribute [rw] address
|
|
51
|
+
# The Address
|
|
52
|
+
#
|
|
53
|
+
# @return [String]
|
|
54
|
+
attribute :address, :string
|
|
55
|
+
validates :address, presence: true, uniqueness: true
|
|
56
|
+
|
|
57
|
+
# @!attribute [rw] created_at
|
|
58
|
+
# Tracks when the IP Address was first created
|
|
59
|
+
#
|
|
60
|
+
# @return [Time]
|
|
61
|
+
attribute :created_at, :time
|
|
62
|
+
|
|
63
|
+
#
|
|
64
|
+
# Looks up the address.
|
|
65
|
+
#
|
|
66
|
+
# @param [String] address
|
|
67
|
+
# The address to query.
|
|
68
|
+
#
|
|
69
|
+
# @return [Address, nil]
|
|
70
|
+
# The found address.
|
|
71
|
+
#
|
|
72
|
+
def self.lookup(address)
|
|
73
|
+
find_by(address: address)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
#
|
|
77
|
+
# Imports an address.
|
|
78
|
+
#
|
|
79
|
+
# @param [String] address
|
|
80
|
+
# The address to parse.
|
|
81
|
+
#
|
|
82
|
+
# @return [Address]
|
|
83
|
+
# The parsed address.
|
|
84
|
+
#
|
|
85
|
+
# @api public
|
|
86
|
+
#
|
|
87
|
+
def self.import(address)
|
|
88
|
+
create(address: address)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
#
|
|
92
|
+
# Converts the address into a string.
|
|
93
|
+
#
|
|
94
|
+
# @return [String]
|
|
95
|
+
# The address.
|
|
96
|
+
#
|
|
97
|
+
# @api public
|
|
98
|
+
#
|
|
99
|
+
def to_s
|
|
100
|
+
self.address.to_s
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
3
|
+
# ronin-db-activerecord - ActiveRecord backend for the Ronin Database.
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
|
6
|
+
#
|
|
7
|
+
# ronin-db-activerecord is free software: you can redistribute it and/or modify
|
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
# (at your option) any later version.
|
|
11
|
+
#
|
|
12
|
+
# ronin-db-activerecord is distributed in the hope that it will be useful,
|
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
# GNU Lesser General Public License for more details.
|
|
16
|
+
#
|
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
|
18
|
+
# along with ronin-db-activerecord. If not, see <https://www.gnu.org/licenses/>.
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
require 'ronin/db/model'
|
|
22
|
+
require 'ronin/db/model/importable'
|
|
23
|
+
|
|
24
|
+
require 'active_record'
|
|
25
|
+
|
|
26
|
+
module Ronin
|
|
27
|
+
module DB
|
|
28
|
+
#
|
|
29
|
+
# Represents a vulnerability Advisory, with a Publisher, Number and
|
|
30
|
+
# URL.
|
|
31
|
+
#
|
|
32
|
+
class Advisory < ActiveRecord::Base
|
|
33
|
+
|
|
34
|
+
include Model
|
|
35
|
+
include Model::Importable
|
|
36
|
+
|
|
37
|
+
self.primary_key = :id
|
|
38
|
+
|
|
39
|
+
# @!attribute [rw] id
|
|
40
|
+
# Primary key of the advisory.
|
|
41
|
+
#
|
|
42
|
+
# @return [String]
|
|
43
|
+
attribute :id, :string
|
|
44
|
+
|
|
45
|
+
# @!attribute [rw] prefix
|
|
46
|
+
# The ID prefix (ex: `CVE` or `GHSA`).
|
|
47
|
+
#
|
|
48
|
+
# @return [String]
|
|
49
|
+
attribute :prefix, :string
|
|
50
|
+
validates :prefix, presence: true
|
|
51
|
+
|
|
52
|
+
# @!attribute [rw] year
|
|
53
|
+
# The year the advisory was published in.
|
|
54
|
+
#
|
|
55
|
+
# @return [Integer]
|
|
56
|
+
attribute :year, :integer
|
|
57
|
+
validates :year, allow_nil: true,
|
|
58
|
+
comparison: {
|
|
59
|
+
greater_than: 1990,
|
|
60
|
+
less_than_or_equal_to: Date.today.year
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# @!attribute [rw] identifier
|
|
64
|
+
# The advisory identifier
|
|
65
|
+
#
|
|
66
|
+
# @return [String]
|
|
67
|
+
attribute :identifier, :string
|
|
68
|
+
validates :identifier, presence: true
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
# @api private
|
|
72
|
+
#
|
|
73
|
+
module ID
|
|
74
|
+
#
|
|
75
|
+
# Parses a security avdisory ID.
|
|
76
|
+
#
|
|
77
|
+
# @param [String] string
|
|
78
|
+
# The security advisory ID String to split.
|
|
79
|
+
#
|
|
80
|
+
# @return [Hash{Symbol => Object}]
|
|
81
|
+
# The parsed security advisory ID.
|
|
82
|
+
#
|
|
83
|
+
# @raise [ArgumentError]
|
|
84
|
+
# The ID does not appear to be a valid security ID.
|
|
85
|
+
#
|
|
86
|
+
def self.parse(string)
|
|
87
|
+
if (match = string.match(/\A([A-Z]+)-(\d{4})[:-]([0-9][0-9-]+)\z/))
|
|
88
|
+
{
|
|
89
|
+
id: match[0],
|
|
90
|
+
prefix: match[1],
|
|
91
|
+
year: match[2].to_i,
|
|
92
|
+
identifier: match[3]
|
|
93
|
+
}
|
|
94
|
+
elsif (match = string.match(/\AMS(\d{2})-(\d{3,})\z/))
|
|
95
|
+
{
|
|
96
|
+
id: match[0],
|
|
97
|
+
prefix: 'MS',
|
|
98
|
+
year: 2000 + match[1].to_i,
|
|
99
|
+
identifier: match[2]
|
|
100
|
+
}
|
|
101
|
+
elsif (match = string.match(/\A([A-Z]+)-(.+)\z/))
|
|
102
|
+
{
|
|
103
|
+
id: match[0],
|
|
104
|
+
prefix: match[1],
|
|
105
|
+
identifier: match[2]
|
|
106
|
+
}
|
|
107
|
+
else
|
|
108
|
+
raise(ArgumentError,"id does not appear to be a valid security advisory ID: #{string.inspect}")
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
#
|
|
114
|
+
# Looks up the advisory.
|
|
115
|
+
#
|
|
116
|
+
# @param [String] id
|
|
117
|
+
#
|
|
118
|
+
# @return [Advisory, nil]
|
|
119
|
+
#
|
|
120
|
+
def self.lookup(id)
|
|
121
|
+
find_by(id: id)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
#
|
|
125
|
+
# Parses an Advisory ID String.
|
|
126
|
+
#
|
|
127
|
+
# @param [String] id
|
|
128
|
+
# The ID String for the advisory.
|
|
129
|
+
#
|
|
130
|
+
# @return [Advisory]
|
|
131
|
+
# The new advisory.
|
|
132
|
+
#
|
|
133
|
+
# @api public
|
|
134
|
+
#
|
|
135
|
+
def self.import(id)
|
|
136
|
+
create(**ID.parse(id))
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
#
|
|
140
|
+
# Generates a URL for the advisory.
|
|
141
|
+
#
|
|
142
|
+
# @return [String, nil]
|
|
143
|
+
# The URL for the advisory.
|
|
144
|
+
#
|
|
145
|
+
# @api public
|
|
146
|
+
#
|
|
147
|
+
def url
|
|
148
|
+
case prefix
|
|
149
|
+
when 'CVE' then "https://nvd.nist.gov/vuln/detail/#{id}"
|
|
150
|
+
when 'RHSA' then "https://access.redhat.com/errata/#{id}"
|
|
151
|
+
when 'GHSA' then "https://github.com/advisories/#{id}"
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
#
|
|
156
|
+
# Converts the advisory to a String.
|
|
157
|
+
#
|
|
158
|
+
# @return [String]
|
|
159
|
+
# The advisory ID string.
|
|
160
|
+
#
|
|
161
|
+
# @api public
|
|
162
|
+
#
|
|
163
|
+
def to_s
|
|
164
|
+
self.id
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
3
|
+
# ronin-db-activerecord - ActiveRecord backend for the Ronin Database.
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
|
6
|
+
#
|
|
7
|
+
# ronin-db-activerecord is free software: you can redistribute it and/or modify
|
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
# (at your option) any later version.
|
|
11
|
+
#
|
|
12
|
+
# ronin-db-activerecord is distributed in the hope that it will be useful,
|
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
# GNU Lesser General Public License for more details.
|
|
16
|
+
#
|
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
|
18
|
+
# along with ronin-db-activerecord. If not, see <https://www.gnu.org/licenses/>.
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
require 'ronin/db/model'
|
|
22
|
+
require 'ronin/db/model/has_unique_name'
|
|
23
|
+
|
|
24
|
+
require 'active_record'
|
|
25
|
+
|
|
26
|
+
module Ronin
|
|
27
|
+
module DB
|
|
28
|
+
#
|
|
29
|
+
# Represents a Computer Architecture and predefines many other common
|
|
30
|
+
# architectures ({x86}, {x86_64}, {ppc}, {ppc64}, {mips}, {mips_le},
|
|
31
|
+
# {mips_be}, {arm}, {arm_le}, and {arm_be}).
|
|
32
|
+
#
|
|
33
|
+
class Arch < ActiveRecord::Base
|
|
34
|
+
|
|
35
|
+
include Model
|
|
36
|
+
include Model::HasUniqueName
|
|
37
|
+
|
|
38
|
+
# @!attribute [rw] id
|
|
39
|
+
# The primary key of the arch.
|
|
40
|
+
#
|
|
41
|
+
# @return [Integer]
|
|
42
|
+
attribute :id, :integer
|
|
43
|
+
|
|
44
|
+
# @!attribute [rw] endian
|
|
45
|
+
# Endianness of the architecture.
|
|
46
|
+
#
|
|
47
|
+
# @return [:little, :big]
|
|
48
|
+
enum :endian, {little: 'little', big: 'big'}
|
|
49
|
+
validates :endian, presence: true
|
|
50
|
+
|
|
51
|
+
# @!attribute [rw] word_size
|
|
52
|
+
# Address length of the architecture.
|
|
53
|
+
#
|
|
54
|
+
# @return [Integer]
|
|
55
|
+
attribute :word_size, :integer
|
|
56
|
+
validates :word_size, presence: true,
|
|
57
|
+
inclusion: {in: [4, 8]}
|
|
58
|
+
|
|
59
|
+
#
|
|
60
|
+
# The x86 Architecture
|
|
61
|
+
#
|
|
62
|
+
# @return [Arch]
|
|
63
|
+
#
|
|
64
|
+
def self.x86
|
|
65
|
+
find_or_create_by(name: 'x86')
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#
|
|
69
|
+
# The i686 Architecture
|
|
70
|
+
#
|
|
71
|
+
# @return [Arch]
|
|
72
|
+
#
|
|
73
|
+
def self.i686
|
|
74
|
+
find_or_create_by(name: 'i686')
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
#
|
|
78
|
+
# The x86_64 Architecture
|
|
79
|
+
#
|
|
80
|
+
# @return [Arch]
|
|
81
|
+
#
|
|
82
|
+
def self.x86_64
|
|
83
|
+
find_or_create_by(name: 'x86-64')
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
#
|
|
87
|
+
# The 32-bit PowerPC Architecture
|
|
88
|
+
#
|
|
89
|
+
# @return [Arch]
|
|
90
|
+
#
|
|
91
|
+
def self.ppc
|
|
92
|
+
find_or_create_by(name: 'PPC')
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
#
|
|
96
|
+
# The 64-bit PowerPC Architecture
|
|
97
|
+
#
|
|
98
|
+
# @return [Arch]
|
|
99
|
+
#
|
|
100
|
+
def self.ppc64
|
|
101
|
+
find_or_create_by(name: 'PPC64')
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
#
|
|
105
|
+
# The MIPS Architecture
|
|
106
|
+
#
|
|
107
|
+
# @return [Arch]
|
|
108
|
+
#
|
|
109
|
+
def self.mips
|
|
110
|
+
find_or_create_by(name: 'MIPS')
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
#
|
|
114
|
+
# The MIPS (little endian) Architecture
|
|
115
|
+
#
|
|
116
|
+
# @return [Arch]
|
|
117
|
+
#
|
|
118
|
+
def self.mips_le
|
|
119
|
+
find_or_create_by(name: 'MIPS (Little-Endian)')
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
#
|
|
123
|
+
# The MIPS (big endian) Architecture
|
|
124
|
+
#
|
|
125
|
+
# @return [Arch]
|
|
126
|
+
#
|
|
127
|
+
def self.mips_be
|
|
128
|
+
find_or_create_by(name: 'MIPS (Big-Endian)')
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
#
|
|
132
|
+
# The ARM Architecture
|
|
133
|
+
#
|
|
134
|
+
# @return [Arch]
|
|
135
|
+
#
|
|
136
|
+
def self.arm
|
|
137
|
+
find_or_create_by(name: 'ARM')
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
#
|
|
141
|
+
# The ARM (little endian) Architecture
|
|
142
|
+
#
|
|
143
|
+
# @return [Arch]
|
|
144
|
+
#
|
|
145
|
+
def self.arm_le
|
|
146
|
+
find_or_create_by(name: 'ARM (Little-Endian)')
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
#
|
|
150
|
+
# The ARM (big endian) Architecture
|
|
151
|
+
#
|
|
152
|
+
# @return [Arch]
|
|
153
|
+
#
|
|
154
|
+
def self.arm_be
|
|
155
|
+
find_or_create_by(name: 'ARM (Big-Endian)')
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
data/lib/ronin/db/asn.rb
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
3
|
+
# ronin-db-activerecord - ActiveRecord backend for the Ronin Database.
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2022 Hal Brodigan (postmodern.mod3 at gmail.com)
|
|
6
|
+
#
|
|
7
|
+
# ronin-db-activerecord is free software: you can redistribute it and/or modify
|
|
8
|
+
# it under the terms of the GNU Lesser General Public License as published
|
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
# (at your option) any later version.
|
|
11
|
+
#
|
|
12
|
+
# ronin-db-activerecord is distributed in the hope that it will be useful,
|
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
# GNU Lesser General Public License for more details.
|
|
16
|
+
#
|
|
17
|
+
# You should have received a copy of the GNU Lesser General Public License
|
|
18
|
+
# along with ronin-db-activerecord. If not, see <https://www.gnu.org/licenses/>.
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
require 'ronin/db/model'
|
|
22
|
+
|
|
23
|
+
module Ronin
|
|
24
|
+
module DB
|
|
25
|
+
#
|
|
26
|
+
# Represents an ASN range.
|
|
27
|
+
#
|
|
28
|
+
class ASN < ActiveRecord::Base
|
|
29
|
+
|
|
30
|
+
include Model
|
|
31
|
+
|
|
32
|
+
# @!attribute [rw] id
|
|
33
|
+
# The primary key of the ASN range.
|
|
34
|
+
#
|
|
35
|
+
# @return [Integer]
|
|
36
|
+
attribute :id, :integer
|
|
37
|
+
|
|
38
|
+
# @!attribute [rw] version
|
|
39
|
+
# Whether the ASN range represents an IPv4 or IPv6 range.
|
|
40
|
+
#
|
|
41
|
+
# @return [Integer]
|
|
42
|
+
attribute :version, :integer
|
|
43
|
+
validates :version, presence: true,
|
|
44
|
+
inclusion: {in: [4, 6]}
|
|
45
|
+
|
|
46
|
+
# @!attribute [rw] range_start
|
|
47
|
+
# The starting IP address of the ASN range.
|
|
48
|
+
#
|
|
49
|
+
# @return [String]
|
|
50
|
+
attribute :range_start, :string
|
|
51
|
+
validates :range_start, presence: true
|
|
52
|
+
|
|
53
|
+
# @!attribute [rw] range_end
|
|
54
|
+
# The ending IP address of the ASN range.
|
|
55
|
+
#
|
|
56
|
+
# @return [String]
|
|
57
|
+
attribute :range_end, :string
|
|
58
|
+
validates :range_end, presence: true
|
|
59
|
+
|
|
60
|
+
# @!attribute [r] range_start_hton
|
|
61
|
+
# The starting IP address of the ASN range, but in network byte-order.
|
|
62
|
+
#
|
|
63
|
+
# @return [String]
|
|
64
|
+
attribute :range_start_hton, :binary
|
|
65
|
+
|
|
66
|
+
# @!attribute [r] range_end_hton
|
|
67
|
+
# The ending IP address of the ASN range, but in network byte-order.
|
|
68
|
+
#
|
|
69
|
+
# @return [String]
|
|
70
|
+
attribute :range_end_hton, :binary
|
|
71
|
+
|
|
72
|
+
before_save :set_hton
|
|
73
|
+
|
|
74
|
+
# @!attribute [rw] number
|
|
75
|
+
# The ASN number.
|
|
76
|
+
#
|
|
77
|
+
# @return [Integer]
|
|
78
|
+
attribute :number, :integer
|
|
79
|
+
validates :number, presence: true,
|
|
80
|
+
uniqueness: {scope: [:range_start, :range_end]}
|
|
81
|
+
|
|
82
|
+
# @!attribute [rw] country_code
|
|
83
|
+
# The country code of the ASN.
|
|
84
|
+
#
|
|
85
|
+
# @return [String]
|
|
86
|
+
attribute :country_code, :string
|
|
87
|
+
|
|
88
|
+
# @!attribute [rw] name
|
|
89
|
+
# The organization the ASN is currently assigned to.
|
|
90
|
+
#
|
|
91
|
+
# @return [String]
|
|
92
|
+
attribute :name, :string
|
|
93
|
+
|
|
94
|
+
#
|
|
95
|
+
# Searches for all IPv4 ASNs.
|
|
96
|
+
#
|
|
97
|
+
# @return [Array<ASN>]
|
|
98
|
+
# The IPv4 ASNs.
|
|
99
|
+
#
|
|
100
|
+
# @api public
|
|
101
|
+
#
|
|
102
|
+
def self.v4
|
|
103
|
+
where(version: 4)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
#
|
|
107
|
+
# Searches for all IPv6 ASNs.
|
|
108
|
+
#
|
|
109
|
+
# @return [Array<ASNs>]
|
|
110
|
+
# The IPv6 ASNs.
|
|
111
|
+
#
|
|
112
|
+
# @api public
|
|
113
|
+
#
|
|
114
|
+
def self.v6
|
|
115
|
+
where(version: 6)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
#
|
|
119
|
+
# Searches for all ASNs with the matching AS number.
|
|
120
|
+
#
|
|
121
|
+
# @param [Integer] number
|
|
122
|
+
# The AS number to search for.
|
|
123
|
+
#
|
|
124
|
+
# @return [Array<ASN>]
|
|
125
|
+
#
|
|
126
|
+
def self.with_number(number)
|
|
127
|
+
where(number: number)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
#
|
|
131
|
+
# Searches for all ASNs with the matching country code.
|
|
132
|
+
#
|
|
133
|
+
# @param [String] country_code
|
|
134
|
+
# The two letter country code to search for.
|
|
135
|
+
#
|
|
136
|
+
# @return [Array<ASN>]
|
|
137
|
+
#
|
|
138
|
+
def self.with_country_code(country_code)
|
|
139
|
+
where(country_code: country_code)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
#
|
|
143
|
+
# Searches for all ASNs with the matching name.
|
|
144
|
+
#
|
|
145
|
+
# @param [String] name
|
|
146
|
+
# The name to search for.
|
|
147
|
+
#
|
|
148
|
+
# @return [Array<ASN>]
|
|
149
|
+
#
|
|
150
|
+
def self.with_name(name)
|
|
151
|
+
where(name: name)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
#
|
|
155
|
+
# Queries the ASN that contains the given IP address.
|
|
156
|
+
#
|
|
157
|
+
# @param [IPAddr, String] ip
|
|
158
|
+
#
|
|
159
|
+
# @return [ASN, nil]
|
|
160
|
+
#
|
|
161
|
+
def self.containing_ip(ip)
|
|
162
|
+
ip = IPAddr.new(ip) unless ip.kind_of?(IPAddr)
|
|
163
|
+
ip_hton = ip.hton
|
|
164
|
+
|
|
165
|
+
range_start_hton = self.arel_table[:range_start_hton]
|
|
166
|
+
range_end_hton = self.arel_table[:range_end_hton]
|
|
167
|
+
|
|
168
|
+
where(range_start_hton.lteq(ip_hton).and(range_end_hton.gteq(ip_hton))).first
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
#
|
|
172
|
+
# @return [IPAddr, nil]
|
|
173
|
+
#
|
|
174
|
+
def range_start_ipaddr
|
|
175
|
+
@range_start_ipaddr ||= if self.range_start
|
|
176
|
+
IPAddr.new(self.range_start)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
#
|
|
181
|
+
# @return [IPAddr, nil]
|
|
182
|
+
#
|
|
183
|
+
def range_end_ipaddr
|
|
184
|
+
@range_end_ipaddr ||= if self.range_end
|
|
185
|
+
IPAddr.new(self.range_end)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
#
|
|
190
|
+
# Queries all IP addresses within the ASN IP range.
|
|
191
|
+
#
|
|
192
|
+
# @return [Array<IPAddress>]
|
|
193
|
+
#
|
|
194
|
+
def ip_addresses
|
|
195
|
+
IPAddress.between(range_start,range_end)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
private
|
|
199
|
+
|
|
200
|
+
#
|
|
201
|
+
# Sets the `range_start_hton` and `range_end_hton` attributes.
|
|
202
|
+
#
|
|
203
|
+
def set_hton
|
|
204
|
+
self.range_start_hton = range_start_ipaddr.hton
|
|
205
|
+
self.range_end_hton = range_end_ipaddr.hton
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
require 'ronin/db/ip_address'
|