查看原文
其他

Discord Stealer样本分析

megaparsec 看雪学苑 2024-03-10




基本信息


样本名称为RockPaperScissors.exe,MD5:7b6e1adf588ce77419920593970292fb,由C#编写。





Discord Stealer分析


Main

没有混淆,首先获取黑名单数组,检测当前用户是否在黑名单中,如果不在黑名单中,则异步任务调用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如下:

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发现了名为Creal-Stealer(https://github.com/Ayhuuu/Creal-Stealer/tree/main)Ethical-Stealer(https://github.com/WiredZXZ/Ethical-Stealer/tree/main)的项目,这两个项目由python编写,Ethical-Stealer参考了Creal-Stealer的很多逻辑和代码,可以窃取密码、Token、Cookie、加密货币等等等,同时找到VirusTotal博客2023年6月份的一篇文章:Inside of the WASP's nest: deep dive into PyPI-hosted malware(https://blog.virustotal.com/2023/06/inside-of-wasps-nest-deep-dive-into.html),也提到了Creal-Stealer,可以推测这个样本的主要功能也与Stealer相关,这个用户名黑名单列表的作用是检查当前程序是否在 VirusTotal 沙箱中运行。除此之外,亦发现了另一个项目virustotal-vm-blacklist(https://github.com/6nz/virustotal-vm-blacklist),blacklistUsers参考了里面的pc_username_list.txt,顺便对比了下两个黑名单列表,blacklistUsers比pc_username_list.txt多了三个,分别是:dx、jz、WALKER。

类<>c

私有密封类<>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()方法

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

Program.GreenToast()方法

Program.GreenToast()方法,再次检测用户名是否在用户名黑名单中,如果在用户名黑名单中,则调用Program.Yellowtoast()方法,然后终止当前程序的执行。

如果不在用户名黑名单中,首先调用TheFrrMonster.TheFRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR()方法,返回一个字符串列表,然后遍历字符串列表,将每个字符串添加到 Program.father 变量中,接着调用 Program.SendWEBBY() 方法,解析处理并发送Program.father 到指定的 Discord Webhook URL,最后调用Program.FRFRFRFRFRF()方法。

Program.Yellowtoast()方法

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

Program.TheFR{49}() 方法

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

\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方法

TheFrrMonster.GrabTokens方法,用于获取浏览器保存的Discord toke,三个正则:[\\w-]{24}\.[\\w-]{6}\.[\\w-]{27}、mfa\.[\\w-]{84}、(dQw4w9WgXcQ:)([\^.*\\['(.*)'\\].*$][^\"]*),前两个正则用于直接匹配Discord token,第三个正则匹配到成功则会调用DecryptToken方法解密dQw4w9WgXcQ:后的部分,解密算法为AES-GCM。关于具体密钥获取和解密逻辑,可参阅github项目Browser-password-stealer(https://github.com/henry-richard7/Browser-password-stealer/blob/master/chromium_based_browsers.py)


获取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>

Program.FRFRFRFRFRF() 方法

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


被注入的js文件较长,通过 JavaScript文件的配置信息可以窥见其主要功能如下,其详细功能见https://www.trendmicro.com/ja_jp/research/23/h/info-stealer-abusing-codespaces-puts-discord-users--data-at-risk.html

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 相关请求。

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/*',
],
},
};


LoadDll

该样本还会下载名为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几乎一致。





PasswordStealer.dll


基本信息

MD5:ef4265e61daa8c0c8db8d40744196b11


PasswordStealer分析

Stealer.run()方法

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


通过FirefoxPassReader方法,窃取Firefox浏览器中保存的url、账户和密码信息,其获取逻辑与https://github.com/unode/firefox_decrypt/blob/main/firefox_decrypt.py基本一致。


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


窃取NordVPN的密码等信息:


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


IOCs

7b6e1adf588ce77419920593970292fb
ef4265e61daa8c0c8db8d40744196b11
hxxps://raw.githubusercontent[.]com/Anthemiaa/fr/master




看雪ID:megaparsec

https://bbs.kanxue.com/user-home-917207.htm

*本文为看雪论坛优秀文章,由 megaparsec 原创,转载请注明来自看雪社区



# 往期推荐

1、区块链智能合约逆向-合约创建-调用执行流程分析

2、在Windows平台使用VS2022的MSVC编译LLVM16

3、神挡杀神——揭开世界第一手游保护nProtect的神秘面纱

4、为什么在ASLR机制下DLL文件在不同进程中加载的基址相同

5、2022QWB final RDP

6、华为杯研究生国赛 adv_lua



球分享

球点赞

球在看


点击阅读原文查看更多

继续滑动看下一个

Discord Stealer样本分析

megaparsec 看雪学苑
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存