3838quasar_sig = {
3939 'namespace1' : 'rule Quasar { \
4040 strings: \
41- $quasarstr1 = "[PRIVATE KEY LOCATION: \\ "{0} \\ "] " wide \
42- $quasarstr2 = "User: {0}{3}Pass: {1}{3}Host: {2}" wide \
43- $quasarstr3 = "Core.MouseKeyHook.WinApi" ascii fullword \
41+ $quasarstr1 = "Client.exe " wide \
42+ $quasarstr2 = "( {0}: {1}: {2}) " wide \
43+ $quasarstr3 = { 52 00 65 00 73 00 6F 00 75 00 72 00 63 00 65 00 73 00 00 17 69 00 6E 00 66 00 6F 00 72 00 6D 00 61 00 74 00 69 00 6F 00 6E 00 00 80 } \
4444 condition: all of them}'
4545}
4646
5959 8 : "ENCRYPTIONKEY" ,
6060 9 : "TAG" ,
6161 10 : "LOGDIRECTORYNAME" ,
62+ 11 : "unknown1" ,
63+ 12 : "unknown2"
6264}
6365
6466
@@ -76,31 +78,33 @@ def get_vad_base(self, task, address):
7678
7779 return None
7880
79- def decrypt_string (self , key , coded ):
80- mode = AES .MODE_CBC
81- if len (coded ) < 48 :
82- value = ""
83- else :
84- aes_iv = coded [32 :48 ]
85- cipher = AES .new (key , mode , IV = aes_iv )
86- value = cipher .decrypt (coded [48 :]).replace ('\x00 ' , '' ).replace ('\x0a ' , '' ).replace ('\x0b ' , '' )
81+ def decrypt_string (self , key , configs , mode ):
82+ p_data = OrderedDict ()
83+ for i , config in enumerate (configs ):
84+ if i not in [2 , 3 , 8 ]:
85+ if len (b64decode (config )) < 48 :
86+ value = config
87+ else :
88+ config = b64decode (config )
89+ aes_iv = config [32 :48 ]
90+ cipher = AES .new (key , mode , IV = aes_iv )
91+ value = re .sub ("[\x00 -\x19 ]" ,"" , cipher .decrypt (config [48 :]))
92+ else :
93+ value = config
94+ p_data [idx_list [i ]] = value
8795
88- return value
96+ return p_data
8997
9098 def parse_config (self , configs ):
91- i = 0
92- p_data = OrderedDict ()
9399 key , salt = configs [8 ], 'BFEB1E56FBCD973BB219022430A57843003D5644D21E62B9D4F180E7E6C33941' .decode ('hex' )
94100 generator = PBKDF2 (key , salt , 50000 )
95101 aes_key = generator .read (16 )
96102
97- for i , config in enumerate (configs ):
98- if i not in [2 , 3 , 8 ]:
99- try :
100- config = self .decrypt_string (aes_key , b64decode (config ))
101- except :
102- pass
103- p_data [idx_list [i ]] = config
103+ if (len (configs ) > 12 ):
104+ mode = AES .MODE_CFB
105+ else :
106+ mode = AES .MODE_CBC
107+ p_data = self .decrypt_string (aes_key , configs , mode )
104108
105109 return p_data
106110
@@ -148,13 +152,15 @@ def calculate(self):
148152 if ord (data [offset ]) == 0x80 or ord (data [offset ]) == 0x81 :
149153 string_len = ord (data [offset + 1 ]) + ((ord (data [offset ]) - 0x80 ) * 256 )
150154 offset += 1
155+
151156 offset += 1
152157 for i in range (string_len ):
153158 if data [offset + i ] != "\x00 " :
154159 strings .append (data [offset + i ])
155160 configs .append ("" .join (strings ))
156161 offset = offset + string_len
157- if len (configs ) > 10 :
162+
163+ if ord (data [offset ]) < 0x20 :
158164 break
159165
160166 config_data .append (self .parse_config (configs ))
0 commit comments