Skip Navigation
BlackBerry Blog

Threat Spotlight: Opening Hacker’s Door


During a recent compromise assessment, Cylance incident responders and threat researchers uncovered a surreptitious and sophisticated remote access trojan (RAT) that had been planted and operated by the suspected threat actor. Upon further inspection, the RAT appeared to share many similarities with an old Chinese backdoor known as “Hacker’s Door”, first released publicly in 2004 and updated in 2005.

Hacker’s Door is now sold privately by the original author (yyt_hac) with updates to support newer Operating Systems and architectures. It is likely that the analyzed samples were created using the private version, as they are designed to run on modern 64-bit systems, although they could have been built based on sold, leaked or stolen source code.


The RAT comprises a backdoor and rootkit component, and once active allows for a typical set of remote commands, including:

  • Gathering system information
  • Grabbing screenshots and files
  • Downloading additional files
  • Running other processes and commands
  • Listing and killing processes
  • Opening Telnet and RDP servers
  • Extracting Windows credentials from the current session

The sample of “Hacker’s Door” analyzed by Cylance was signed with a stolen certificate, known to be used by the Winnti APT group. Its discovery within an environment is a clear indication of a broader compromise.

Technical Analysis


The malware consists of a dropper that contains an embedded DLL in its resource section. The DLL is the main backdoor payload that also drops an additional rootkit driver that is used for covert communications:

All dropped files are time-stomped using the MAC time copied from %WINDIR%\hh.exe.


The dropper extracts the backdoor DLL from a resource named BIN/100 and writes it to %windir%\system32\pifngr.dll. Next it copies itself to %windir%\system32\pifmgr.exe and creates a service that will run it on each boot. When run with the “/o” parameter, the malware will create a separate instance of itself that will load the dropped binary and start the backdoor.

Command Line Parameters

Figure 1. Dropper - Strings


The DLL is the main backdoor payload. It is responsible for opening a channel for communication with the rootkit driver and awaiting commands and executing them. It creates two threads, one responsible for installation of the embedded driver, the other for processing the commands. If the DLL detects that it was loaded by rundll32.exe, or if the mutex "Global\SystemTime3" exists, the installation will be skipped, and only the command processing thread will be executed.

Most of the sensitive strings inside the DLL are encoded using a substitution cipher comprising the following alphabet:

Figure 2. Substitution Alphabet

Throughout execution, if the Global\SystemTime2 mutex is present, then the backdoor will log messages to c:\system.txt.

Installation Thread Workflow

  • Determines if it is already running by checking for a mutex named Global\SystemTime0, and if so, logs the message "Can't start hkdr,maybe it already run!" and terminates.
  • Creates the mutex Global\SystemTime0.
  • Creates a thread that will loop checking if the hkdoorevt event exists, and if so, terminates.
  • Logs the message "Begin to start hacker's door....".
  • Tries to start the IPFILTERDRIVER service. If this fails, it logs the message "Can't start net work driver".


Figure 3. Backdoor – Starting IPFILTERDRIVER Service

  • Tries to open a service named "kifes". If it exists, the service will be stopped and deleted and the process will terminate.
  • Finds a resource containing the DES encrypted backdoor communication password (RT_STRING/1):

Figure 4. Backdoor – Finding the Resource That Contains Communication Password

  • Checks if the mutex Global\SystemTime2 exists. If so, the backdoor will log debug messages to C:\system.txt.
  • Checks and logs the Operating System version
  • Drops the encrypted driver from resource FILE/101 to %SYSTEM%\drivers\kifesEn.sys
  • Decrypts the driver to %SYSTEM%\drivers\kifes.sys using the 3DES algorithm with an initial key "I'mhackeryythac1977" hardcoded in plain-text inside the binary:

Figure 5. Backdoor – Hardcoded DES Password Used to Decrypt the Driver

Figure 6. Backdoor - Decrypting the Driver

  • Loads the kifes.sys driver and sends an initial IOCTL code of 0x4322A0E0, which will result in the driver hooking the IPFILTERDRIVER device:


Figure 7. Backdoor - Calling the Driver’s Hooking Routine

  • Deletes the kifes.sys file and copies ntfs.sys to kifes.sys. This is used to mask the presence of the driver and hinder forensic analysis.

Figure 8. Backdoor – Overwriting Malicious Driver With ntfs.sys

  • Sends IOCTL 0x4322A0DC. There is no handler for this command inside the kifes.sys driver, but judging from a debug string that is written to the log file in case of failure, it seems it is related to rootkit functionality that is not implemented in this version of the driver:


Figure 9. Backdoor – Invoking the Driver’s Hiding Routine (Unimplemented in the Analyzed Version of the Driver)

  • Sends IOCTL 0x432220D8 to initialize the internal structures that will store backdoor traffic
  • Patches the SERVICE_RECORD structure to hide the PowerFucker service from the list of running services. Uses a byte pattern to find the structure in the memory of services.exe process:

Figure 10. Backdoor - Scanning Memory for SERVICE_RECORD Structure

The memory patching methods support systems up to Windows 8.1.

Figure 11. Patching Memory to Hide the Malicious Service

  • Sends IOCTL 0x432220C4 to set the backdoor session password. The session password is obtained from the DES-encrypted resource RT_STRING/1. In cases where no password was provided as a resource, the default session password will be set to the hardcoded string “hkdoorpass”. Before setting, the password is encoded with the same substitution cipher used for string encoding.

Figure 12. Backdoor – Decrypting the Communication Password from the Resource

  • Sends IOCTL 0x432220D0 to set the login event.
  • If successful, logs the message "Start hacker's door successfully!"
  • The thread then waits in a loop for an event with the same name as the hardcoded password, and if set, uninstalls itself from the system.

Command Processor Thread Workflow

  • Creates the backdoor communication routine that will await commands and process them.
  • The attacker needs to provide a valid password, which is then checked against the string stored in resource RT_STRING/1.
  • Upon successful authentication, the backdoor will display the following message to the attacker:
    "Welcome back,Master!n Use '?' to get Help", followed by the command prompt "Control>”.

Figure 13. Backdoor’s Welcome Message

Backdoor Commands

The list of supported backdoor commands and descriptions is almost the same as listed on the developer's website, with the addition of two commands, copyscreen and setinterval:

Figure 14: The List of Supported Backdoor Commands and Descriptions

Figure 15. Backdoor - Hardcoded Command Descriptions


The kernel mode component is stored as a 3DES encrypted resource named FILE/101 inside the DLL, and dropped in encrypted form to %SYSTEM%\drivers\kifesEn.sys during the installation process. The backdoor then decrypts it to %SYSTEM%\drivers\kifes.sys using a hardcoded key "I'mhackeryythac1977" and loads the driver as a service.

Figure 16. Malicious Driver in Memory

After the driver is loaded into memory, the backdoor will overwrite kifes.sys with the contents of ntfs.sys to hinder forensic analysis.

Figure 17: DriverView, kifes.sys "Appears" Legitimate, But it’s Really a Copy of ntfs.sys

The backdoor communicates with the driver by sending input/output control (IOCTL) codes that are handled by a dispatcher routine inside the driver.

Figure 18. Driver -  IOCTL Dispatch Routine

Once the driver is loaded, the backdoor will first request it to set a hook in the IPFILTERDRIVER device. The hook routine will scan all the incoming network packets and redirect the relevant traffic to the backdoor.

Such an approach, in which the backdoor is not bound to listen on a specific port, allows the attackers to connect to the backdoor on any port that is currently open on the victim's machine, and therefore bypass the firewall.

Once the hook is in place, the backdoor can receive and process commands. The responses are sent via raw sockets with the use of the sendto API.



Upon receiving this IOCTL code the driver will hook the MatchFilter function inside the IPFILTERDRIVER driver (ipfltdrv.sys) by replacing 14 bytes at the beginning of the function with an absolute indirect jump to its own hook routine:

Figure 19. Driver - Patching IPFILTERDRIVER

The appropriate function is located by matching byte patterns:

Figure 20. Driver - Finding the MatchFilter Routine

Figure 21: Memory - Call to ipfltmgr!MatchFilter From ipfltmgr!IpfInboundIpClassifyCallout

Figure 22: Memory - Hook in ipfltmgr!MatchFilter

The hook routine scans incoming network traffic for packets that contain one of the specified login strings, either in plain text or encrypted with the backdoor’s substitution cipher. If the password following the login string matches the backdoor password, or a secret password embedded in the driver “----------“, the packet will be copied to an internal structure and the login event will be set.

Figure 23: Hook Routine

There are 5 different types of login request that the hook routine in IPFILTERDRIVER will respond to:

The login types do not seem to matter in this version of the backdoor, and whilst all are supported, they basically revert to NCLOGIN or CMDLOGIN, depending on whether the password was sent in cleartext or encoded.

Figure 24. Login Strings

Unimplemented (0x4322A0DC)
The analyzed sample did not have a routine to handle this control code. Judging from the debug strings inside the backdoor, this IOCTL was meant to trigger driver hiding functionality.

Initialize (0x432220D8)
This control code is used to initialize internal structures that will be used to store the filtered traffic.

Set login password (0x432220C4)
The handler routine for this control code will replace the default connection password (hardcoded as "hellohaha") with the provided string (which is the password that is stored in an encrypted resource inside the DLL, or "hkdoorpass" in case no password was provided). Then IOCTL_IP_SET_BLOCKOFROUTESand IOCTL_PF_SET_EXTENSION_POINTER IOCTL requests are sent to \\Device\\IPFILTERDRIVER.

Set login event (0x432220D0)
The driver will set an internal event to signal that a proper login packet was found and the backdoor session has been started.

Get current session login information (0x432220D4)
The driver will provide the user-mode component with the login session information.

Set session event (0x432220CC)
The driver will fill in an internal structure with the login session information.

On send (0x432220C0)
Invoked when the backdoor is about to send a response packet; the originally received packet will be removed from the filtered packets list.

On receive (0x4322A0C8)
Invoked when the backdoor receives a packet; the received packet will be copied into the internal structure.


“Hacker’s Door” is an old RAT, largely undocumented, that has seldom been observed in-the-wild. The recent discovery of a new version, updated for modern Operating Systems, signed with a stolen certificate and actively employed as part of an ongoing compromise is interesting, as it once again shows that threat actors are comfortable relying on third-party tools to reduce development time/costs for malware that will likely be uncovered.

Updates to “Hacker’s Door” compared to the last public release clearly show that the project is undergoing active development, and despite the author stating, “please do not use for illegal purposes”, they continue to profit from the sale of this aggressive remote access tool.

It is highly likely that this tool will continue to be uncovered as part of targeted attacks for some time, as the ease of use and advanced functionality makes “Hacker’s Door” the perfect RAT for any adversary’s arsenal. If found within an environment it is highly advised that you arrange for a compromise assessment to determine if there are further signs of attacker activity.  

If you use our endpoint protection product, CylancePROTECT®, you are protected from this attack.

Indicators of Compromise (IoCs)


c:\system.txt (Log File)
%WINDIR%\Temp\system.txt (Log file)
%SYSTEM%\pifngr.dll (Backdoor)
%SYSTEM%\pifmgr.exe (Dropper)
%SYSTEM%\drivers\kifesEn.sys (Rootkit, encrypted)
%SYSTEM%\drivers\kifes.sys (Rootkit, decrypted - later overwritten with NTFS.sys)
kernel.dll (Backdoor, internal name)
acluiw.dll (Backdoor, alternative name)
loadperf.dll (Usermode rootkit)
cryptuit.dll (Backdoor, alternative name)
hkdoordll.dll (original name from the public version) 




Certificate (Expired/Revoked.  Used by Winnti group.)
SG Internet
Valid from 1:00 AM 10/7/2011
Valid to 12:59 AM 10/7/2013
Valid usage Code Signing,
Algorithm SHA1
Thumbprint E71A4CE485EC3B848C03D61231D0B8288B2080A6
Serial number 6E 7C C1 76 06 2D 91 22 5C FD CB DF 5B 5F 0E A5

Certificate (Expired/Revoked.)
Valid from 1:00 AM 6/21/2013
Valid to 12:59 AM 9/20/2016
Valid usage Code Signing
Algorithm SHA1
Thumbprint B42E215E3EA0072B7A38D57DD01EBA3310932F2F
Serial number 1C A4 8C 9A B1 95 DD 38 83 AA 97 60 33 6E 75 C0

SHA256 - Dropper

SHA256 - Backdoor

SHA256 - Rootkit


import "pe"

rule hkdoor_backdoor_dll {
        description = "Hacker’s Door Backdoor DLL"

        $s1 = "The version of personal hacker's door server is" fullword ascii
        $s2 = "The connect back interval is %d (minutes)" fullword ascii
        $s3 = "I'mhackeryythac1977" fullword ascii
        $s4 = "Welcome to" fullword ascii
        $s5 = "SeLoadDriverPrivilege" fullword ascii

        uint16(0) == 0x5a4d and
        filesize < 400KB and
        ( 3 of ($s*) ) and
        pe.characteristics & pe.DLL and
        pe.imports("ws2_32.dll", "WSAStartup") and
        pe.imports("ws2_32.dll", "sendto")

rule hkdoor_backdoor {
      description = "Hacker's Door Backdoor"

      $s1 = "" fullword ascii
      $s2 = "Example:%s 139 -p yyt_hac -t 1" fullword ascii
      $s3 = "password-----------The hacker's door's password" fullword ascii
      $s4 = "It is the client of hacker's door %d.%d public version" fullword ascii
      $s5 = "hkdoordll.dll" fullword ascii
      $s6 = "" fullword ascii
      $s7 = "I'mhackeryythac1977" fullword ascii
      $s8 = "" fullword ascii

      uint16(0) == 0x5a4d and
      filesize < 400KB and
      ( 4 of ($s*) )

rule hkdoor_dropper {
        description = "Hacker’s Door Dropper"

        $s1 = "The version of personal hacker's door server is" fullword ascii
        $s2 = "The connect back interval is %d (minutes)" fullword ascii
        $s3 = "I'mhackeryythac1977" fullword ascii
        $s4 = "Welcome to" fullword ascii
        $s5 = "SeLoadDriverPrivilege" fullword ascii
        $s6 = "\\drivers\\ntfs.sys" fullword ascii
        $s7 = "kifes" fullword ascii

        uint16(0) == 0x5a4d and
        filesize < 1000KB and
        ( 4 of ($s*) ) and
        pe.number_of_resources > 0 and
        for any i in ( - 1):
            (pe.resources[i].type_string == "B\x00I\x00N\x00" and
            uint16(pe.resources[i].offset) == 0x5A4D) and
        pe.imports("KERNEL32.dll", "FindResourceW") and
        pe.imports("KERNEL32.dll", "LoadResource")

rule hkdoor_driver {
        description = "Hacker’s Door Driver"

        $s1 = "ipfltdrv.sys" fullword ascii
        $s2 = "Patch Success." fullword ascii
        $s3 = "\\DosDevices\\kifes" fullword ascii
        $s4 = "\\Device\\kifes" fullword ascii
        $s5 = {75 28 22 36 30 5b 4a 77 7b 58 4d 6c 3f 73 63 5e 38 47 7c 7d 7a 40 3a 41 2a 45 4e 44 79 64 67 6d 65 74 21 39 23 3c 20 49 43 69 4c 3b 31 57 2f 55 3e 26 59 62 61 54 53 5a 2d 25 78 35 5c 76 3d 34 27 6b 5f 72 2c 32 4f 2b 71 66 42 33 37 56 52 60 5d 29 4b 51 2e 6f 50 68 6e 6a 24 48 7e 46 70}

        uint16(0) == 0x5a4d and
        pe.subsystem == pe.SUBSYSTEM_NATIVE and
        ( 4 of ($s*) )



alert tcp any any -> $(HOME_NET) any (msg:"HKDOOR Login attempt"; content:"NCLOGIN hkdoorpass"; flags:AP; sid:10000001;)
alert tcp any any -> $(HOME_NET) any (msg:"HKDOOR Login attempt"; content:"NCLOGIN ----------"; flags:AP; sid:10000002;)
alert tcp any any -> $(HOME_NET) any (msg:"HKDOOR Login attempt"; content:"/91UIi/ussssssssss"; flags:AP; sid:10000003;)
alert tcp any any -> $(HOME_NET) any (msg:"HKDOOR Login attempt"; content:"/91UIi/uq3,``K]kQQ"; flags:AP; sid:10000004;)


The author's original Hacker's Door blogpost and version 1.2 readme (translated from Chinese):

The BlackBerry Cylance Threat Research Team

About The BlackBerry Cylance Threat Research Team

The BlackBerry Cylance Threat Research team examines malware and suspected malware to better identify its abilities, function and attack vectors. Threat Research is on the frontline of information security and often deeply examines malicious software, which puts us in a unique position to discuss never-seen-before threats.