Skip to content

Commit f9064f5

Browse files
committed
Added support for new types of AgentTesla
1 parent b94564a commit f9064f5

File tree

3 files changed

+78
-15
lines changed

3 files changed

+78
-15
lines changed

malconfscan.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ def calculate(self):
7373
malname = "redleaves"
7474
if str(hit) in "TSC_Loader":
7575
malname = "tscookie"
76+
if "Agenttesla" in str(hit):
77+
malname = "agenttesla"
7678

7779
try:
7880
module = import_module("volatility.plugins.malware.utils.{name}scan".format(name=malname))

utils/agentteslascan.py

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,17 @@
3030
has_crypto = False
3131

3232
agenttesla_sig = {
33-
'namespace1' : 'rule Agenttesla { \
33+
'namespace1' : 'rule Agenttesla_type1 { \
3434
strings: \
35-
$iestr = "C:\\\\Users\\\\Admin\\\\Desktop\\\\IELibrary\\\\IELibrary\\\\obj\\\\Debug\\\\IELibrary.pdb" \
36-
$atstr = "C:\\\\Users\\\\Admin\\\\Desktop\\\\ConsoleApp1\\\\ConsoleApp1\\\\obj\\\\Debug\\\\ConsoleApp1.pdb" \
37-
$sqlitestr = "Not a valid SQLite 3 Database File" wide \
35+
$type1ie = "C:\\\\Users\\\\Admin\\\\Desktop\\\\IELibrary\\\\IELibrary\\\\obj\\\\Debug\\\\IELibrary.pdb" \
36+
$type1at = "C:\\\\Users\\\\Admin\\\\Desktop\\\\ConsoleApp1\\\\ConsoleApp1\\\\obj\\\\Debug\\\\ConsoleApp1.pdb" \
37+
$type1sql = "Not a valid SQLite 3 Database File" wide \
38+
condition: all of them}',
39+
'namespace2' : 'rule Agenttesla_type2 { \
40+
strings: \
41+
$type2db1 = "1.85 (Hash, version 2, native byte-order)" wide \
42+
$type2db2 = "Unknow database format" wide \
43+
$type2db3 = "SQLite format 3" wide \
3844
condition: all of them}'
3945
}
4046

@@ -59,15 +65,51 @@ def get_vad_base(self, task, address):
5965

6066
return None
6167

62-
def strings(self, data, n=18):
68+
def base64strings(self, data, n=18):
6369
for match in re.finditer(("(([0-9a-z-A-Z\+/]\x00){%s}([0-9a-z-A-Z\+/]\x00)*(=\x00){0,2})" % n).encode(), data):
6470
yield match.group(0)
6571

66-
def stringdecrypt(self, a):
72+
def remove_unascii(self, b):
73+
cleaned = ""
74+
for i in b:
75+
if ord(i) >= 0x20 and ord(i) < 0x7f:
76+
cleaned += i
77+
return cleaned
78+
79+
def stringdecrypt_type1(self, a):
6780
string = b64decode(a)
6881
cleartext = AES.new(KEY[0:32], AES.MODE_CBC, IV).decrypt(string)
6982
return cleartext
7083

84+
def stringdecrypt_type2(self, data):
85+
encdata = data[0x2050:]
86+
87+
dlist = OrderedDict()
88+
offset = 0
89+
num = 0
90+
i = 16
91+
while True:
92+
key = encdata[offset:offset + 32]
93+
iv = encdata[offset + 32:offset + 48]
94+
enc_data =encdata[offset + 48:offset + 48 + i]
95+
96+
if b"\x00\x00" in key and b"\x00\x00" in iv:
97+
break
98+
99+
try:
100+
cleartext = AES.new(key, AES.MODE_CBC, iv).decrypt(enc_data)
101+
if len(cleartext) and (ord(cleartext[-1]) <= 0x10 or self.remove_unascii(cleartext) % 16 == 0) and not (ord(cleartext[-2]) == 0x0d and ord(cleartext[-1]) == 0x0a):
102+
dlist["Encoded string " + str(num)] = self.remove_unascii(cleartext).rstrip()
103+
offset = offset + 48 + i
104+
num += 1
105+
i = 0
106+
else:
107+
i += 16
108+
except:
109+
i += 16
110+
111+
return dlist
112+
71113
def calculate(self):
72114

73115
if not has_yara:
@@ -94,14 +136,18 @@ def calculate(self):
94136
data = proc_addr_space.zread(vad_base_addr, end - vad_base_addr)
95137

96138
config_data = []
97-
dlist = {}
98-
for word in self.strings(data):
99-
try:
100-
dec = self.stringdecrypt(word)
101-
dec = re.sub("([\x00,\x01,\x02,\x03,\x04,\x05,\x06,\x07,\x08,\x09,\x0a,\x0b,\x0c,\x0d,\x0e,\x0f,\x10]{1})", "\x00", dec)
102-
dlist[word.strip().replace('\0', '')] = dec.strip().replace("\n", "").replace("\r", "")
103-
except:
104-
pass
139+
dlist = OrderedDict()
140+
if "type1" in str(hit):
141+
for word in self.base64strings(data):
142+
try:
143+
dec = self.stringdecrypt_type1(word)
144+
dec = self.remove_unascii(dec).rstrip()
145+
dlist[word.strip().replace('\0', '')] = dec
146+
except:
147+
pass
148+
149+
if "type2" in str(hit):
150+
dlist = self.stringdecrypt_type2(data)
105151

106152
config_data.append(dlist)
107153

yara/rule.yara

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ rule Formbook {
388388
condition: all of them
389389
}
390390

391-
rule Agenttesla {
391+
rule Agenttesla_type1 {
392392
meta:
393393
description = "detect Agenttesla in memory"
394394
author = "JPCERT/CC Incident Response Group"
@@ -402,6 +402,21 @@ rule Agenttesla {
402402
condition: all of them
403403
}
404404

405+
rule Agenttesla_type2 {
406+
meta:
407+
description = "detect Agenttesla in memory"
408+
author = "JPCERT/CC Incident Response Group"
409+
rule_usage = "memory scan"
410+
reference = "internal research"
411+
hash1 = "670a00c65eb6f7c48c1e961068a1cb7fd3653bd29377161cd04bf15c9d010da2 "
412+
413+
strings:
414+
$type2db1 = "1.85 (Hash, version 2, native byte-order)" wide
415+
$type2db2 = "Unknow database format" wide
416+
$type2db3 = "SQLite format 3" wide
417+
condition: all of them
418+
}
419+
405420
rule Noderat {
406421
meta:
407422
description = "detect Noderat in memory"

0 commit comments

Comments
 (0)