创建schtasks.exe文件
参数: "C:\Windows\System32\schtasks.exe" /Create /TN "Updates\vsqbOQbkJjh" /XML "C:\Users\xxx\AppData\Local\Temp\tmpC0FD.tmp"'
创建了自己
创建C:\Users\xxx\AppData\Roaming\vsqbOQbkJjh.exe文件 并写入数据
在临时文件夹下创建tmpC0FD.tmp 写入数据
注册表监控
删除注册表
网络监控
发送数据 数据未加密
进程监控
创建挂起进程 写入数据 恢复进程
创建自己 写入数据 读内存修改属性 设置线程上下文 最后恢复进程
行为监控
自我复制C:\Users\xxx\AppData\Roaming\vsqbOQbkJjh.exe
代码第一层-字符串资源解密
资源字符串 为第二层要执行的代码(未解密)
解密函数
通过base64解码 得到下一层PE文件
Dump出来以后是一个dll文件
第二层-图片资源解密
获取图片资源
解密得到第三层
第三层
拷贝自己到C:\Users\xxxx\AppData\Roaming文件夹 文件名称为vsqbOQbkJjh.exe
创建计划任务
任务名称:vsqbOQbJjh
创建者:WIN-U8DNL3N3GKJ\pc
触发信息:登录WIN-U8DNL3N3GKJ\pc时
操作:启动程序C:\Users\pc\AppData\Roaming\vsqbOQbkJjh.exe
创建自己
获取线程上下文
像新创建的进程写入PE文件 设置新的eip
并激活线程
第四层开始运行
第四层
程序所需字符串硬编码到数组里
程序开始运行会调用此方法解密字符串
程序会通过下标和大小返回自身所需的字符串 共有772条
关闭自身重复进程
创建http请求 url: http://nSfkEw.com
最后运行此文件
复制自身 通过注册表自启动
重命名tmpG769.tmp 将自己拷贝到C:\Users\xxxx\AppData\Local\Temp\ 实现自我删除
要窃取的浏览器客户端
Chedot,Kometa,Brave,Coowon,Cool Novo,Iridium Browser,Citrio,Sputnik,Opera Browser,7Star, Yandex Browser,Liebao Browser,Chromium,Torch Browser,360 Browser,Sleipnir 6,Epic Privacy, Orbitum,QIP Surf,Uran,Vivaldi,Amigo,CentBrowser,Coccoc,Elements Browser,Elements Browser
屏幕截图
创建计时器 获取屏幕截图
将此图像以指定的格式保存到指定的流中
通过http发送到服务器
键盘记录
记录被感染者的键盘信息
创建计时器 发送记录的键值
通过电子邮件发送用户信息
发件邮箱:[email protected]
发件邮箱密码:Gdn4ford@2016
主机地址:mail.focuzauto.com
端口:587
回传邮箱地址:[email protected]
邮件主题:"PW_xxxx/WIN-UL8QQFCU9CJ"
邮件正文:
"Time: 07/07/2022 10:54:16
User Name: xxxx
Computer Name: WIN-UxxxxFCU9CJ
OSFullName: Microsoft Windows 7 专业版
CPU: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
RAM: 2703.49 MB
创建FTP请求
发送内容 以xml文件格式发送
PW_xxxx-WIN-UL8QQFCU9CJ_2022_07_07_13_34_10.html
"Time: 07/07/2022 13:34:10
User Name: xxxx
Computer Name: WIN-UxxxxU9CJ
OSFullName: Microsoft Windows 7 专业版
CPU: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
RAM: 2703.49 MB
创建http请求
以表单的形式 传输数据
下载tor客户端
网址:
https://www.theonionrouter.com/dist.torproject.org/torbrowser/9.5.3/tor-win32-0.4.3.6.zip
下载到:
C:\Users\xxxx\AppData\Roaming\Tor\tor.zip
匿名传输数据
Ioc
MD5 | URL | |
---|---|---|
39F524C1AB0EB76DFD79B2852E5E8C39 | [email protected] | http://nSfkEw.com |
8A171A85D778196517E737D9EF23D3DB | mail.focuzauto.com | |
81F86EFD54CA768968830299ABE776FA |
配置提取工具:
import re
import pathlib
import os
import shutil
from collections import deque
#from matplotlib.style
class AgentTeslaAnalysis():
version = '1.0.0'
def __init__(self, folder):
self.folder = folder
self.code = None
self.property_dict1 = {}
self.property_dict = {}
self.property_map = {
'.Host =': self._extract_email_host,
'NetworkCredential': self._extract_email_u_p,
'NameValueCollection': self._extract_Http_host,
'WebRequest.Create' : self._extract_Tor_host
}
self.config = {}
def process(self):
for _ in pathlib.Path(self.folder).rglob("*"):
if not os.path.isfile(str(_)): continue
with open(str(_), 'r') as fp:
file_stream = fp.read()
if re.search(r'(public static [\d\w]+ [\d\w]+ \= .*?;[\n\t ]+){1,}',file_stream):
self.code = file_stream
self.create_mapping()
for _ in pathlib.Path(self.folder).rglob("*"):
if not os.path.isfile(str(_)): continue
with open(str(_), 'r') as fp:
file_stream = fp.read()
if re.search(
r'internal static byte\[\] {1,}= {1,}new byte\[\d+\].*?\{([\t\n\d ]+,{0,1}){500,}[\n\t]+\}',
file_stream, re.DOTALL):
self.code = file_stream
self.config_extract()
return
def create_mapping(self):
if re.search(r'public static string [\d\w]+ \= .*?\.[\d\w]+\(\)',self.code):
for _ in re.findall(r'public static string [\d\w]+ \= .*?\.[\d\w]+\(\)',self.code):
_list =re.findall(r'public static string ([\d\w]+) \= .*?\.([\d\w]+)\(\)',_)
self.property_dict1[_list[0][0]] = _list[0][1]
_list.clear()
def config_extract(self):
iter_bytes = re.search(
r'internal static byte\[\] {1,}= {1,}new byte\[\d+\].*?\{([\t\n\d ]+,{0,1}){500,}[\n\t]+\}',
self.code, re.DOTALL).group()
enc_bytes = []
for _ in re.findall(r'[\n\t ]+(\d{1,3})', iter_bytes):
enc_bytes.append(int(_))
xor_key = re.search(r'\^ i\) \^ (0x[A-Fa-f0-9]{2})u', self.code)
if xor_key:
xor_key = int(re.findall(r'0x([a-fA-F0-9]{2})', xor_key.group())[0], 16)
def decrypt(key, enc_array):
res = []
for index, _ in enumerate(enc_array):
res.append(((_ ^ index) ^ xor_key) & 0xFF)
return res
dec_bytes = decrypt(xor_key, enc_bytes)
for _ in re.findall(
r'public static string ([\d\w]+)\(\).*?\{.*?return .*?\.\[\d+\] \?\? \(\d+, (\d+), (\d+)\);.*?\}',
self.code, re.DOTALL):
self.property_dict[_[0]] = ''.join([chr(c) for c in dec_bytes[int(_[1]): int(_[1]) + int(_[2])]])
for _ in pathlib.Path(self.folder).rglob("*"):
if not os.path.isfile(str(_)): continue
reback_code = deque(maxlen=3)
with open(str(_), 'r') as fp:
for code_line in fp.readlines():
reback_code.append(code_line)
for k, v in self.property_map.items():
if code_line.find(k) >= 0:
v(list(reback_code))
def _extract_Tor_host(self, code_line):
if re.search(r'HttpWebRequest .*? \= \(HttpWebRequest\)WebRequest\.Create\(.*?\)',code_line[-1]):
if re.search(r'string .*? \= .*?\.[\d\w]+\(\)',code_line[-2]):
[http_TorProxy_host] = re.findall(r'string .*? \= .*?\.([\d\w]+)\(\)',code_line[-2])
self.config["http_TorProxy_host"] = self.property_dict.get(http_TorProxy_host,'')
#邮箱的host完成
def _extract_email_host(self, code_line):
code_line = code_line[-1]
value_data = code_line.split('=')[1]
if re.search(r'\.[\d\w]+\(\)', value_data):
key = re.findall(r'\.([\d\w]+)\(\)', value_data)[0]
if key in self.property_dict:
self.config['EmailHost'] = self.property_dict[key]
elif re.search(r'global\:\:.\..\..\..',value_data):
key = re.findall(r'global\:\:.\..\..\.(.)', value_data)[0]
self.config['EmailHost'] = self.property_dict[self.property_dict1[key[0]]]
def _extract_Http_host(self,code_line):
if re.search(r'global\:\:.\..\..\...*?, {1,}.*?\, {1,}.*?\, {1,}.*?\.[\d\w]+\(\)\, {1,}.*?\, {1,}\(NameValueCollection\).*?\)', code_line[-1]):
[httpHost] = re.findall(
r'global\:\:.\..\..\.(.).*?, {1,}.*?\, {1,}.*?\, {1,}.*?\.[\d\w]+\(\)\, {1,}.*?\, {1,}\(NameValueCollection\).*?\)',
code_line[-1])
self.config['httpHost'] = self.property_dict.get(httpHost[0], '')
if re.search(r'.*?\(.*?\.[\d\w]+\(\)\, {1,}.*?\, {1,}.*?\, {1,}.*?\.[\d\w]+\(\)\, {1,}.*?\, {1,}\(NameValueCollection\).*?\)', code_line[-1]):
[httpHost] = re.findall(r'.*?\(.*?\.([\d\w]+)\(\)\, {1,}.*?\, {1,}.*?\, {1,}.*?\.[\d\w]+\(\)\, {1,}.*?\, {1,}\(NameValueCollection\).*?\)', code_line[-1])
self.config['httpHost'] = self.property_dict.get(httpHost, '')
#邮箱和ftp
def _extract_email_u_p(self, code_line):
mode = 'Email'
for _ in code_line:
if _.find("WebRequest.Create") >= 0:
if re.search(r'WebRequest\.Create\([\d\w_-]+\.[\d\w]+\(\) \+ .*?\)', code_line[1]):
[FtpHost] =re.findall(r'WebRequest\.Create\(.*?\.([\d\w]+)\(\) \+ .*?\)', code_line[1])
self.config['FtpHost'] = self.property_dict.get(FtpHost, '')
elif re.search(r'WebRequest\.Create\(global::.\..\..\.. .*?\)', code_line[1]):
key = re.findall(r'WebRequest\.Create\(global::.\..\..\.(.) .*?\)', code_line[1])
FtpHost = self.property_dict1[key[0]]
self.config['FtpHost'] = self.property_dict.get(FtpHost, '')
if _.find("ftp") != -1 and _.find("NetworkCredential") != -1 :
mode = 'Ftp'
break
if re.search(r'NetworkCredential\([\d\w_-]+\.[\d\w]+\(\), {1,}[\d\w_-]+\.[\d\w]+\(\)\)', code_line[2]):
[user, password] = \
re.findall(r'NetworkCredential\([\d\w_-]+\.([\d\w]+)\(\), {1,}[\d\w_-]+\.([\d\w]+)\(\)\)', code_line[2])[0]
if user and password and (user in self.property_dict or password in self.property_dict):
self.config[f'{mode}UserName'] = self.property_dict.get(user, '')
self.config[f'{mode}Password'] = self.property_dict.get(password, '')
if re.search(r'NetworkCredential\(global\:\:.\..\..\..\, global\:\:.\..\..\..\)', code_line[2]):
key = re.findall(r'NetworkCredential\(global\:\:.\..\..\.(.)\, global\:\:.\..\..\.(.)\)', code_line[2])
self.config[f'{mode}UserName'] = self.property_dict.get(self.property_dict1[key[0][0]], '')
self.config[f'{mode}Password'] = self.property_dict.get(self.property_dict1[key[0][1]], '')
key.clear()
if __name__ == '__main__':
if os.path.exists(".\\file"):
shutil.rmtree(".\\file")
os.system(".\\ilspycmd\\ilspycmd.exe -p -o .\\file " + input("文件路径: "))
A = AgentTeslaAnalysis(".\\file")
A.process()
print(A.config)