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 ofuint32
words. - 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 theNTRUEncrypt
parameter 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 theNTRU
algorithm. - File:
ntru_crypto_sha1.c
- Routines implementing theSHA-1
hash calculation. - File:
ntru_crypto_sha2.c
- Routines implementing theSHA-2
hash calculation. - File:
ntru_crypto_sha256.c
- Routines implementing theSHA-256
hash calculation. - And the last one is file:
ntru_crypto_ntru_encrypt.c
- Routines implementingNTRUEncrypt
encryption 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 bytes
of 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_ENTROPY
command requests the number of bytes needed to produce a byte of entropy. Here, it returns1
, indicating that1
byte of input gives1
byte 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_ENTROPY
command 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