forked from kevthehermit/RATDecoders
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathDarkComet.py
169 lines (143 loc) · 5.03 KB
/
DarkComet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/usr/bin/env python
'''
DarkComet Rat Config Decoder
'''
__description__ = 'DarkComet Rat Config Extractor'
__author__ = 'Kevin Breen http://techanarchy.net'
__version__ = '0.1'
__date__ = '2014/03/15'
import sys
import string
from struct import unpack
try:
import pefile
except ImportError:
print "Couldnt Import pefile. Try 'sudo pip install pefile'"
from optparse import OptionParser
from binascii import *
def rc4crypt(data, key):
x = 0
box = range(256)
for i in range(256):
x = (x + box[i] + ord(key[i % len(key)])) % 256
box[i], box[x] = box[x], box[i]
x = 0
y = 0
out = []
for char in data:
x = (x + 1) % 256
y = (y + box[x]) % 256
box[x], box[y] = box[y], box[x]
out.append(chr(ord(char) ^ box[(box[x] + box[y]) % 256]))
return ''.join(out)
def v51_data(data, enckey):
config = {"FWB": "", "GENCODE": "", "MUTEX": "", "NETDATA": "", "OFFLINEK": "", "SID": "", "FTPUPLOADK": "", "FTPHOST": "", "FTPUSER": "", "FTPPASS": "", "FTPPORT": "", "FTPSIZE": "", "FTPROOT": "", "PWD": ""}
dec = rc4crypt(unhexlify(data), enckey)
dec_list = dec.split('\n')
for entries in dec_list[1:-1]:
key, value = entries.split('=')
key = key.strip()
value = value.rstrip()[1:-1]
clean_value = filter(lambda x: x in string.printable, value)
config[key] = clean_value
config["Version"] = enckey[:-4]
return config
def v3_data(data, key):
config = {"FWB": "", "GENCODE": "", "MUTEX": "", "NETDATA": "", "OFFLINEK": "", "SID": "", "FTPUPLOADK": "", "FTPHOST": "", "FTPUSER": "", "FTPPASS": "", "FTPPORT": "", "FTPSIZE": "", "FTPROOT": "", "PWD": ""}
dec = rc4crypt(unhexlify(data), key)
config[str(entry.name)] = dec
config["Version"] = enckey[:-4]
return config
def versionCheck(rawData):
if "#KCMDDC2#" in rawData:
return "#KCMDDC2#-890"
elif "#KCMDDC4#" in rawData:
return "#KCMDDC4#-890"
elif "#KCMDDC42#" in rawData:
return "#KCMDDC42#-890"
elif "#KCMDDC42F#" in rawData:
return "#KCMDDC42F#-890"
elif "#KCMDDC5#" in rawData:
return "#KCMDDC5#-890"
elif "#KCMDDC51#" in rawData:
return "#KCMDDC51#-890"
else:
return None
def configExtract(rawData, key):
config = {"FWB": "", "GENCODE": "", "MUTEX": "", "NETDATA": "", "OFFLINEK": "", "SID": "", "FTPUPLOADK": "", "FTPHOST": "", "FTPUSER": "", "FTPPASS": "", "FTPPORT": "", "FTPSIZE": "", "FTPROOT": "", "PWD": ""}
pe = pefile.PE(data=rawData)
rt_string_idx = [
entry.id for entry in
pe.DIRECTORY_ENTRY_RESOURCE.entries].index(pefile.RESOURCE_TYPE['RT_RCDATA'])
rt_string_directory = pe.DIRECTORY_ENTRY_RESOURCE.entries[rt_string_idx]
for entry in rt_string_directory.directory.entries:
if str(entry.name) == "DCDATA":
data_rva = entry.directory.entries[0].data.struct.OffsetToData
size = entry.directory.entries[0].data.struct.Size
data = pe.get_memory_mapped_image()[data_rva:data_rva+size]
config = v51_data(data, key)
elif str(entry.name) in config.keys():
data_rva = entry.directory.entries[0].data.struct.OffsetToData
size = entry.directory.entries[0].data.struct.Size
data = pe.get_memory_mapped_image()[data_rva:data_rva+size]
dec = rc4crypt(unhexlify(data), key)
config[str(entry.name)] = filter(lambda x: x in string.printable, dec)
config["Version"] = key[:-4]
return config
def configClean(config):
try:
newConf = {}
newConf["FireWallBypass"] = config["FWB"]
newConf["FTPHost"] = config["FTPHOST"]
newConf["FTPPassword"] = config["FTPPASS"]
newConf["FTPPort"] = config["FTPPORT"]
newConf["FTPRoot"] = config["FTPROOT"]
newConf["FTPSize"] = config["FTPSIZE"]
newConf["FTPKeyLogs"] = config["FTPUPLOADK"]
newConf["FTPUserName"] = config["FTPUSER"]
newConf["Gencode"] = config["GENCODE"]
newConf["Mutex"] = config["MUTEX"]
newConf["Domains"] = config["NETDATA"]
newConf["OfflineKeylogger"] = config["OFFLINEK"]
newConf["Password"] = config["PWD"]
newConf["CampaignID"] = config["SID"]
newConf["Version"] = config["Version"]
return newConf
except:
return config
def run(data):
versionKey = versionCheck(data)
if versionKey != None:
config = configExtract(data, versionKey)
config = configClean(config)
return config
else:
return None
if __name__ == "__main__":
parser = OptionParser(usage='usage: %prog inFile outConfig\n' + __description__, version='%prog ' + __version__)
(options, args) = parser.parse_args()
if len(args) > 0:
pass
else:
parser.print_help()
sys.exit()
try:
print "[+] Reading file"
fileData = open(args[0], 'rb').read()
except:
print "[+] Couldn't Open File {0}".format(args[0])
print "[+] Searching for Config"
config = run(fileData)
if config == None:
print "[+] Config not found"
sys.exit()
if len(args) == 2:
print "[+] Writing Config to file {0}".format(args[1])
with open(args[1], 'a') as outFile:
for key, value in sorted(config.iteritems()):
outFile.write("Key: {0}\t Value: {1}\n".format(key,value))
else:
print "[+] Printing Config to screen"
for key, value in sorted(config.iteritems()):
print " [-] Key: {0}\t Value: {1}".format(key,value)
print "[+] End of Config"