2020-07-07 13:46:41 +01:00
# -*- coding: binary -*-
# frozen_string_literal: true
2022-08-08 01:40:15 +01:00
require 'rex/text'
2020-07-07 13:46:41 +01:00
module Msf
###
#
# The feature manager is responsible for managing feature flags that can change characteristics of framework.
2020-07-15 20:59:17 +01:00
# Each feature will have a default value. The user can choose to override this default value if they wish.
2020-07-07 13:46:41 +01:00
###
class FeatureManager
2020-07-15 20:59:17 +01:00
include Singleton
2020-07-07 13:46:41 +01:00
2020-07-15 20:59:17 +01:00
CONFIG_KEY = 'framework/features'
2020-07-07 13:46:41 +01:00
WRAPPED_TABLES = 'wrapped_tables'
2022-08-08 01:40:15 +01:00
DATASTORE_FALLBACKS = 'datastore_fallbacks'
2021-08-06 13:57:59 +01:00
FULLY_INTERACTIVE_SHELLS = 'fully_interactive_shells'
2023-07-27 12:02:00 +01:00
MANAGER_COMMANDS = 'manager_commands'
2023-09-27 11:20:17 +01:00
METASPLOIT_PAYLOAD_WARNINGS = 'metasploit_payload_warnings'
2023-03-24 14:00:05 +00:00
DEFER_MODULE_LOADS = 'defer_module_loads'
2024-03-12 09:33:27 -04:00
DNS = 'dns'
2023-11-28 13:14:13 +00:00
HIERARCHICAL_SEARCH_TABLE = 'hierarchical_search_table'
2023-11-14 18:20:14 +00:00
SMB_SESSION_TYPE = 'smb_session_type'
2023-09-19 10:35:51 +01:00
POSTGRESQL_SESSION_TYPE = 'postgresql_session_type'
2024-01-17 15:35:47 +00:00
MYSQL_SESSION_TYPE = 'mysql_session_type'
2023-12-12 09:53:37 -06:00
MSSQL_SESSION_TYPE = 'mssql_session_type'
2020-07-07 13:46:41 +01:00
DEFAULTS = [
{
2021-01-28 10:24:01 +00:00
name : WRAPPED_TABLES ,
2020-07-07 13:46:41 +01:00
description : 'When enabled Metasploit will wordwrap all tables to fit into the available terminal width' ,
2023-12-04 17:17:28 +00:00
default_value : true ,
developer_notes : 'This functionality is enabled by default now, and the feature flag can be removed now'
2021-08-06 13:57:59 +01:00
} . freeze ,
{
name : FULLY_INTERACTIVE_SHELLS ,
description : 'When enabled you will have the option to drop into a fully interactive shell from within meterpreter' ,
2023-12-04 17:17:28 +00:00
default_value : false ,
developer_notes : 'Development paused as the interaction time feels clunky, especially for slow transport layers like HTTP on Mettle. Would require changes to the transport sleep/priority logic'
2022-03-04 12:41:24 +00:00
} . freeze ,
{
2023-07-27 12:02:00 +01:00
name : MANAGER_COMMANDS ,
description : 'When enabled you will have access to manager commands such as _servicemanager and _historymanager' ,
2023-12-04 17:17:28 +00:00
default_value : false ,
developer_notes : 'Useful for developers, likely not to ever be useful for an average user'
2022-08-08 01:40:15 +01:00
} . freeze ,
{
name : DATASTORE_FALLBACKS ,
description : 'When enabled you can consistently set username across modules, instead of setting SMBUser/FTPUser/BIND_DN/etc' ,
requires_restart : true ,
2023-12-04 17:17:28 +00:00
default_value : true ,
developer_notes : 'This functionality is enabled by default now, and the feature flag can be removed now'
2023-09-27 11:20:17 +01:00
} . freeze ,
{
name : METASPLOIT_PAYLOAD_WARNINGS ,
description : 'When enabled Metasploit will output warnings about missing Metasploit payloads, for instance if they were removed by antivirus etc' ,
requires_restart : true ,
2023-12-08 16:24:31 +00:00
default_value : true ,
2024-03-12 21:12:31 +00:00
developer_notes : 'Enabled in Metasploit 6.4.x'
2023-03-24 14:00:05 +00:00
} . freeze ,
{
name : DEFER_MODULE_LOADS ,
description : 'When enabled will not eagerly load all modules' ,
requires_restart : true ,
2023-12-04 17:17:28 +00:00
default_value : false ,
2024-03-12 21:12:31 +00:00
developer_notes : 'Needs a final round of testing. Can be enabled after 6.4.0 is released.'
2023-11-02 19:44:04 +11:00
} . freeze ,
2023-11-14 18:20:14 +00:00
{
name : SMB_SESSION_TYPE ,
description : 'When enabled will allow for the creation/use of smb sessions' ,
requires_restart : true ,
2024-03-12 21:12:31 +00:00
default_value : true ,
developer_notes : 'Enabled in Metasploit 6.4.x'
2023-11-14 18:20:14 +00:00
} . freeze ,
2023-09-19 10:35:51 +01:00
{
name : POSTGRESQL_SESSION_TYPE ,
description : 'When enabled will allow for the creation/use of PostgreSQL sessions' ,
requires_restart : true ,
2024-03-12 21:12:31 +00:00
default_value : true ,
developer_notes : 'Enabled in Metasploit 6.4.x'
2024-01-17 15:35:47 +00:00
} . freeze ,
{
name : MYSQL_SESSION_TYPE ,
description : 'When enabled will allow for the creation/use of MySQL sessions' ,
requires_restart : true ,
2024-03-12 21:12:31 +00:00
default_value : true ,
developer_notes : 'Enabled in Metasploit 6.4.x'
2023-09-19 10:35:51 +01:00
} . freeze ,
2023-12-12 09:53:37 -06:00
{
name : MSSQL_SESSION_TYPE ,
description : 'When enabled will allow for the creation/use of mssql sessions' ,
requires_restart : true ,
2024-03-12 21:12:31 +00:00
default_value : true ,
developer_notes : 'Enabled in Metasploit 6.4.x'
2023-12-12 09:53:37 -06:00
} . freeze ,
2023-11-02 19:44:04 +11:00
{
2024-03-12 09:33:27 -04:00
name : DNS ,
description : 'When enabled allows configuration of DNS resolution behaviour in Metasploit' ,
requires_restart : true ,
2024-03-12 21:12:31 +00:00
default_value : true ,
developer_notes : 'Enabled in Metasploit 6.4.x'
2023-11-28 13:14:13 +00:00
} . freeze ,
{
name : HIERARCHICAL_SEARCH_TABLE ,
2024-03-12 09:33:27 -04:00
description : 'When enabled the search table is enhanced to show details on module actions and targets' ,
2023-11-28 13:14:13 +00:00
requires_restart : false ,
2024-03-12 21:12:31 +00:00
default_value : true ,
developer_notes : 'Enabled in Metasploit 6.4.x'
2020-07-07 13:46:41 +01:00
} . freeze
] . freeze
#
# Initializes the feature manager.
#
2020-07-15 20:59:17 +01:00
def initialize
2020-07-07 13:46:41 +01:00
@flag_lookup = DEFAULTS . each_with_object ( { } ) do | feature , acc |
2021-01-28 10:24:01 +00:00
if feature [ :name ] == WRAPPED_TABLES
if feature [ :default_value ] == true
Rex :: Text :: Table . wrap_tables!
else
Rex :: Text :: Table . unwrap_tables!
end
end
2020-07-07 13:46:41 +01:00
key = feature [ :name ]
acc [ key ] = feature . dup
end
end
def all
2020-07-15 20:59:17 +01:00
@flag_lookup . values . map do | feature |
feature . slice ( :name , :description ) . merge ( enabled : enabled? ( feature [ :name ] ) )
end
2020-07-07 13:46:41 +01:00
end
2022-08-08 01:40:15 +01:00
# @param [String] name The feature name
# @return [TrueClass,FalseClass] True if the flag is be enabled, false otherwise
2020-07-07 13:46:41 +01:00
def enabled? ( name )
return false unless @flag_lookup [ name ]
2020-07-15 20:59:17 +01:00
feature = @flag_lookup [ name ]
feature . key? ( :user_preference ) ? feature [ :user_preference ] : feature [ :default_value ]
2020-07-07 13:46:41 +01:00
end
2022-08-08 01:40:15 +01:00
# @param [String] name The feature name
# @return [TrueClass,FalseClass] True if the flag requires a console restart to work effectively
def requires_restart? ( name )
return false unless @flag_lookup [ name ]
@flag_lookup [ name ] [ :requires_restart ] == true
end
2020-07-07 13:46:41 +01:00
def exists? ( name )
@flag_lookup . key? ( name )
end
def names
all . map { | feature | feature [ :name ] }
end
def set ( name , value )
return false unless @flag_lookup [ name ]
2020-07-15 20:59:17 +01:00
@flag_lookup [ name ] [ :user_preference ] = value
2020-07-07 13:46:41 +01:00
2021-08-17 17:17:42 +01:00
if name == WRAPPED_TABLES
2020-07-07 13:46:41 +01:00
if value
Rex :: Text :: Table . wrap_tables!
else
Rex :: Text :: Table . unwrap_tables!
end
end
end
2020-07-15 20:59:17 +01:00
def load_config
conf = Msf :: Config . load
conf . fetch ( CONFIG_KEY , { } ) . each do | name , value |
set ( name , value == 'true' )
end
end
def save_config
# Note, we intentionally omit features that have not explicitly been set by the user.
config = Msf :: Config . load
old_config = config . fetch ( CONFIG_KEY , { } )
new_config = @flag_lookup . values . each_with_object ( old_config ) do | feature , config |
next unless feature . key? ( :user_preference )
config . merge! ( feature [ :name ] = > feature [ :user_preference ] . to_s )
end
Msf :: Config . save ( CONFIG_KEY = > new_config )
end
2020-07-07 13:46:41 +01:00
end
end