HANCITOR: Analysing The Main Loader | 0ffset Training Solutions By Chuong Dong Published: 2021-12-31 · Archived: 2026-04-05 22:30:24 UTC This post is a follow up for my last one on HANCITOR. If you haven’t checked it out, you can view it here. In this post, we’ll take a look at the main loader of this malware family, which is used for downloading and launching Cobalt Strike Beacon, information stealers, and malicious shellcode. If you’re interested in following along, you can grab the loader sample as well as the PCAP for it on Malware-Traffic-Analysis.net. SHA256: b9bafe8645a4dba7b7a9bd5132b696c0a419998d4f65fe897bb6912c2e019a7b Step 1: Unpacking HANCITOR’s first executable stage is a packed DLL. We can tell since the HANCITOR payload is typically not obfuscated and relatively short. The gelforr.dap file dropped from the maldoc stages, on the other hand, is quite large and has a high entropy (the measure of randomness for data in the file). This high entropy can be a good indicator for the sample containing some data obfuscation. To dynamically unpack this, we can load the sample in our favourite debugger and try to stop the program after it’s done unpacking the final payload in memory. https://www.0ffset.net/reverse-engineering/malware-analysis/hancitor-analysing-the-main-loader/ Page 1 of 22 First, we can set breakpoints on VirtualAlloc and VirtualProtect as those two API calls are typically used by packers to allocate memory for the unpacked executable and change the memory’s protection to executable prior to launching. We can also set breakpoints on CreateProcessInternalW and ResumeThread to try and stop our debugger before the final payload is launched. At this point, we can have the debugger execute the DLL and wait until these breakpoints are hit. As the code is quite large, it takes around 30 seconds before we hit our first VirtualAlloc breakpoint. To observe if the packer writes the unpacked executable into the newly allocated memory, we can capture the return value of the VirtualAlloc call and dump its memory before continuing the execution. The first two allocated regions do not seem to give us anything valuable, but the third one does. The packer writes what seems to be a compressed PE file in it before calling VirtualProtect to change its protection. https://www.0ffset.net/reverse-engineering/malware-analysis/hancitor-analysing-the-main-loader/ Page 2 of 22 Scrolling down a bit to examine this memory region, we can see that its lower part is not compressed at all. To be exact, at offset 0x4389, we can see the uncompressed PE header, which indicates the beginning of the final unpacked payload. From here, we can simply dump this memory region and cut out the top 0x4389 bytes using any hex editor to retrieve the unpacked executable for the next stage. https://www.0ffset.net/reverse-engineering/malware-analysis/hancitor-analysing-the-main-loader/ Page 3 of 22 We can also use PE-bear to examine and ensure that we have fully unpacked the file. After checking that all imports are properly resolved, we will use IDA to perform static analysis on this last stage. Step 2: HANCITOR Entry Point The HANCITOR DLL contains the following 3 exports:  BNJAFSRSQIX, SDTECHWMHHONG, and DllEntryPoint. Since the functions BNJAFSRSQIX and SDTECHWMHHONG share the same address, we can count them as one single function. Typically, DllEntryPoint is used as the entry point function for malicious DLL files, but in HANCITOR case, this function does not do anything but return 1. This means that the malware does not execute its full capability when loaded using rundll32.exe without an export name specified. https://www.0ffset.net/reverse-engineering/malware-analysis/hancitor-analysing-the-main-loader/ Page 4 of 22 From the previous blog post, we know that the second Word document launches the rundll32.exe command to execute the BNJAFSRSQIX export function, so it must be the real entry point for this DLL. Step 3: Extracting Victim Information By the time this blog post is written, the C2 servers used by the sample have been taken offline, so I will use the traffic captured by Malware-Traffic-Analysis.net in parallel with static analysis to show how the malware communicates with its C2 servers. To contact C2 servers, the malware generates a string containing the victim’s information prior to encrypting and sending it to C2. First, HANCITOR generates a global unique identifier (GUID) for the victim. By calling GetAdaptersAddresses, it retrieves an array of addresses associated with the network adapters on the victim’s machine. It begins by XOR-ing the Media Access Control (MAC) adapter of each address together. Then, the malware retrieves the machine’s volume serial number by calling GetVolumeInformationA and XORs it with the result to create the victim’s GUID. https://www.0ffset.net/reverse-engineering/malware-analysis/hancitor-analysing-the-main-loader/ Page 5 of 22 Following this, HANCITOR extracts the machine’s information by calling GetComputerNameA to retrieve the infected computer’s name. It also retrieves the process ID of an explorer.exe process and calls LookupAccountSidA to get the current user’s account name and domain name. The machine’s information is then formatted as below. @ \ Next, HANCITOR retrieves the victim’s IP address by sending a GET request to hxxp://api[.]ipify[.]org. If the malware is unable to contact the website, it uses 0.0.0.0 as the victim’s IP address instead. https://www.0ffset.net/reverse-engineering/malware-analysis/hancitor-analysing-the-main-loader/ Page 6 of 22 The documented query_URL_and_get_response function is shown below. After connecting to the target server using InternetConnectA, HANCITOR calls HttpOpenRequestA to create a GET request and HttpSendRequestA to send it to the server. The server’s response is then retrieved through InternetReadFile calls. Beside being used for querying the victim’s IP address, this function is later used to download malware and shellcode from HANCITOR’s C2 servers. The malware then calls DsEnumerateDomainTrustsA to enumerate and retrieve all NETBIOS and DNS domain names. https://www.0ffset.net/reverse-engineering/malware-analysis/hancitor-analysing-the-main-loader/ Page 7 of 22 Finally, HANCITOR decrypts its configuration using RC4 before building the final victim’s information string. Below is the content of the decoded configuration. It contains the sample’s build ID (2909_xplw) followed by the list of C2 URLs. The final victim’s information string is built according to one of the following formats based on the machine’s architecture. https://www.0ffset.net/reverse-engineering/malware-analysis/hancitor-analysing-the-main-loader/ Page 8 of 22 GUID=&BUILD=&INFO=&EXT=&IP=&BUILD=&INFO=&EXT=&IP=