« Back to Blog

Threat Spotlight: Opening Hacker’s Door

By Cylance Threat Guidance Team

Introduction

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.

Impact

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

Components

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.

Dropper

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

Backdoor

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

Rootkit

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.

IOCTLs

Patch IPFILTERDRIVER (0x4322A0E0)

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_BLOCKOFROUTES and 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.

Conclusions

“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)

Overview

Path
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) 

Service
PowerFucker
Kifes

Event
Hkdoorevt
Doorneedshut

Mutex
Global\SystemTime0
Global\SystemTime2
Global\SystemTime3

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, 1.3.6.1.4.1.311.2.1.22
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.)
EKSYS CORP
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
561c25694083b96d3912b3096bc2e9f35ee84a1850ac2297ff6e2cac849dd670
201c8572bbf19bf3327484e902e23a07fdd305f74e2c70282c3aa805006e4e41
284d8e8bcb9d1830cf37669f481d4e989244c5b6ba5e56f44a32d6006a117692
350df85f82048b259161f1786d42868a1ef7e23909bd3eb6949133dfc3e6093d
40039571d9a5c2c3f2ca44a05523dfb028793758787006f8fef87244adb178fd
6204fc88f6a4653d164b4be8b9654e2a98dc487adf42df91f3ec71de5db058f7
6f285afee1eac45c1aaad9e7d49e99a1cd2f399b12f7997d9fc8b5200b385fc6
87a73c5a4c0ff06d69fb6ad62894223543c455fdf6916ccf953fddd486546e9d
89d2d7e1e441dc20b4a967aa00423da33bce68a55cf0e855e8d9ba3e6c5cbd72
91d8009c116c4cbfcf0c540084912e76587abdfa0b64facba85aa4418b2a3556
a549d66df72ddfb85fd676abea3c136e621a239c301dada7817e7d269e99a8fb
acb509aca4a1d81b380bf8224ae0febb1b985573df0e495806833d1c0e5187c3
dd2acdac10324ff4896003c651813c3caef891ef89c889ea00cf4c43e479f169
e59b310502b0750f0c45e55313a3ab9fb76567cc51a5c344696e97f4b396dde9
f49f2a6b8447b809cb1e90135d08c81af671202426e8fe1688a90c1d78708b46
954edcb9274a4b4a5d07352582b4d0f2012520d29cb2930f0213e5162f180d2c

SHA256 - Backdoor
d696008c0a8fa5942f320c46b57a8ec4502a9b2f42fee290e0f8d7ad8b48832d
bfd4717af84d918d5abbaddb0d561306664d13f7ebba30c26a7626b1637d299f
35f0d4ea4d9cce586a33f31631d8e3c91e294bbee5c5c8445652389e9d00c4bc
d8678e2cafc4130e1919cec36ef5cb9b0b3124c246723b8e013eecb015acda5d
aa0df754ada7387e08bd70b024d389dabd3c8aa4a60b7792ef48e60221907d11
e7b126385fe7c63568914400faca1b940cf584a83fa4730acbcaa77054c4182b
b299f5cab019c63421993db69cc2dbca676db551eb40f5b5d13dc49d841fcff6

SHA256 - Rootkit
f4b88f201ef380ccfd97a190ad9eaec168c99d501012baffd542e0758fa373e3

YARA

import "pe"

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

    strings:
        $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 http://www.yythac.com" fullword ascii
        $s5 = "SeLoadDriverPrivilege" fullword ascii

    condition:
        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 {
   meta:
      description = "Hacker's Door Backdoor"

   strings:
      $s1 = "http://www.yythac.com" fullword ascii
      $s2 = "Example:%s 192.168.1.100 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 = "http://www.yythac.com/images/mm.jpg" fullword ascii
      $s7 = "I'mhackeryythac1977" fullword ascii
      $s8 = "yythac.yeah.net" fullword ascii

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

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

    strings:
        $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 http://www.yythac.com" fullword ascii
        $s5 = "SeLoadDriverPrivilege" fullword ascii
        $s6 = "\\drivers\\ntfs.sys" fullword ascii
        $s7 = "kifes" fullword ascii

    condition:
        uint16(0) == 0x5a4d and
        filesize < 1000KB and
        ( 4 of ($s*) ) and
        pe.number_of_resources > 0 and
        for any i in (0..pe.number_of_resources - 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 {
    meta:
        description = "Hacker’s Door Driver"

    strings:
        $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}

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

}

SNORT

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;)

References

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

https://translate.google.com/translate?sl=zh-CN&tl=en&js=y&prev=_t&hl=en&ie=UTF-8&u=http%3A%2F%2Fwww.yythac.com%2Fpost%2F%25E9%25BB%2591%25E5%25AE%25A2%25E4%25B9%258B%25E9%2597%25A8

https://translate.google.com/translate?hl=en&sl=zh-CN&tl=en&u=http%3A%2F%2Fwww.yythac.com%2Fothers%2Freadme.txt

About the Cylance Threat Guidance Team

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

Tags: