I have released a mod last night called Russian Roulette. It was supposed to show something, and a few curious modders looked into it extensively. This post serves as the explanation of what it did and why I did it.
Apologies for the rushed writing.
At first glance, Russian Roulette appears as a JAR that contains no code other than a @Mod class and a no-op preInit method. The only interesting thing about it, from an user’s perspective, is that it depends on a mod - Better Questing. It certainly has no malicious functionality - or functionality at all. However, if the following conditions are met, something else happens:
- Russian Roulette (and Better Questing) is installed on the client side,
- The user connects to a dedicated server with Better Questing installed,
- The user is not connecting to their own computer (localhost).
[00:51:20] [Netty Epoll Server IO #1/INFO] [FML]: Client attempting to join with 6 mods : firstname.lastname@example.org,email@example.com,FML@184.108.40.206,firstname.lastname@example.org,email@example.com,firstname.lastname@example.org [00:51:21] [Server thread/INFO] [FML]: [Server thread] Server side modded connection established [00:51:21] [Server thread/INFO] [net.minecraft.server.management.PlayerList]: asiekierka[/XX.XX.XX.XX:38786] logged in with entity id 1817 at (170.5, 69.0, 257.5) [00:51:21] [Server thread/INFO] [net.minecraft.server.dedicated.DedicatedServer]: asiekierka joined the game [00:51:28] [Server thread/INFO] [net.minecraft.network.NetHandlerPlayServer]: asiekierka lost connection: Tamper Nuked [00:51:28] [Server thread/INFO] [net.minecraft.server.dedicated.DedicatedServer]: asiekierka left the game [00:51:28] [Netty Epoll Server IO #1/INFO] [STDOUT]: [betterquesting.network.PacketAssembly:TnVrZU1lU2VucGFp:206]: [!] HACKER DETECTED [!] Player asiekierka was auto-banned. Reason: Using known hacking client [00:51:28] [Server thread/WARN] [net.minecraft.network.NetworkManager]: handleDisconnection() called twice
To explain what happened here - the connected user tripped the recently-discovered “tamper nuke” code in BetterQuesting, based solely on the inclusion of a specially-prepared, otherwise unsuspicious mod. The effect of this code is as follows:
- banning the user by UUID and IP,
- clearing their inventory, OP status, whitelist status, game mode, health,
- disconnecting all users connecting from the same IP, including the user who tripped it,
- clearing Better Questing progress and lives,
- notifying all players on the server that the disconnected player was a hacker, who was auto-banned.
The nuke logic is opt-out - it is enabled by default, but disableable using a config option. It also only affects dedicated multiplayer servers - I feel that this is important to clarify.
How does the detection work? It has two checks:
- sending a certain exploitable packet from an older version of the mod - newer versions of the mod should not be sending it, or
- detecting a “known hacking client”, which is done by either:
- finding a mod with a known string pointing to the usage of a specific hacked client in the class name or mod ID, or
- detecting “usage of process injection” - which is done by comparing if the ZIP comment (optional text embedded in a ZIP or JAR file) is a name of a class or subclass of the base mod class. As far as I understand, a certain hack client uses the ZIP comment field to find desirable classes - but I lack further information at this time.
The former check is executed on the server side. The latter is done on the client side, and the server is notified using lightly obfuscated code.
Russian Roulette, as explained above, appears innocent to an onlooker - it does not send any packets, it is not a coremod, it does not have a mod ID or class name reminiscent of popular hacking clients. However, it trips up the last check - the ZIP comment is not blank (as usual), but “pl.asie.russianroulette.RussianRoulette”.
The mod is my personal protest against the BetterQuesting creator’s execution of an anti-cheat mechanism, released initially in the form of a puzzle. I am strictly opposed to it and consider it incredibly irresponsible.
I have heard many arguments defending said executions. If possible, let me respond to some of them:
Had it been well-known, exploit developers would have adjusted their code to circumvent the check.
Yes. That is true. However, this code wasn’t particularly hidden - it was resistant to obvious string searches, but the mod’s configuration file made it perfectly clear that it contains such functionality:
# Bans and erases the data of known hacking clients [default: true] B:"Tamper Nuke"=true
In addition, as seen above, the disconnection logic states the obfuscated method name which was called - a reproduction case and a simple look with a debugger would make it trivial for exploiters to adjust their code regardless.
My particular problem is that it was opt-out. Had it been opt-in for server administrators, there would be no potential of element of surprise - explicit enabling of the feature would mean an administrator would be aware of the data erasing occurring, and could prepare accordingly (for example, make backups).
Server administrators asked for this feature to be added.
That does not prevent it from being opt-in - nay, it encourages doing so, since the administrators are implied to have been in communication with the mod developer in such a scenario.
There were no false positives when the exploit detection logic was being released!
This is different than PlusTiC because it has good intentions!
Yes. It does have good intentions - I’m not trying to deny this. There may have been no false positives - but we have already proven it’s possible to sneak one under the radar. It’s, to me, far more irresponsible than what Landmaster did, even if unquestionably more noble in concept. Let me explain why.
Let’s Nuke The Modding Community
All that it takes to flag a client as bannable is sneaking a crafted ZIP comment - a field most people don’t really check or consider, as verified by community reactions to the Roulette - into any Forge mod.
Let’s put myself in a different position now. Let’s imagine I am an attacker - my goal is to cause drama and suffering in the modding scene. (… wait, what? Are you saying this changes nothing at all!?)
In the past, there were multiple cases of illegitimate versions of mods being successfully uploaded to CurseForge. Projects like Tinker’s Construct and FastLeafDecay were affected. This means that tampering with a popular, highly-downloaded mod is not outside the realm of possibility. With some skill, I could inject malicious code to cause damage to people downloading my tampered version of the mod. There are some issues with this approach, though:
- The code would be blatantly visible to anyone comparing the official code and the tampered-with release. This means that, had the author come back, this would have been easily noticed and damage would be minimized.
- If the mod had been signed with a certificate, code tampering becomes even more blatantly visible - stealing the keys of a mod developer is not quite as trivial as hijacking an online account.
However, with the above I can turn any mod into a bomb in a far sneakier and non-obvious manner.
- I am tampering with the ZIP comment field, which is not always displayed or checked.
- All the files in the JAR continue to match the official release.
- In addition, the comment field is not part of a JAR signature - the mod continues to validate as signed.
- Finally, as we’ve seen from the above log, all the blame for banning the end user falls on Better Questing - buying me, as an attacker, a fair bit of time before the creator explains what happened and a hunt begins to find the malicious mod, while also causing lasting damage to anyone playing on a dedicated server without timely backups.
The end-game is when a popular modpack ends up including it. Many modpacks are not tested in a dedicated server scenario on every update, so the code would not be tripped then. Often, testing is also inadequate - I remember an obviously broken version of a mod which only lasted three hours being circulated for two weeks via a major modpack including it, back in late 2014. It’s a game of luck at that point.
Of course, this scenario probably would not happen overnight, but the code has been in the mod for three months - and it would have most likely not been removed had it not been pointed out publicly. In such a timeframe, it absolutely becomes possible, if still somewhat unlikely. A different option is to use a “number site” to circulate malicious, difficult to detect versions of existing mods - that is possibly significantly easier to execute.
Overall, this is the reason why I consider this specific execution incredibly irresponsible, and the public criticism of it absolutely justified. There were ways to make this far less damaging:
- Making it opt-in, and only configurable by the server administrator (not the modpack developer)! Any server administrator who studied the configuration file involved would then be able to turn the option on, fully understanding the repercussions.
- Making the server side only warn about a detected hacking mod, offering a
bq_nukecommand to “nuke” such users for the server administrator. Again, in this scenario creating lasting damage requires explicit consent, and in many cases could allow administrators to notice something is wrong - or make a backup.
- Making it a separate server-side-only mod which actually bans users, with one or multiple client-side mods containing the “snitch” logic. This approach still has some debatable issues with privacy violation, but also has some peculiar benefits:
- You could choose to distribute the server-side mod to only server administrators who ask about the problem, meaning that the cheat developers only ever saw one half of the equation - making figuring out the trigger far more difficult,
- It still requires explicit consent on the administrators’ side, satisfying my requirement for this being at all acceptable, as listed above.
- At the absolute least, Better Questing reporting which mod ID tripped it would have made detecting such a scenario for server administrators noticeably easier - but might have also made it easier to find for exploiters, albeit in my opinion not by a significant amount.
(There are some approaches which would make the anti-cheat harder to bypass, but they would definitely not fly as a quiet addition to an existing mod.)
Notice that I’m not recommending removing it outright - this is what ultimately happened, and what had to happen once the code was revealed to the public. However, one good argument made is that:
Had it been a separate mod, everyone would have known instantly.
That is ultimately a problem of anti-cheats - if everyone knows it’s there, people will try to attack and bypass it. Perhaps the best solution would have been to not do it at all - but that’s not really something I can recommend as a “fix” for the anti-cheat, much like I can’t reasonably recommend throwing out a computer as a solution to bugs in software - no matter how much I’d like to sometimes.
Thankfully, we have avoided the doomsday scenario I’m envisioning, instead it ending in an overnight Reddit drama. Honestly, I consider the justified criticism of the functionality to be the best possible scenario overall - minor or no damage has occurred, and the community will probably move on. Had the mod been silently removed from CurseForge, hundreds upon hundreds modpacks would break instantly. With lasting damage caused by a clever exploiter, the creator would receive a lot of the blame and trust in them would be eroded much more permanently in the eyes of any server administrator and player affected, not even mentioning the erosion of trust in the modding scene in general.
Also, let me just state this: the code has been removed in the latest release of BetterQuesting. An update is sufficient to make your modpack or server immune to this scenario.
Apologies for the post being long and rambly, but I hope this explains my view of the recent situation. Back to not-modding!
EDIT #1: Additional notes follow. Also, a clarification has been added as to the purpose of the ZIP comment check.
A quick guide to checking the behaviour yourself the way I had reproduced it:
- Set up a Forge server with (an affected version of) Better Questing installed. No need to touch the configs, or anything.
- Set up a Forge client instance with Better Questing and Russian Roulette on a different machine (the key - not connecting from localhost).
- Connect from the client to the server.
- Give it about 5-15 seconds, on average.
The post and my analysis has been criticized for presenting an implausible scenario. It is true that upon being able to tamper mods, you can cause far more damage - the reason this specific approach is so insidious is because (a) it misdirects the blame to another mod, making it take longer to detect the true reason behind the issue and (b) a ZIP comment can be applied to a signed JAR without breaking its verification, avoiding raising suspicions in such a case. Mod JARs from unknown, untrusted sources also don’t strictly require exploiting a modder account - another potential scenario involves a repost site, however this would probably not affect most modpacks as they tend to use exclusively mods available via CurseForge or trusted author websites, and the issue does not affect single-player worlds or LAN play.