Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/shared_gem_verify_rails.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Build Rails version matrix
id: merge_rails_versions
run: |
default_rails_versions='["~> 7.0.0","~> 7.1.0","~> 7.2.0"]'
default_rails_versions='["~> 7.0.0","~> 7.1.0","~> 7.2.0","~> 8.0.0"]'
additional_rails_versions='${{ inputs.additional_rails_versions }}'

rails_versions=$(jq -cn \
Expand Down
123 changes: 61 additions & 62 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ PATH
metasploit-framework (6.4.128)
aarch64
abbrev
actionpack (~> 7.2.0)
activerecord (~> 7.2.0)
activesupport (~> 7.2.0)
actionpack (~> 8.0.0)
activerecord (~> 8.0.0)
activesupport (~> 8.0.0)
aws-sdk-ec2
aws-sdk-ec2instanceconnect
aws-sdk-iam
Expand Down Expand Up @@ -43,11 +43,11 @@ PATH
json
lru_redux
metasm
metasploit-concern
metasploit-credential (>= 6.0.21)
metasploit-model
metasploit-concern (~> 5.0, >= 5.0.6)
metasploit-credential (~> 6.0, >= 6.0.22)
metasploit-model (~> 5.0, >= 5.0.5)
metasploit-payloads (= 2.0.245)
metasploit_data_models (>= 6.0.15)
metasploit_data_models (~> 6.0, >= 6.0.16)
metasploit_payloads-mettle (= 1.0.46)
mqtt
msgpack (~> 1.6.0)
Expand All @@ -72,7 +72,7 @@ PATH
pdf-reader
pg
puma
rack (~> 2.2)
rack (>= 3.0)
railties
rasn1 (= 0.14.0)
rb-readline
Expand Down Expand Up @@ -105,13 +105,12 @@ PATH
ruby_smb (~> 3.3.17)
rubyntlm
rubyzip
sinatra (~> 3.2)
sinatra (~> 4.0)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to bump sinatra for rails 8, or is this worth splitting out?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rails 8 requires a minimum of Rack 3 which requires sinatra 4

sqlite3 (= 1.7.3)
sshkey
stringio (= 3.1.1)
swagger-blocks
syslog
thin (~> 1.x)
tzinfo
tzinfo-data
unix-crypt
Expand All @@ -130,30 +129,29 @@ GEM
aarch64 (2.1.0)
racc (~> 1.6)
abbrev (0.1.2)
actionpack (7.2.2.2)
actionview (= 7.2.2.2)
activesupport (= 7.2.2.2)
actionpack (8.0.5)
actionview (= 8.0.5)
activesupport (= 8.0.5)
nokogiri (>= 1.8.5)
racc
rack (>= 2.2.4, < 3.2)
rack (>= 2.2.4)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
useragent (~> 0.16)
actionview (7.2.2.2)
activesupport (= 7.2.2.2)
actionview (8.0.5)
activesupport (= 8.0.5)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
activemodel (7.2.2.2)
activesupport (= 7.2.2.2)
activerecord (7.2.2.2)
activemodel (= 7.2.2.2)
activesupport (= 7.2.2.2)
activemodel (8.0.5)
activesupport (= 8.0.5)
activerecord (8.0.5)
activemodel (= 8.0.5)
activesupport (= 8.0.5)
timeout (>= 0.4.0)
activesupport (7.2.2.2)
activesupport (8.0.5)
base64
benchmark (>= 0.3)
bigdecimal
Expand All @@ -165,6 +163,7 @@ GEM
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
uri (>= 0.13.1)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
afm (0.2.2)
Expand All @@ -175,8 +174,8 @@ GEM
mime-types (>= 3.3, < 4)
require_all (>= 2, < 4)
rspec-expectations (~> 3.12)
arel-helpers (2.16.0)
activerecord (>= 3.1.0, < 8.1)
arel-helpers (2.17.0)
activerecord (>= 3.1.0)
ast (2.4.3)
aws-eventstream (1.3.2)
aws-partitions (1.1065.0)
Expand Down Expand Up @@ -225,7 +224,6 @@ GEM
cookiejar (0.3.4)
crass (1.0.6)
csv (3.3.2)
daemons (1.4.1)
date (3.4.1)
debug (1.11.0)
irb (~> 1.10)
Expand Down Expand Up @@ -324,14 +322,14 @@ GEM
lru_redux (1.1.0)
memory_profiler (1.1.0)
metasm (1.0.5)
metasploit-concern (5.0.5)
activemodel (~> 7.0)
activesupport (~> 7.0)
metasploit-concern (5.0.6)
activemodel (>= 7.0, < 8.1)
activesupport (>= 7.0, < 8.1)
drb
mutex_m
railties (~> 7.0)
railties (>= 7.0, < 8.1)
zeitwerk
metasploit-credential (6.0.21)
metasploit-credential (6.0.22)
bigdecimal
csv
drb
Expand All @@ -345,25 +343,25 @@ GEM
rex-socket
rubyntlm
rubyzip (< 3.0.0)
metasploit-model (5.0.4)
activemodel (~> 7.0)
activesupport (~> 7.0)
metasploit-model (5.0.5)
activemodel (>= 7.0, < 8.1)
activesupport (>= 7.0, < 8.1)
bigdecimal
drb
mutex_m
railties (~> 7.0)
railties (>= 7.0, < 8.1)
metasploit-payloads (2.0.245)
metasploit_data_models (6.0.15)
activerecord (~> 7.0)
activesupport (~> 7.0)
metasploit_data_models (6.0.16)
activerecord (>= 7.0, < 8.1)
activesupport (>= 7.0, < 8.1)
arel-helpers
bigdecimal
drb
metasploit-concern
metasploit-model (~> 5.0.4)
metasploit-model (>= 5.0.4)
mutex_m
pg
railties (~> 7.0)
railties (>= 7.0, < 8.1)
recog
webrick
metasploit_payloads-mettle (1.0.46)
Expand Down Expand Up @@ -435,38 +433,40 @@ GEM
pry-byebug (3.11.0)
byebug (~> 12.0)
pry (>= 0.13, < 0.16)
psych (5.2.6)
psych (5.3.1)
date
stringio
public_suffix (6.0.2)
puma (6.6.0)
nio4r (~> 2.0)
racc (1.8.1)
rack (2.2.19)
rack-protection (3.2.0)
rack (3.2.6)
rack-protection (4.2.1)
base64 (>= 0.1.0)
rack (~> 2.2, >= 2.2.4)
rack-session (1.0.2)
rack (< 3)
logger (>= 1.6.0)
rack (>= 3.0.0, < 4)
rack-session (2.1.2)
base64 (>= 0.1.0)
rack (>= 3.0.0)
rack-test (2.2.0)
rack (>= 1.3)
rackup (1.0.1)
rack (< 3)
webrick
rackup (2.3.1)
rack (>= 3)
rails-dom-testing (2.3.0)
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.6.2)
loofah (~> 2.21)
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
railties (7.2.2.2)
actionpack (= 7.2.2.2)
activesupport (= 7.2.2.2)
railties (8.0.5)
actionpack (= 8.0.5)
activesupport (= 8.0.5)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
thor (~> 1.0, >= 1.2.2)
tsort (>= 0.2)
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.3.0)
Expand Down Expand Up @@ -611,10 +611,12 @@ GEM
simplecov-html (~> 0.11)
simplecov-html (0.13.1)
simpleidn (0.2.3)
sinatra (3.2.0)
sinatra (4.2.1)
logger (>= 1.6.0)
mustermann (~> 3.0)
rack (~> 2.2, >= 2.2.4)
rack-protection (= 3.2.0)
rack (>= 3.0.0, < 4)
rack-protection (= 4.2.1)
rack-session (>= 2.0.0, < 3)
tilt (~> 2.0)
sqlite3 (1.7.3)
mini_portile2 (~> 2.8.0)
Expand All @@ -625,10 +627,6 @@ GEM
syslog (0.3.0)
logger
test-prof (1.4.4)
thin (1.8.2)
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0, >= 1.0.4)
rack (>= 1, < 3)
thor (1.4.0)
tilt (2.6.0)
timecop (0.9.10)
Expand All @@ -646,6 +644,7 @@ GEM
unicode-emoji (~> 4.1)
unicode-emoji (4.1.0)
unix-crypt (1.3.1)
uri (1.1.1)
useragent (0.16.11)
warden (1.2.9)
rack (>= 2.0.9)
Expand All @@ -667,9 +666,9 @@ GEM
rexml (~> 3.0)
rubyntlm (~> 0.6.0, >= 0.6.3)
with_env (1.1.0)
xdr (3.0.3)
activemodel (>= 4.2, < 8.0)
activesupport (>= 4.2, < 8.0)
xdr (3.0.1)
activemodel (>= 5.2.0)
activesupport (>= 5.2.0)
xml-simple (1.1.9)
rexml
xmlrpc (0.3.3)
Expand Down
48 changes: 32 additions & 16 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,30 @@
require File.expand_path('../boot', __FILE__)

require 'action_view'
# Monkey patch https://github.com/rails/rails/blob/v7.2.2.1/actionview/lib/action_view/helpers/tag_helper.rb#L51
# Might be fixed by 8.x https://github.com/rails/rails/blob/v8.0.2/actionview/lib/action_view/helpers/tag_helper.rb#L51C1-L52C1
raise unless ActionView::VERSION::STRING == '7.2.2.2' # A developer will need to ensure this is still required when bumping rails
module ActionView::Helpers::TagHelper
class TagBuilder
def self.define_element(name, code_generator:, method_name: name.to_s.underscore)
code_generator.define_cached_method(method_name, namespace: :tag_builder) do |batch|
# Fixing a bug introduced by Metasploit's global Kernel patch: https://github.com/rapid7/metasploit-framework/blob/ae1db09f32cd04c007dbf445cf16dc22c9fc2e53/lib/rex.rb#L74-L79
# which fails when using the below 'instance_methods.include?(method_name.to_sym)' check
batch.push(<<~RUBY) # unless instance_methods.include?(method_name.to_sym)
def #{method_name}(content = nil, escape: true, **options, &block)
tag_string("#{name}", content, options, escape: escape, &block)
end
RUBY
# Monkey patch for ActionView::Helpers::TagHelper::TagBuilder.define_element
#
# Metasploit's global Kernel patch (lib/rex.rb) overrides Kernel#select and Kernel#sleep.
# ActionView's define_element checks whether a method already exists before defining HTML
# element helpers (e.g. :select). Because Kernel#select is in the ancestor chain, the check
# returns true and the :select element helper is never defined, breaking tag.select().
#
# Rails 7.2.x uses `instance_methods.include?(method_name.to_sym)` — affected.
# Rails 8.0.x uses `return if method_defined?(name)` — also affected, since method_defined?
# checks the ancestor chain including Kernel.
#
# See: https://github.com/rapid7/metasploit-framework/blob/ae1db09f32cd04c007dbf445cf16dc22c9fc2e53/lib/rex.rb#L74-L79
if ActionView::VERSION::MAJOR == 8
# Rails 8.0.x patch: override define_element to skip the method_defined? guard
# https://github.com/rails/rails/blob/v8.0.5/actionview/lib/action_view/helpers/tag_helper.rb#L51
module ActionView::Helpers::TagHelper
class TagBuilder
def self.define_element(name, code_generator:, method_name: name)
code_generator.class_eval do |batch|
batch << "\n" <<
"def #{method_name}(content = nil, escape: true, **options, &block)" <<
" tag_string(#{name.inspect}, content, options, escape: escape, &block)" <<
"end"
Comment on lines +26 to +30
end
end
end
end
Expand Down Expand Up @@ -59,9 +69,15 @@ class Application < Rails::Application

config.paths['log'] = "#{Msf::Config.log_directory}/#{Rails.env}.log"
config.paths['config/database'] = [Metasploit::Framework::Database.configurations_pathname.try(:to_path)]
config.autoloader = :zeitwerk

config.load_defaults 7.2
# Rails 8.0 upgrade: changed from 'config.load_defaults 7.2'.
# Activates Rails 8.0 framework defaults including:
# - config.active_support.to_time_preserves_timezone = :zone
# - config.active_record.default_column_serializer = nil
# - config.active_record.run_after_transaction_callbacks_in_order_defined = true
# The config.autoloader = :zeitwerk line was also removed here because
# Zeitwerk is the only autoloader in Rails 8 — the setting no longer exists.
config.load_defaults 8.0

config.eager_load = false
end
Expand Down
4 changes: 2 additions & 2 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.2].define(version: 2026_01_30_124052) do
ActiveRecord::Schema[8.0].define(version: 2026_01_30_124052) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
enable_extension "pg_catalog.plpgsql"

create_table "api_keys", id: :serial, force: :cascade do |t|
t.text "token"
Expand Down
6 changes: 5 additions & 1 deletion lib/metasploit/framework/rails_version_constraint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
module Metasploit
module Framework
module RailsVersionConstraint
RAILS_VERSION = '~> 7.2.0'
# Rails 8.0 upgrade: changed from '~> 7.2.0' to '~> 8.0.0'.
# This constant is used in metasploit-framework.gemspec to pin activerecord,
# activesupport, and actionpack. Rails 8.0 requires Rack 3.x and Zeitwerk-only
# autoloading, which drove the broader upgrade across all supporting gems.
RAILS_VERSION = '~> 8.0.0'
end
end
end
3 changes: 2 additions & 1 deletion lib/msf/core/exploit/remote/cert_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,8 @@ def get_cert_policy_oids(cert)
# @param [OpenSSL::X509::Certificate] cert
# @return [String, nil] The SID if it was found, otherwise nil.
def get_cert_msext_sid(cert)
ext = cert.extensions.find { |e| e.oid == Rex::Proto::X509::OID_NTDS_CA_SECURITY_EXT }
# OpenSSL 3.6+ resolves this OID to its registered short name instead of the dotted string
ext = cert.extensions.find { |e| [Rex::Proto::X509::OID_NTDS_CA_SECURITY_EXT, 'ms-ntds-sec-ext'].include?(e.oid) }
return unless ext

ntds_ca_security_ext = Rex::Proto::CryptoAsn1::NtdsCaSecurityExt.parse(ext.value_der)
Expand Down
Loading
Loading