【软件逆向-Discord Stealer样本分析】此文章归类为:软件逆向。
样本名称为RockPaperScissors.exe,MD5:7b6e1adf588ce77419920593970292fb,由C#编写。

没有混淆,首先获取黑名单数组,检测当前用户是否在黑名单中,如果不在黑名单中,则异步任务调用Program.<>c.<>9.<Main>.<b__6_0>()方法Program.<>c.<>9.<Main>.<b__6_1>()方法,然后获取本地应用程序数据文件夹路径(即C:\Users\用户名\AppData\Local)并启动异步任务调用Program.<>c.<>9.<Main>.<b__6_2>()方法、Program.<>c.<>9.<Main>.<b__6_3>()**方法,最后调用 Program.RPS()方法,如果在黑名单内,则调用Program.RPS() 方法,Program.RPS()方法是石头剪刀布(Rock, Paper, Scissors)游戏。

blacklistUsers如下:
|
1
|
WDAGUtilityAccount、
3W1GJT
、QZSBJVWM、
5ISYH9SH
、Abby、hmarc、patex、RDhJ0CNFevzX、kEecfMwgj、Frank、
8Nl0ColNQ5bq
、Lisa、John、george、PxmdUOpVyx、
8VizSM
、w0fjuOVmCcP5A、lmVwjj9b、PqONjHVwexsS、
3u2v9m8
、Julia、HEUeRzl、fred、server、BvJChRPnsxn、Harry Johnson、SqgFOf3G、Lucas、mike、PateX、h7dk1xPr、Louise、User01、test、RGzcBUyrznReg、
05h00Gi0
、
43By4
、
4tgiizsLimS
、
6O4KyHhJXBiR
、
7wjlGX7PjlW4
、Amy、AppOnFlySupport、ASPNET、azure、BUiA1hkm、cM0uEGN4do、cMkNdS6、DefaultAccount、dOuyo8RV71、DVrzi、e60UW、ecVtZ5wE、EGG0p、G2DbYLDgzz8Y、GjBsjb、Guest、ICQja5iT、IVwoKUF、j6SHA37KA、j7pNjWM、jude、kFu0lQwgX5P、KUv3bT4、lK3zMR、l3cnbB8Ar5b8、lmVwjj9b、Louise、Lucas、mike、Mr.
None
、noK4zG7ZhOf、o6jdigq、o8yTi52T、OgJb6GqgK0O、PgfV1X、pWOuqdTDQ、PxmdUOpVyx、QfofoG、QmIS5df7u、QORxJKNk、qZo9A、S7Wjuf、sal.rosenburg、Steve、TVM、txWas1m2t、umyUJ、Uox1tzaMO、vzY4jmH0Jw02、XMiMmcKziitD、xPLyvzr8sgC、ykj0egq7fze、DdQrgc、ryjIJKIrOMs、nZAp7UBVaS1、zOEsT、xUnUy、fNBDSlDTXY、gu17B、UiQcX、
21zLucUnfI85
、OZFUCOD6、
8LnfAai9QdJR
、
5sIBK
、rB5BnfuR2、GexwjQdjXG、IZZuXj、ymONofg、dxd8DJ7c、JAW4Dz0、GJAm1NxXVm、UspG1y1C、equZE3J、BXw7q、lubi53aN14cU、
5Y3y73
、
9yjCPsEYIMH
、GGw8NR、JcOtj17dZx、
05KvAUQKPQ
、
64F2tKIqO5
、
7DBgdxu
、uHUQIuwoEFU、gL50ksOp、Of20XqH4VL、tHiF2T、dx、jz、WALKER
|
通过这个用户名黑名单列表,在github发现了名为和的项目,这两个项目由python编写,Ethical-Stealer参考了Creal-Stealer的很多逻辑和代码,可以窃取密码、Token、Cookie、加密货币等等等,同时找到VirusTotal博客2023年6月份的一篇文章:,也提到了Creal-Stealer,可以推测这个样本的主要功能也与Stealer相关,这个用户名黑名单列表的作用是检查当前程序是否在 VirusTotal 沙箱中运行。除此之外,亦发现了另一个项目,blacklistUsers参考了里面的pc_username_list.txt,顺便对比了下两个黑名单列表,blacklistUsers比pc_username_list.txt多了三个,分别是:dx、jz、WALKER。
私有密封类<>c,匿名委托方法<FRFRFRFRFRF>b__14_0(Process p),检索名为"discord"的进程、匿名方法<Main>b__6_0()调用Program.GetScreenshot()方法来获取屏幕截图发送至指定的Discord Webhook URL、匿名方法<Main>b__6_1()调用了Program.addstartupnonadmin()方法,通过方法命名推测其功能为非在管理员账户下实现自启动、匿名方法 <Main>b__6_2()发送密码至指定的Discord Webhook URL、匿名方法 <Main>b__6_2()调用了一个Program.GreenToast()方法,可能与通知相关。

Program.addstartupnonadmin()方法,在注册表键SOFTWARE\Microsoft\Windows\CurrentVersion\Run下添加一个注册表值,值的内容为 $77 + 当前程序文件的名称,该值的数据部分是当前程序的位置,实现开机自启动。

Program.GreenToast()方法,再次检测用户名是否在用户名黑名单中,如果在用户名黑名单中,则调用Program.Yellowtoast()方法,然后终止当前程序的执行;如果不在用户名黑名单中,首先调用 TheFrrMonster.TheFRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR() 方法,返回一个字符串列表,然后遍历字符串列表,将每个字符串添加到 Program.father 变量中,接着调用 Program.SendWEBBY() 方法,解析处理并发送Program.father 到指定的 Discord Webhook URL,最后调用 Program.FRFRFRFRFRF() 方法。

Program.Yellowtoast()方法,调用RtlAdjustPrivilege提权,19(0x13)对应特权常量SeShutdownPrivilege,即关机权限,一旦提权成功,接着调用NtRaiseHardError设置错误码为0xC0000022,可引发蓝屏(BSOD )。

Program.TheFRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR() 方法,创建了一个空的字符串列表list,循环遍历字符串数组,将字符串解码后拼接成文件路径,检查指定文件是否存在,如果存在则调用TheFrrMonster.GrabTokens方法,并将结果添加到"list"中。

解码字符串如下,获取特定的所在的Local Storage\leveldb、 User Data、User Data\Default、\Local State等目录信息。浏览器列表:Amigo、Torch、Kometa、Google Chrome、Orbitum、CentBrowser、7Star、Sputnik、Vivaldi、Google Chrome SxS、Epic Privacy Browser、Uran、Microsoft Edge、Yandex、Opera Neon、Brave-Browser
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
\AppData
\Local Storage\leveldb
\Roaming v
+
discord
\Roaming v
+
discordptb
\Roaming v
+
discordcanary
\Roaming v
+
discorddevelopment
\Roaming v
+
Opera Software Opera Stable
\Roaming v
+
Opera Software Opera GX Stable
\Local\Amigo\User Data
\Local\Torch\User Data
\Local\Kometa\User Data
\Local\Google\Chrome\User Data\Default
\Local\Orbitum\User Data
\Local\CentBrowser\User Data
\Local\
7Star
\
7Star
\User Data
\Local\Sputnik\Sputnik\User Data
\Local\Vivaldi\User Data\Default
\Local\Google\Chrome SxS\User Data
\Local\Epic Privacy Browser\User Data
\Local\uCozMedia\Uran\User Data\Default
\Local\Microsoft\Edge\User Data\Default
\Local\Yandex\YandexBrowser\User Data\Default
\Local\Opera Software\Opera Neon\User Data\Default
\Local\BraveSoftware\Brave
-
Browser\User Data\Default
|
TheFrrMonster.GrabTokens方法,用于获取浏览器保存的Discord toke,三个正则: [\\w-]{24}\.[\\w-]{6}\.[\\w-]{27}、mfa\.[\\w-]{84}、(dQw4w9WgXcQ:)([\^.*\\['(.*)'\\].*$][^\"]*),前两个正则用于直接匹配Discord token,第三个正则匹配到成功则会调用DecryptToken方法解密dQw4w9WgXcQ:后的部分,解密算法为AES-GCM。关于具体密钥获取和解密逻辑,可参阅github项目

获取Discord toke成功后调用Distinct去重,通过token和WebClient 获取用户数据

Program.SendWEBBY() 方法,从Discord API返回的JSON数据中解析详细的用户信息,然后将用户名(username)、鉴别器(discriminator,通常是一个四位数),用户ID(user ID)添加到一个列表(list)中, 接着将 Discord Token 以YAML格式添加到一个list中,同时创建一个包含 Discord Token 复制链接的项,再把用户的2FA和验证状态、将.gif或.png格式的链接形式的用户头像的信息添加到 list 中,最后,相关信息经格式化处理之后,将Discord用户相关信息发送至指定的Discord Webhook URL。

在Program.SendWEBBY() 方法中,包含一个frfrfrfrfrfrfrfrfrfr()方法,向 Discord API 发送请求,获取与已认证用户相关的结算/支付信息。

发送Discord Webhook URL的消息标题被设置为 Anthemia logger <:TrackerPFP:1089051195722706964>

将获取的token和用户相关信息发送至指定Discord Webhook URL后,会调用FRFRFRFRFRF() 方法。关闭所有与 Discord 相关的进程,并检查特定的Discord目录是否存在,并在discord 客户端注入名为index.js的脚本文件,修改discord 客户端以实现一些定制化的功能。

被注入的js文件较长,通过 JavaScript文件的配置信息可以窥见其主要功能如下,其详细功能见
1.webhook: Discord Webhook 的 URL,用于将信息发送到指定的 Discord 服务器或频道。
2.webhook_protector_key: Webhook 保护密钥。
3.auto_buy_nitro: 一个布尔值,表示是否启用自动购买 Nitro 的功能。
4.ping_on_run: 一个布尔值,表示是否在运行时通过 ping_val 提及(ping)所有人。
5.ping_val: 在运行时提及(ping)的消息内容,通常是 @everyone。
6.embed_name: 发送到 Discord 的消息中嵌入的名称。
7.embed_icon: 发送到 Discord 的消息中嵌入的图标的 URL。
8.embed_color: 发送到 Discord 的消息中嵌入的颜色。
9.injection_url: Discord 注入脚本的 URL。
10.api: Discord 用户信息 API 的 URL。
11.nitro: 包含 Nitro 订阅计划的对象。
12.boost: 包含 Nitro Boost 订阅计划。
13.year: 年订阅计划的详细信息。
14.month: 月订阅计划的详细信息。
15.classic: 包含经典 Nitro 订阅计划。
16.filter: 包含需要过滤的 URL 列表,用于监听 Discord API 请求。
17.filter2: 包含需要过滤的第二个 URL 列表,用于监听其他 Discord 相关请求。
|
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
|
const config = {
webhook:
'hxxps://discord[.]com/api/webhooks/1095580593544237088/P6vEnIM_dngrti7YjsQG7J5vsRaMY6EFlxxj-kMLNU-6Hnb1d4PHjrHUDlAsLXtBJHew'
,
webhook_protector_key:
'%WEBHOOK_KEY%'
,
auto_buy_nitro:
false
,
ping_on_run:
false
,
ping_val:
'@everyone'
,
embed_name:
'Fr injection'
,
embed_icon:
'hxxps://cdn.discordapp[.]com/attachments/1077267633365340172/1094133346788970556/582387.png'
,
embed_color: 0,
injection_url:
'hxxps://raw.githubusercontent[.]com/Anthemiaa/fr/main/clean.js'
,
api:
'https://discord.com/api/v9/users/@me'
,
nitro: {
boost: {
year: {
id:
'521847234246082599'
,
sku:
'511651885459963904'
,
price:
'9999'
,
},
month: {
id:
'521847234246082599'
,
sku:
'511651880837840896'
,
price:
'999'
,
},
},
classic: {
month: {
id:
'521846918637420545'
,
sku:
'511651871736201216'
,
price:
'499'
,
},
},
},
filter: {
urls: [
'https://discord.com/api/v*/users/@me'
,
'https://discordapp.com/api/v*/users/@me'
,
'https://*.discord.com/api/v*/users/@me'
,
'https://discordapp.com/api/v*/auth/login'
,
'https://discord.com/api/v*/auth/login'
,
'https://*.discord.com/api/v*/auth/login'
,
'https://api.braintreegateway.com/merchants/49pp2rp4phym7387/client_api/v*/payment_methods/paypal_accounts'
,
'https://api.stripe.com/v*/tokens'
,
'https://api.stripe.com/v*/setup_intents/*/confirm'
,
'https://api.stripe.com/v*/payment_intents/*/confirm'
,
],
},
filter2: {
urls: [
'https://status.discord.com/api/v*/scheduled-maintenances/upcoming.json'
,
'https://*.discord.com/api/v*/applications/detectable'
,
'https://discord.com/api/v*/applications/detectable'
,
'https://*.discord.com/api/v*/users/@me/library'
,
'https://discord.com/api/v*/users/@me/library'
,
'wss://remote-auth-gateway.discord.gg/*'
,
],
},
};
|
该样本还会下载名为PasswordStealer.dll的恶意dll文件并加载执行类PasswordStealer.Stealer 中的Run方法。该恶意dll托管在github,hxxps://raw.githubusercontent[.]com/Anthemiaa/fr/master/PasswordStealer.dll

github用户名为 Anthemiaa

PasswordStealer.dll同目录下还有一个名为clean.js的文件,功能与index.js几乎一致。
MD5:ef4265e61daa8c0c8db8d40744196b11

通过Chromium.Grab()方法窃取基于 chromium 的浏览器相关浏览器中保存的url、账户和密码信息,如:Hostname (账户相关的网站 URL,origin_url)、
Username(用户名,username_value)、Password(密码,password_value),其逻辑与Browser-password-stealer类似,针对基于 chromium 的浏览器。

通过FirefoxPassReader方法,窃取Firefox浏览器中保存的url、账户和密码信息,其获取逻辑与 基本一致。

窃取FileZilla 应用程序的密码等信息。FileZilla是一个FTP客户端软件,其历史记录以纯文本形式存储在文件“%APPDATA%\filezilla\recentservers.xml”中,并将其登录数据存储在文件“%APPDATA%\filezilla\sitemanager.xml”中。

窃取NordVPN的密码等信息。

窃取Outlook密码等信息。遍历注册表中与 Outlook 配置文件相关的子键,并尝试获取 IMAP、POP3、HTTP 和 SMTP 密码。

7b6e1adf588ce77419920593970292fb
ef4265e61daa8c0c8db8d40744196b11
hxxps://raw.githubusercontent[.]com/Anthemiaa/fr/master
更多【软件逆向-Discord Stealer样本分析】相关视频教程:www.yxfzedu.com