add OptTimedelta datastore option and remove Kerberos-specific clock skew parsing

This commit is contained in:
Nayeraneru
2026-02-20 22:28:05 +02:00
parent 2289e889be
commit ce2e23ccef
6 changed files with 109 additions and 10 deletions
@@ -1,6 +1,6 @@
# -*- coding: binary -*-
require 'msf/core/exploit/remote/kerberos/clock_skew'
require 'msf/core/opt_timedelta'
module Msf
class Exploit
@@ -45,8 +45,7 @@ module Msf
register_advanced_options(
[
OptString.new('KrbClockSkew', [true, 'Adjust Kerberos client clock by this offset (e.g. 90s, -5m, 1h)', '0s'],
regex: Msf::Exploit::Remote::Kerberos::ClockSkew::CLOCK_SKEW_REGEX)
OptTimedelta.new('KrbClockSkew', [true, 'Adjust Kerberos client clock by this offset (e.g. 90s, -5m, 1h)', '0s'])
], self.class
)
end
@@ -90,7 +89,7 @@ module Msf
#
# @param value [String, Numeric, nil]
def kerberos_clock_skew=(value)
@kerberos_clock_skew = Msf::Exploit::Remote::Kerberos::ClockSkew.parse(value)
@kerberos_clock_skew = Msf::OptTimedelta.parse(value)
end
# Returns the current time adjusted for Kerberos clock skew in UTC.
@@ -3,7 +3,7 @@
#
# This class stores Metasploit option configuration used across service authentication
#
require 'msf/core/exploit/remote/kerberos/clock_skew'
require 'msf/core/opt_timedelta'
module Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Options
# Create the list of options that a module must provide for Kerberos authentication via the given protocol
@@ -38,10 +38,9 @@ module Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Options
fallbacks: ['Rhostname'],
conditions: option_conditions
),
Msf::OptString.new(
Msf::OptTimedelta.new(
'KrbClockSkew',
[true, 'Adjust Kerberos client clock by this offset (e.g. 90s, -5m, 1h)', '0s'],
regex: Msf::Exploit::Remote::Kerberos::ClockSkew::CLOCK_SKEW_REGEX,
conditions: option_conditions
),
Msf::OptAddress.new(
@@ -66,6 +65,6 @@ module Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Options
#
# @return [Float]
def kerberos_clock_skew_seconds
Msf::Exploit::Remote::Kerberos::ClockSkew.parse(datastore['KrbClockSkew'])
Msf::OptTimedelta.parse(datastore['KrbClockSkew'])
end
end
+64
View File
@@ -0,0 +1,64 @@
# frozen_string_literal: true
# -*- coding: binary -*-
module Msf
class OptTimedelta < OptBase
TIMEDELTA_REGEX = /\A([+-]?\d+(?:\.\d+)?(?:[smhd])?)+\z/i.freeze
UNIT_IN_SECONDS = {
's' => 1,
'm' => 60,
'h' => 3_600,
'd' => 86_400
}.freeze
attr_reader :allow_negative
def initialize(in_name, attrs = [], allow_negative: true, **kwargs)
super(in_name, attrs, **kwargs)
@allow_negative = allow_negative
end
def type
'timedelta'
end
def normalize(value)
self.class.parse(value)
end
def valid?(value, check_empty: true, datastore: nil)
return false if check_empty && empty_required_value?(value)
begin
parsed_value = self.class.parse(value)
rescue Msf::OptionValidateError
return false
end
return false if !allow_negative && parsed_value.negative?
super
end
def self.parse(value)
return 0 if value.nil?
return value.to_f if value.is_a?(Numeric)
trimmed_value = value.to_s.strip
return 0 if trimmed_value.empty?
return trimmed_value.to_f if trimmed_value.match?(/\A[+-]?\d+(?:\.\d+)?\z/)
raise Msf::OptionValidateError.new([], message: 'Invalid timedelta format') unless trimmed_value.match?(TIMEDELTA_REGEX)
total = 0
trimmed_value.scan(/([+-]?\d+(?:\.\d+)?)([smhd]?)/i) do |amount, unit|
unit = 's' if unit.blank?
multiplier = UNIT_IN_SECONDS[unit.downcase]
total += amount.to_f * multiplier
end
total
end
end
end
+2 -2
View File
@@ -3,7 +3,7 @@ require 'rex/proto/mssql/client_mixin'
require 'rex/text'
require 'msf/core/exploit'
require 'msf/core/exploit/remote'
require 'msf/core/exploit/remote/kerberos/clock_skew'
require 'msf/core/opt_timedelta'
module Rex
module Proto
@@ -389,7 +389,7 @@ module Rex
framework: framework,
framework_module: framework_module,
ticket_storage: Msf::Exploit::Remote::Kerberos::Ticket::Storage::WriteOnly.new(framework: framework, framework_module: framework_module),
clock_skew: Msf::Exploit::Remote::Kerberos::ClockSkew.parse(framework_module.datastore['KrbClockSkew'])
clock_skew: Msf::OptTimedelta.parse(framework_module.datastore['KrbClockSkew'])
)
kerberos_result = kerberos_authenticator.authenticate
@@ -11,6 +11,13 @@ RSpec.describe Msf::Exploit::Remote::Kerberos::Client do
mod
end
describe 'KrbClockSkew option' do
it 'is registered as an OptTimedelta datastore option' do
expect(subject.options['KrbClockSkew']).to be_a(Msf::OptTimedelta)
end
end
describe '#kerberos_clock_skew' do
it 'defaults to zero' do
expect(subject.kerberos_clock_skew).to eq(0)
+30
View File
@@ -0,0 +1,30 @@
# -*- coding:binary -*-
require 'spec_helper'
RSpec.describe Msf::OptTimedelta do
valid_values = [
{ value: '120', normalized: 120.0 },
{ value: '-5m', normalized: -300.0 },
{ value: '1h30m', normalized: 5_400.0 },
{ value: '2d', normalized: 172_800.0 },
{ value: '+1.5h', normalized: 5_400.0 }
]
invalid_values = [
{ value: 'yolo' },
{ value: '1w' },
{ value: '5mfoo' }
]
it_behaves_like 'an option', valid_values, invalid_values, 'timedelta'
describe '#valid?' do
it 'can enforce positive-only values' do
subject = described_class.new('Duration', [true, 'Duration'], allow_negative: false)
expect(subject.valid?('5m')).to be(true)
expect(subject.valid?('-5m')).to be(false)
end
end
end