Malware source code investigation: HelloKitty - part 2. NTRUEncrypt
HelloKitty ransomware represents a sophisticated strain of malicious software strategically designed for targeted attacks, demonstrating an evolved and nuanced approach within the realm of cybersecurity threats. First identified in November 2020, this ransomware variant distinguishes itself through its utilization of robust encryption algorithms, rendering victim files inaccessible and underscoring the formidable technical proficiency of its operators.

NTRUEncrypt
The NTRUEncrypt SDK for C/C++ implements the NTRUEncrypt algorithm, a replacement for legacy public-key encryption algorithms such as RSA. NTRUEncrypt gives incredible performance gains at no loss in security.
Installation
First of all, the interesting file is INSTALL file with instructions:

So, you can build libntruencrypt with simple commands and bash scripts.
Another option is in the vs2012 folder:

Where you can find Microsoft Visual Studio Solution File Ntrubuild.sln and project files.
include
The NTRUEncrypt SDK offers a wide range of “parameter sets” to cater to different security requirements. The parameter sets can be specified using the NTRU_ENCRYPT_PARAM_SET_ID found in the header file crypto_ntru.h. The parameter set selected is specified during key generation. When the private and public keys are created, the parameter set is encoded into the key blob:

The parameter set you choose depends on several factors:
- What level of security is required?
 - Do you need to ensure compatibility with ASC Standard X9.98-2010? For instance, is this a requirement for an RFP you are responding to?
 - What is the primary focus: reducing operation time, conserving bandwidth, or a combination of both?
 
It’s important to note that this SDK does not offer a parameter set at the widely used RSA-1024 security level, which is comparable to 80-bit symmetric ciphers or 163-bit Elliptic Curve cryptography. This is because RSA-1024 is no longer recommended by NIST, Microsoft, and the CA/Browser Forum, and certificates at that security level will no longer be issued after December 31, 2010. You can find more information about this on the following link: https://learn.microsoft.com/en-us/previous-versions//cc751157(v=technet.10).
src
So the main and most interesting folder is src:

As you can see, here the encryption logic.
The most important implementations here are Deterministic Random Byte Generator (DRBG) and Entropy source (Seeding the DRBG).
What is DRBG?
Prior to using NTRUEncrypt for key-generation or encryption, it is necessary to create an instance of a deterministic random byte generator (DRBG). The DRBG in this release follows the ANS X9.82 Part 3-2007 standard and utilizes HMAC_DRBG. The DRBG instantiation function provides a handle that can be passed to the key-generation and encryption functions.
When setting up a DRBG, you need to specify a security level. This should be at least as high as the security level of the NTRU parameter set that will be employed. Refer to the following table for the security levels linked to the different NTRUEncrypt parameter sets. You can have a maximum of four DRBGs running concurrently, with each one operating at a different security level: 112-bits, 128-bits, 192-bits, and 256-bits. Once set up, a single DRBG can be utilized for all tasks at a specific security level:
| Security Level | Best bandwidth and speed, no X9.98 compatibility | Need X9.98 compatibility (best speed / best bandwidth / balance speed and bandwidth) | 
|---|---|---|
| 112-bit symmetric / RSA-2048 / ECC-224 | NTRU_EES401EP2 | NTRU_EES659EP1 / NTRU_EES401EP1 / NTRU_EES541EP1 | 
| 128-bit symmetric / RSA-4096 / ECC-256 | NTRU_EES439EP1 | NTRU_EES761EP1 / NTRU_EES449EP1 / NTRU_EES613EP1 | 
| 192-bit symmetric / RSA-7680 / ECC-384 | NTRU_EES593EP1 | NTRU_EES1087EP1 / NTRU_EES677EP1 / NTRU_EES887EP1 | 
| 256-bit symmetric / RSA-15360 / ECC-512 | NTRU_EES743EP1 | NTRU_EES1499EP1 / NTRU_EES1087EP2 / NTRU_EES1171EP1 | 
Table 2 gives the bandwidth and performance at each security level for NTRUEncrypt keys for the appropriate parameter sets, and for Elliptic Curve Cryptography (ECC) and RSA:
| Name | Strength | Sizes (CText/Pub/Priv) | Enc / Dec Time | Pat. Until | 
|---|---|---|---|---|
| EES401EP1 | 112 bits | 552 / 556 / 264 | 2.5 / 2.7 | 8/19/2017 | 
| EES541EP1 | 112 bits | 744 / 748 / 132 | 1.5 / 1.9 | 8/19/2017 | 
| EES659EP1 | 112 bits | 907 / 911 / 104 | 1.5 / 2.0 | 8/19/2017 | 
| EES401EP2 | 112 bits | 552 / 556 / 67 | 1.0 / 1.2 | 8/24/2021 | 
| NTRU_DEFAULT_PARAMS_112_BITS | 112 bits | Synonym for EES401EP2 or EES401EP1 | ||
| EES449EP1 | 128 bits | 618 / 622 / 311 | 2.7 / 3.4 | 8/19/2017 | 
| EES613EP1 | 128 bits | 843 / 847 / 147 | 1.6 / 2.2 | 8/19/2017 | 
| EES761EP1 | 128 bits | 1047 / 1051 / 114 | 1.6 / 2.2 | 8/19/2017 | 
| EES439EP1 | 128 bits | 604 / 608 / 68 | 1.1 / 1.4 | 8/24/2021 | 
| EES443EP1 | 128 bits | 610 / 614 / 68 | 1.1 / 1.3 | 8/24/2021 | 
| NTRU_DEFAULT_PARAMS_128_BITS | 128 bits | Synonym for EES443EP1 or EES449EP1 | ||
| EES677EP1 | 192 bits | 931 / 935 / 402 | 4.4 / 5.5 | 8/19/2017 | 
| EES887EP1 | 192 bits | 1220 / 1224 / 212 | 2.8 / 3.9 | 8/19/2017 | 
| EES1087EP1 | 192 bits | 1495 / 1499 / 183 | 3.0 / 4.0 | 8/19/2017 | 
| EES593EP1 | 192 bits | 816 / 820 / 87 | 1.7 / 2.1 | 8/24/2021 | 
| EES587EP1 | 192 bits | 808 / 812 / 87 | 1.9 / 2.3 | 8/24/2021 | 
| NTRU_DEFAULT_PARAMS_192_BITS | 192 bits | Synonym for EES587EP1 or EES677EP1 | ||
| EES1087EP2 | 256 bits | 1495 / 1499 / 339 | 4.5 / 6.1 | 8/19/2017 | 
| EES1171EP1 | 256 bits | 1611 / 1615 / 301 | 4.3 / 6.0 | 8/19/2017 | 
| EES1499EP1 | 256 bits | 2062 / 2066 / 227 | 4.3 / 6.0 | 8/19/2017 | 
| EES743EP1 | 256 bits | 1022 / 1026 / 111 | 2.2 / 2.9 | 8/24/2021 | 
| NTRU_DEFAULT_PARAMS_256_BITS | 256 bits | Synonym for EES743EP1 or EES1087EP2 | 
Running times were obtained on a single core of a 2 GHz Intel Duo T7250 processor running Linux.
What about seeding DRBG?
Seeding is a crucial step for any DRBG, as the security of the DRBG relies heavily on the randomness of the seed. The X9.82 DRBG included in this release acquires the seed through an entropy function. The caller is responsible for providing the entropy function and passing a pointer to it to the DRBG instantiation function. The code provided in this release includes a function that calculates sample entropy.
The entropy function prototype is in ntru_crypto_drbg.h:

As we can see, the source code has a lot of comments and is well documented.
It has two arguments: a one-byte command, and an address for one byte of data to be passed back. The function returns one byte of status, with 1 indicating success and 0 indicating failure. The three commands that must be implemented are INIT, GET_NUM_BYTES_PER_BYTE_OF_ENTROPY, and GET_BYTE_OF_ENTROPY:

The INIT command is used to perform whatever initialization the entropy function requires.
The GET_NUM_BYTES_PER_BYTE_OF_ENTROPY command returns the required number of bytes to obtain 8 bits of entropy. This value should range from 1 to 8 bytes. This value relies on the unpredictability of the entropy source. It is important to consider that the level of entropy needed to set up a DRBG is 1.5 times the security level of the DRBG. As an illustration, creating a DRBG with 112-bit security necessitates 21 bytes of entropy.
The GET_BYTE_OF_ENTROPY command returns a byte with a certain amount of entropy, ranging from 1 to 8 bits. The specific amount of entropy is indicated in the response to the GET_NUM_BYTES_PER_BYTE_OF_ENTROPY command.
The caller-supplied entropy function may be a true random source, an already properly-seeded pseudo-random number generator, or a seed that has been obtained from a random source.
The remaining files are source codes of different logics, among them I would like to note the following:
- File 
ntru_crypto_hash.c- Routines implementing the hash object abstraction. - File 
ntrue_crypto_hmac.c- Routines implementing the HMAC hash calculation. - File 
ntru_crypto_msbyte_uint32.c- Routines to convert between an array of bytes in network byte order (most-significant byte first) and an array ofuint32words. - File 
ntru_crypto_ntru_convert.c- Conversion routines for NTRUEncrypt, including packing, unpacking, and others. - File 
ntru_crypto_ntru_encrypt_key.c- Routines for exporting and importing public and private keys forNTRUEncrypt. - File 
ntru_crypto_ntru_encrypt_param_sets.c- Defines theNTRUEncryptparameter sets: 

- File: 
ntru_crypto_ntru_mgf1.c- Routines implementing MGF-TP-1 and MGF-1. - File: 
ntru_crypto_ntru_poly.c- Routines for generating and operating on polynomials in theNTRUalgorithm. - File: 
ntru_crypto_sha1.c- Routines implementing theSHA-1hash calculation. - File: 
ntru_crypto_sha2.c- Routines implementing theSHA-2hash calculation. - File: 
ntru_crypto_sha256.c- Routines implementing theSHA-256hash calculation. - And the last one is file: 
ntru_crypto_ntru_encrypt.c- Routines implementingNTRUEncryptencryption and decryption and key generation: 

sample
The sample code included in this release demonstrates how the function works and provides working code with a fixed seed. Providing entropy in this manner is clearly not suitable for a real-world application:

For example, static uint8_t get_entropy code snippet defines an example entropy function that simulates the generation of entropy for cryptographic purposes. The function get_entropy is designed to handle different commands (ENTROPY_CMD) to initialize, return the number of bytes required to get a byte of entropy, and return a byte of entropy.

This function takes a command and a pointer to an 8-bit integer and returns 1 for success and 0 for failure.
static uint8_t seed[28] = {
    'P','l','e','a','s','e',' ','u','s','e',' ','a',' ',
    'd','i','f','f','e','r','e','n','t',' ','s','e','e','d','!'
};
static size_t index;
seed- This is a static array containing28 bytesof fixed seed data. This data is not truly random and should be replaced with actual entropy in a real-world application.index- This static variable keeps track of the position in the seed array from which the next byte of entropy will be delivered.
if (cmd == INIT) {
    index = 0;
    return 1;
}
INIT- This command initializes the entropy function, setting the index to0. This means the next request for a byte of entropy will start from the beginning of the seed array.
Checking for null output pointer:
if (out == NULL)
    return 0;
This check ensures that the out pointer is not NULL. If it is NULL, the function returns 0, indicating failure.
if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) {
    *out = 1;
    return 1;
}
GET_NUM_BYTES_PER_BYTE_OF_ENTROPYcommand requests the number of bytes needed to produce a byte of entropy. Here, it returns1, indicating that1byte of input gives1byte of entropy, implying a perfectly random source.
if (cmd == GET_BYTE_OF_ENTROPY) {
    if (index == sizeof(seed))
        return 0;                   /* used up all our entropy */
    *out = seed[index++];           /* deliver an entropy byte */
    return 1;
}
GET_BYTE_OF_ENTROPYcommand requests a single byte of entropy. If the index has reached the size of the seed array, it returns 0, indicating that all the entropy has been used up. Otherwise, it copies a byte from the seed array to out and increments the index.
Finally, if the command is not recognized, the function returns 0, indicating failure.
That’s all today.
The purpose of these articles was to improve the reader’s code analysis skills, gain insight into the techniques used by modern malware, and improve artifact detection. In addition, these blog posts in our laboratory were written with the intention of publishing an article during a long break, inspired by various presentations by our specialists at international conferences in Europe and the Middle East like BlackHat, Standoff, Security BSides Zagreb, Sofia and Prishtina. Although there is a lack of complete understanding of some parts of the source code, the goal of the article was to provide detailed and eloquent explanations.
By Cyber Threat Hunters from MSSPLab:
References
https://malpedia.caad.fkie.fraunhofer.de/details/win.hellokitty     
Malware source code investigation: HelloKitty - part 1    
https://en.wikipedia.org/wiki/NTRUEncrypt   
Original NTRUEncrypt paper
Thanks for your time happy hacking and good bye!       
All drawings and screenshots are MSSPLab’s