Sep 07, 2026
Unpacking malware: Hancitor
Analysis of a packed sample attributed to the Hancitor loader (also known as Chanitor and Tordal), with unpacking, encrypted configuration extraction, and C2 infrastructure identification.
- family
- Hancitor
Summary
This article documents the analysis of a packed sample attributed to the Hancitor loader (also known as Chanitor and Tordal). The goal was to unpack the sample, extract its encrypted configuration, and identify the command-and-control (C2) infrastructure for correlation with active threats.
The observed chain has two stages: a custom packer that decrypts and executes a payload in memory, and the Hancitor loader itself, whose configuration — encrypted with RC4 in the .data section — contained the build ID and three malicious server gates. The decryption routine matches the publicly known Hancitor scheme (RC4 with a key derived from SHA-1 via CryptoAPI), which supported the attribution.
Unpacking process, configuration extraction, and infrastructure attribution
I received a malicious file for analysis with the goal of understanding more about the attacker’s infrastructure and whether it could be linked to any currently active threat.
First things first, I used the good old architecture overview for the file, which returned the following information: it’s a 32-bit PE binary, written in C, with some identifiable layer of protection.
![Detect It Easy: PE32, GUI, Visual Studio 2022, Generic[No IAT], overlay at 0x00023a00](/images/writeups/unpacked_hancitor/hc-img01.png)
Looks suspicious? We’ll see.
Stage 1 (packer)
The binary has 4 sections and, apparently, not all strings are readable, reinforcing a high probability that they’re still heavily encoded.

The .text (6.5) and .rsrc (7.3) sections are present with high entropy, which calls for extremely careful analysis.

A subset of strings was visible in readable text and were tied to credentials and abuse of the legitimate “ScreenConnect” tool, suggesting the use of remote access software. Could this file be related to an infostealer? As tempting as it is to lean on some biases during the investigation, I can’t attribute it to an infostealer until the hypothesis is proven based on reliable evidence.


Checking the import table, only kernel32.dll and msimg32.dll are present. The export table is empty.

There’s also an API function called IsDebuggerPresent, giving an insight into checks for malware-debugging tools.
Adding up these signals, there’s a strong indication that something malicious is being hidden in this binary.
Since the resources (.rsrc) are packed, I used Resource Hacker to check what was inside, and the result was two string tables.
String Table 7:
STRINGTABLE
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
{
101, "sadof asdoufyg a9s7d8gf aosd8yf ga9sd6f aosdf"
102, "asdjf[ 9as7df 9a7ds8f haosdf"
103, "[ asdif 87asdtf7asgydhf"
104, "aps\xF8df pasdtfasd{F ua[sd8f asfd uap9sdyf a"
105, "SDUfp a7tsdfa"
106, "sduf asdtf9a78sdyfi7asdf aspdf gas7dfy aosdf["
107, " aisd0fy aos7d gfasid;fh asfdj a9psdf8 ya97df6gwpt4iu;g p"
108, "ODFg [98asdfyg 9asd078yf hbwotegn "
109, "[wdjfvp8YSADf8as9d87ef hw]4"
110, "[gp ad[fogy97dsftay[08gidofh"
111, "asdif pas7dtf8asd97f9gwegu"
}
String Table 8:
STRINGTABLE
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
{
112, "asdojf p8sdf8asdfgap87g hsdfog"
113, "[ jsfgohij w0r7tg ha8sdgf a7sdhf "
114, "a[sdg jfdoh g97a6dsgfya[08sdyfia7sdyf "
115, "[asdkf psdf7yg a8sd7fy 8hwouifg na"
116, "s[odjf a078sdf t8a90f78p9g hwhti \x07"
117, "sdgk aps9d7fta9sd87f hao8sdfugj "
118, "a[spdkg p9as8dyf as8dh f"
119, "[asdojf [ausd f7isd8fh"
120, "[asdjf p8ysdg f08a7sd gf9a8sduf ap9sduhf as8d9"
}

I still don’t have enough correlation to confirm this content is tied to the actual unpack routine in this analysis — it could be padding or an additional layer of encoded data.
Looking at the Windows API calls, some of them can point toward the malicious file’s objective:
- LoadLibraryW
- CreateHardLinkA
- WriteFile
- CreateFileW
- VirtualProtect
In IDA, you can see a considerable .data area marked as “unexplored” and a mention of “dfighjbsdiofj.dll” in both .data and .rdata, plus an instruction that could point to in-memory decompression.


The binary calls a .txt file (push 01:adfspgkjsdflkgjsdkfgmpskdfjgopsdfgpsdfmgpsdflgm.txt). Right after, an oddly named DLL was also identified: dfighjbsdiofj.dll.
With the pseudocode in evidence, you can read the entire unpack routine and know exactly where to focus while running the debugger.
The CreateHardLinkA function stands out for not being a commonly abused API by malware — it could indicate anti-forensic evasion (creating a link to the same file at another path) or a remnant of reused legitimate code.
In routine sub_807C10, several of these calls (CreateHardLinkA, GetPrivateProfileSectionW, CreateFileA with a random filename, TransparentBlt with all null parameters) are anti-analysis decoys with no functional effect. The two do;while loops with unlikely comparisons are timing delays. The real core of the unpack is just four steps, described below.
v5 = LocalAlloc(0, 0x7550u); // allocate buffer
VirtualProtect(v5, 0x7550u, 0x40u, &floldProtect); // RWX (PAGE_EXECUTE_READWRITE)
TransparentBlt(nullptr, 0, 0, 0, 0, ...);
[..]
for (i=0; i<0x7550; i++) // copy the blob (loop at 0x807D80)
v5[i] = src[i + (0x811D65 - v5)]; // src is fixed inside the binary itself
sub_807B70(); // decrypt (TEA)
((void(*)())v5)(); // call [ebp-824] -> executes the payload


What actually copies the payload is the byte-by-byte copy loop at 0x807D80, and the routine sub_807B70 implements TEA (Tiny Encryption Algorithm) in decryption mode, identified by the constants 0xC6EF3720 (initial sum = delta × 32) and 0x61C88647 (−delta). The key used is four DWORDs stored in .rdata. After this step runs, the buffer contains a valid PE (MZ), and the loader is executed via call [ebp-824].
The call to TransparentBlt (exported by msimg32.dll) shows up with null parameters — meaning it doesn’t perform any useful copy in this flow, which points to a possible attempt at disguise, meant to add noise and misattribute the real copy to the identified loop.
With this information in hand, breakpoints were used on important functions that cover the in-memory unpacker cycle:
- LocalAlloc: allocation of the destination buffer
- VirtualProtect: setting up executable permissions (RWX)
- CreateFileA: persisting artifacts to disk
Practical capture tip: stopping at
VirtualProtect, the buffer (lpAddress, at[esp+4]) is still encrypted. The ideal dump point is right after the TEA decryption and before thecall [ebp+824], because at that instant the MZ header is already fully formed.



Stage 2 (payload)
After unpacking and dumping, the newly generated file has an Imports table with the functions: wininet, iphlpapi, psapi, ntdll, kernel32, user32, advapi. Also, the number of sections increased to 6, with .data showing packed status and high entropy (7.8).

This time, looking at the strings pane, it was possible to notice a new range of information such as:
- Connection (wininet.dll, InternetConnect)
- Process enumeration and system information gathering
- Crypt/decrypt routines
- Memory manipulation
- Decompression of packed data (ntdll > RtlDecompressBuffer)
- Loader self-deletion after execution (
\System32\svchost.exe /c del >> NUL) - Connectivity check services:
http://api.ipify.organdhttp://google.com - IP placeholder:
0.0.0.0 - Beacon:
GUID=%I64u&BUILD=%s&INFO=%s&IP=%s&TYPE=1&WIN=%d.%d(x32 ;x64) - User-Agent:
Mozilla/5.0 (Windows NT 6.1; Win64; x64; Trident/7.0; rv:11.0) like Gecko
Host profiling: possibly generating a unique victim ID from the Windows directory’s volume serial combined with the adapters’ MAC addresses, collecting OS version, IP, machine/user name, and domain trusts. Malware commonly uses this information to decide the next payload (based on the victim’s environment). This explains the GUID/INFO/IP fields in the beacon.
Ok, but what’s in .data? (Stage 3 - final)
Analyzing the unexplored part of the binary in .data, which starts with: 00406000 10 20 30 40 50 60 70 80 31 33 2E 36 37 00 00 00. 0@P’p.13.67, it’s likely that the sequence 10 20 30 40 50 60 70 80 could be the 8-byte key for decryption (0@P’p), followed by the version string “13.67”.
The routine sub_401F00 is what drives the decryption action, calling "call sub_401390", "call sub_401450", and finally "call sub_402B20", which in turn does the decrypt using the key.
Basically, it goes in this order:
sub_401390 > sub_401450 > sub_402B20
allocate 0x2000 > copy the blob > decrypt via CryptoAPI
Disassembling sub_402B20 reveals the following scheme:
CryptCreateHashwith ALG_ID0x8004= SHA-1CryptHashDataon the 8-byte key (pbDataat0x406010)CryptDeriveKeywith ALG_ID0x6801= RC4 and flags0x280011→ 40-bit (5-byte) keyCryptDecrypt(RC4) on the blob at0x406018, in-place
In other words, the RC4 key is, in fact, the first 5 bytes of the SHA-1 (of the 8-byte key). This type of config-extraction mechanism has been observed and attributed to the Hancitor malware, described in articles from Unit 42, OALabs, Binary Defense, and others. This is a strong indicator of the malware family.
CryptDecrypt function signature:
CryptDecrypt(hKey, hHash, Final, dwFlags, pbData, pdwDataLen)
[esp+4] [esp+8] [esp+C] [esp+10] [esp+14] [esp+18]
The following text was pulled from the Microsoft wiki for the CryptDecrypt function:
CryptDecrypt function (wincrypt.h)
The CryptDecrypt function decrypts data previously encrypted using the CryptEncrypt function. Important changes to support Secure/Multipurpose Internet Mail Extensions (S/MIME) interoperability have been made to CryptoAPI, affecting how enveloped messages are handled. For more information, see the Remarks section of CryptMsgOpenToEncode.
Syntax
BOOL CryptDecrypt(
[in] HCRYPTKEY hKey,
[in] HCRYPTHASH hHash,
[in] BOOL Final,
[in] DWORD dwFlags,
[in, out] BYTE *pbData,
[in, out] DWORD *pdwDataLen
);
Parameters
[in, out] pbData : A pointer to a buffer that contains the data to be decrypted. After decryption has taken place, the plaintext is placed back in this same buffer. The number of encrypted bytes in this buffer is specified by pdwDataLen.
[in, out] pdwDataLen : A pointer to a DWORD value that indicates the length of the pbData buffer. Before calling this function, the calling application sets this DWORD value to the number of bytes to be decrypted. On return, the DWORD value contains the number of bytes of decrypted plaintext. When a block cipher is used, this data length must be a multiple of the block size, unless this is the final section of data to decrypt and the Final parameter is TRUE.
Return value
If the function succeeds, it returns a nonzero value (TRUE). If the function fails, it returns zero (false).
In short, CryptDecrypt decrypts, in memory, a buffer previously encrypted with CryptEncrypt; the relevant parameter here is pbData (5th parameter → [esp+14]), which receives and returns the same buffer — ciphertext goes in, plaintext comes out, in-place.
Keeping this in mind, pbData (the buffer that’s decrypted in-place) is the 5th parameter = [esp+14], located at address 00A3B850. Running the debug up to the return, which lands in the final call to cryptsp, and looking at address 00A3B850, there are now domains in readable text.
In the analyzed case, [esp+14] = 00A3B850; running up to the function’s return and inspecting that address, it’s possible to identify, in readable text, the domains that lead to the infrastructure used by the attacker during the campaign.
- C2:
http://howrowthettof.com/ls5/forum.php - C2:
http://ratsparropret.ru/ls5/forum.php - C2:
http://ryropthetsed.ru/ls5/forum.php

With that, the malware was unpacked and the analysis’s initial objective was reached: identifying the campaign’s infrastructure and correlating the attack to a real threat.
Searching historical indicators related to these addresses, it’s possible to see they are indeed malicious, with attribution to the Hancitor family.
Note: there may be more than one call to CryptDecrypt. If the first stop doesn’t expose any URLs, just continue running the debug until the call that decrypts the 0x2000-byte config block.
The convergence between network behavior and the decryption scheme raises the attribution’s confidence from “probable” to “high”.
Hancitor is a downloader/loader active since mid-2014, distributed via malspam with maldocs, historically delivering Pony, Vawtrak, FickerStealer, Sendsafe, and Cobalt Strike Beacon. It has been associated with the Cuba ransomware operation as its loader of choice.
MITRE ATT&CK
| Tactic | Technique | ID |
|---|---|---|
| Defense Evasion | Obfuscated Files or Information | T1027 |
| Defense Evasion | Obfuscated Files or Information: Software Packing | T1027.002 |
| Defense Evasion | Obfuscated Files or Information: Embedded Payloads | T1027.009 |
| Defense Evasion | Deobfuscate/Decode Files or Information | T1140 |
| Defense Evasion | Debugger Evasion | T1622 |
| Defense Evasion | Reflective Code Loading | T1620 |
| Persistence | Create or Modify System Process: Windows Service | T1543.003 |
| Command and Control | Remote Access Software (ScreenConnect) | T1219 |
| Command and Control | Application Layer Protocol: Web Protocols | T1071.001 |
| Discovery | Internet Connection Discovery | T1016.001 |
| Defense Evasion | Indicator Removal: File Deletion | T1070.004 |
IoCs
Files
| Artifact | Hash |
|---|---|
| Packer (binary.exe) | 7dcbb4e490ee52c01e7838288c799981eaab47131b9f3dc21d349b8eac7545d4 |
| Packer (Imphash) | 4b61c02635e27b3b91e08cf39f0b6207 |
| SHA-1 | 3546f8a5f516a12b87ca7fefd83fe806bf9624dd |
| Dump (payload) | bf65a4c82f262241e91a0c5e162ae8520d26dcba257a3c7ed137bf14edd4400b |
| Unpacker | 17511446d1943880bf579e703c5fca96d307e10583fa2b98d926a415d8576061 |
Network
| Type | Indicator |
|---|---|
| URL C2 | hxxp://howrowthettof[.]com/ls5/forum[.]php |
| URL C2 | hxxp://ratsparropret[.]ru/ls5/forum[.]php |
| URL C2 | hxxp://ryropthetsed[.]ru/ls5/forum[.]php |
| Domain | howrowthettof[.]com |
| Domain | ratsparropret[.]ru |
| Domain | ryropthetsed[.]ru |
| IP | 199[.]59[.]242[.]150 |
| IP | 212[.]116[.]113[.]108 |
| IP | 163[.]172[.]235[.]143 |
Other names
-
hancitor[.]exe -
7dcbb4e490ee52c01e7838288c799981eaab47131b9f3dc21d349b8eac7545d4[.]exe -
7e8c4d0d8ee8310eba3360e7c4f27cd9 -
putty[.]exe
References
- Unit 42 (Palo Alto) — Dissecting Hancitor’s Latest 2018 Packer
- OALabs — Hancitor config extraction (Lab Notes)
- #StopRansomware — Cuba Ransomware
- Binary Defense — Analysis of Hancitor: When Boring Begets Beacon
- Eli Salem — Dissecting and automating Hancitor’s config extraction
- 0ffset — HANCITOR: Analysing The Main Loader
- The DFIR Report — Hancitor Continues to Push Cobalt Strike