Technical explanation of ransomware PadCrypty domain name Generation Algorithm
PadCrypt is the name of a ransomware, which was first mentioned on Twitter @ abuse_ch. BleepinComputer.com wrote two articles about PadCrypt. MalwareHunterTeam also mentioned the domain name generation algorithm (DGA) of PadCrypt version 2.2.86.1 on Twitter ):
The version pushed by BleepinComputer.com is 2.2.97.0:
The following are the 24 domain names generated by version 2.2.86.1 on April 9, March 6, 2016:
The following are 72 domain names generated by version 2.2.97.0 on April 9, March 6, 2016:
To reproduce DGA, the sample I used was PadCrypt 2.2.86.1 from Hybrid-Analysis.
MD5 f58072b9413886e7b79e826ad94bd89e
SHA-256 1ad70a64863c2c59390e4e956d97065524acf5e2ae53f786770d2cf6bd602141
upload date 2015-03-01 10:55:57 (CST)
filename package.pdcr.bin
PadCrypt version 2.2.86.1
filesize 1.3 MB
Link
The following sample is PadCrypt 2.2.97.0. It is from Lawrence Abrams and can be downloaded from virusshare. This sample made a small modification on DGA (For details, refer to the above Twitter ).
MD5 7c0f7a734014022f249338a23881dc24
SHA-256 f0f8ef9a0cd40363aa4b06ba4c0fa286f23010830caa931addefacb087d7c678
upload date 2016-03-06 19:52:54
filename PadCrypt.exe
PadCrypt version 2.2.97.0
filesize 1.4 MB
Link
0 × 01 DGA Design
PadCrypt 2.2.86.1's DGA generates 24 domain names a day, and PadCrypt 2.2.97.0 is three times its (72 ). DGA uses SHA256 hash values as the generation scheme. Hash of other malware families includes bamboo, Murofet, Gamover, Pushdo (MD5), and Dyre (SHA-256 ).
The number of PadCrypt does not undergo complex changes. Only the current time of the domain name number (0 to 23) uses the hash value. The only difference between 2.2.86.1 and 2.2.97.0 is that the time and domain name numbers are separated. The old version is separated by (eg, 6-3-2016: 17); in the new version (eg: 6-3-2017 | 17 ).
The last four digits of the Hash value determine whether it is a top-level domain name. The four-digit value is used as the index of the hard-coded list of top-level domain names. The list contains only 11 domain names. The first top-level domain name is used to replace a larger index. This makes the first domain name ". com" more common than other domain names. The 3-18 bits determine 16 second-level features. The second-level features are mapped to a hard-coded list of 0000-1001:
The remaining values 1010-1111 are mapped to the corresponding hexadecimal representation, "a" to "f ". Because letters a, B, c, d and f are also hard-coded ing, they appear twice like the letter "enolmk.
0 × 02 Reproduction
Use python to reproduce DGA. Use the-d or-date parameter to set the date. If no date is provided, the domain name of the current day is generated. You can use-V or-version to select the DGA version. You can also find the improved DGA reproduction process on my Github.
The DGA of PadCrypt
See
- https://twitter.com/BleepinComputer/status/705813885673201665
- http://www.bleepingcomputer.com/news/security/padcrypt-the-first-ransomware-with-live-support-chat-and-an-uninstaller/
- http://www.bleepingcomputer.com/news/security/the-padcrypt-ransomware-is-still-alive-and-kicking/
- http://johannesbader.ch/2016/03/the-dga-of-padcrypt/
"""
import argparse
import hashlib
from datetime import datetime
configs = {
"2.2.86.1" : {
'nr_domains': 24,
'tlds': ['com', 'co.uk', 'de', 'org', 'net', 'eu', 'info', 'online',
'co', 'cc', 'website'],
'digit_mapping': "abcdnfolmk",
'separator': ':',
},
"2.2.97.0" : {
'nr_domains': 24*3,
'tlds': ['com', 'co.uk', 'de', 'org', 'net', 'eu', 'info', 'online',
'co', 'cc', 'website'],
'digit_mapping': "abcdnfolmk",
'separator': '|'
}
}
def dga(date, config_nr):
config = configs[config_nr]
dm = config['digit_mapping']
tlds = config['tlds']
for i in range(config['nr_domains']):
seed_str = "{}-{}-{}{}{}".format(date.day, date.month, date.year,
config['separator'], i)
h = hashlib.sha256(seed_str.encode('ascii')).hexdigest()
domain = ""
for hh in h[3:16+3]:
domain += dm[int(hh)] if '0' <= hh <= '9' else hh
tld_index = int(h[-1], 16)
tld_index = 0 if tld_index >= len(tlds) else tld_index
domain += "." + config['tlds'][tld_index]
yield domain
if __name__=="__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--date", help="date for which to generate domains")
parser.add_argument("-v", "--version", help="dga version",
choices=["2.2.86.1", "2.2.96.1"], default="2.2.86.1")
args = parser.parse_args()
if args.date:
d = datetime.strptime(args.date, "%Y-%m-%d")
else:
d = datetime.now()
for domain in dga(d, args.version):
print(domain)
0 × 03 features
The following are the features of PadCrypt DGA:
A second-level domain name character set consisting of only 11 characters. Along with the fixed length of 16 characters, this makes the domain name better attributed to PadCrypt. The allocation is as follows:
A: 12.5%
B: 12.5%
C: 12.5%
D: 12.5%
E: 6.25%
F: 12.5%
K: 6.25%
1: 6.25%
M: 6.25%
N: 6.25%
O: 6.25%
Among top-level domain names,. com accounts for 37.5%, and the remaining 10 top-level domain names account for about 6.25%.
0 × 05 appendix-how to reverse
Someone sent a private message on Twitter about how to reverse DGA. Here we will show you how to reverse PadCrypt.
PadCrypt is written in. NET4.5. We can use the. NET anti-compiler to open binary files. I use a free and useful dnSpy. Naturally, the authors of PadCrypt realized that the decompilation of intermediate languages is relatively simple, so they use some protective means. Therefore, DeepSea4.1 is used in PadCrypt 2.2.86.1, 2.2.97.0, and the latest version 2.2.120.0. When you use dnSpy to open a binary file, only the scattered code is obtained. The following is the code after DGA obfuscation:
The decompiled program contains a total of 268 lines and cannot be read. Fortunately, most known obfuscators have obfuscators. I am using the free open-source de4dot. It is equipped with 21 obfuscators and uses the following command:
De4dot.exe padcrypt_2.2.97.0.exe-o padcrypt_2.2.97.0_deobf.exe
Let's take a look at the DGA program. This is a shorter and more readable C # code:
If you like, the VB code can also be: