Update: The exploit this was originally created to combat has been long since patched out by roblox and as such I have not updated this plugin in a long time. It may or may not still work but unless there is some severe need to continue this project I likely will not mess with this plugin anymore.
Due to a recent event where a game I am a part of the development team on started seeing a lot of severe server-sided exploit issues (Which we found really odd as the game was FilteringEnabled and had been coded with security in mind by experienced scripters) I have created a plugin which detects and removes hidden infections in the game. The short of the problem was that a malicious plugin injected a serverside backdoor into the game that was unable to be viewed or in any way detected by the user except in rare cases. After extensive searching in the game’s data that ultimately lead me to open the game’s place save file in xml into a text editor and reading line for line what was being stored I found the infection hiding in the “CSGDictionaryService” instance which is RobloxLocked security context level 6 (meaning neither plugins nor command bar has authority to index or otherwise touch that service.) They did this by abusing a glitch in the roblox engine which allows you to parent objects to robloxlocked instances but never be able to retrieve them again. I made a post about this in the exploit reports section of the forums and after consulting with other developers I wound up finding a method I could use to remove the infection from within plugin authority (script context level 5) and after tinkering on it a bit I have gone ahead and released this to the public. The plugin can remove any hidden backdoor/infection scripts that are outside of the proper areas as well as scan any existing script in the game for known infection code. Once found you can choose to either “Store” the infections found into a new folder in ServerStorage named “Infections” so that you can view their sources or “Delete” the infections found entirely from the game.
tl;dr: This plugin can remove infections injected by malicious (usually copied) plugins that would otherwise be difficult to remove.
Plugin: Hidden/Infection Script Detector - Roblox
How to use:
- Open your game
- Go to the plugins tab at the top
- Click the “Scan for infection” button in the toolbar
- (If the scan finds an infection) Click either “Store” or “Delete” in the GUI that opens.
- Check the output window for information. (Go to View → Output if you don’t see the Output window in Studio)
As of V2.1.0 this plugin now also checks for known malicious plugins. If you find a plugin with a malicious script that injects an infection into the user’s game please post it into the megathread so that I may add it to this plugin’s detection list and we can make it easier/faster for other users to be made aware of the malicious nature of the plugin as well as the original non-malicious plugin if known.
Glad to see that this is being posted publicly. It’s astounding that this is even possible but I’m glad we have the tools to combat it, albeit in a round about fashion.
I had a huge panic yesterday about an apparent attack to a game that hadn’t been released to the public yet (I’m sure you could find the topic if you wanted). You could even have the plugin check services that are invisible to the explorer because all of my infections were hiding in the TweenService, DebrisService and InsertService.
Thank you for this. Definitely have more security in mind after that attack.
The plugin already does this. It scans all services in the game including hidden and robloxlocked protected services. If the plugin didn’t catch the infections then please DM/PM me the infection scripts and I’ll add them to the known infections list which will contain them in the future.
That’s awesome. I had no idea this plugin existed at the time of my attack but I have downloaded it for constant checking
I just updated the plugin. It now has automated scanning, update checking, and a few more settings that I figured users would like. Be sure to update it in your studio for ease of use!
Thanks for this! Let’s just hope no hacker makes an infencted backdoor version of your plugin.
This is really cool! I definitely had a big scare when I read that post about a backdoor being added through a plugin in an area we can’t even see.
However, I do think it’s a bit unnerving to have it calling a module, although it’s open source, I’d personally much rather have the option of manually updating the plugin myself, rather than it being done automatically. While I understand it’s viewable by every user, the security of my games relies entirely on your account’s security and having it call an external module would allow for a wide range of attacks without the plugin user’s knowledge.
Perhaps I’m just too paranoid about these things, it’s a great plugin, but I’ll be removing that line or not using it at all. I may be the only person with this concern.
Would you feel better about it if I made it so you could toggle the require on/off with a setting in the settings gui?
Update: Just added this setting to the settings gui. You can now disable the plugin’s usage of require for auto-updating of the infections table. (If you do this then I recommend you check frequently to be sure the plugin is always up to date as I won’t be triggering an update notice for something small like updating the localized known infections table as the auto updater check is meant more for if I change the code in the plugin itself)
Added. Update the plugin to get the new setting.
PSA: The infection scripts are now attempting to hijack pre-existing scripts by appending the backdoor code to them. (I was expecting and ready for this since yesterday) Due to this the plugin now uses 2 requires but it can automatically remove the infection hijack code and replace it with a harmless comment that the plugin removed it. (This can be turned off in the settings) (He also got smart and made the variable names randomize each time the plugin injects them so I built a smart string.find system that allows me to pass wildcards in the form of multiple strings in a table so there is no character he can put that my systems can’t locate)
If you haven’t updated the plugin I recommend doing so now! The version as of this post is V1.1.0
P.S. I’ve been talking with the exploit creator who has been distributing these backdoors and although our conversation started respectful (Basically us complimenting eachother on the creativeness/innovative approaches) it has now turned sour as he is quite salty about the plugin. He also claims his backdoor is in many games, some with 2k-4k active players so it might be worth mentioning to your dev friends that running a scan with this plugin couldn’t hurt. lol (As always the require modules are free to the public and the plugin source is easily viewable. I take great entertainment and personal satisfaction in producing a quality product… plus the exploit creator’s saltyness is like the cherry on top~) I’ll keep the plugin updated as the exploiter continues to attempt to circumvent it. Stay safe everyone~
I think ROBLOX need to mention about this issue because of the scale of the issue obviously when they completely know what’s going on
Thank you for publicising this. It’s paramount for the welfare of new developers and even experienced developers using plugins where it may ruin their creations.
Maybe the script already does this, but why not include a whitelist of instances that belong under services? This way, the blacklist can inform you of a virus while a whitelist can inform the user that something isn’t as expected under a service, whether it’s an instance with a name that doesn’t belong, or more than once instance of the same name when there shouldn’t be more than one.
Mainly because due to the open source nature of plugins and the exploit creator’s continued monitoring of the plugin it would open a security concern where the exploit creator could simply inject the infection script’s name into the whitelist (since the only way to save data in plugins is with the plugin:SetSetting() function) so for security purposes I have it scan the source code of the scripts in the game instead of the names or locations. I also have a setting (default to on) that if there is a script in any container that isn’t directly explorable in studio (meaning the service doesn’t show up in the Explorer window in studio) then it will treat the script as an infection and contain/delete it. For his recent attempt to circumvent my plugin where he injected code directly into the source of pre-existing scripts (which he ultimately reversed because he feels this makes it too easy to have his backdoor found and due to the low popularity of my plugin he is more concerned about having the games he already has infected find out about the infection and take steps to remove it) I built a secondary scanner which doesn’t quarantine the entire script but instead replaces his infection code with a harmless comment to prevent it from damaging the game. These two systems together make it extremely difficult to put infection code into a game and even more so to do so without being caught… and even if they do make a new infection script all it takes is one update to the modules/plugin and the system will be able to find and remove it the next time the developer opens studio with my plugin installed.
Didn’t realize we were playing Spy vs Spy here lol
By the way! As far as I know the settings for a plugin is basically impossible to access from outside that plugin. There’s one for local plugins and one per each installed setting and they’re self-contained, so you should be fine with settings.
Great to see this. Thank you for creating something that Roblox should probably be doing automatically anyway.
Found a few things in team create places I’m involved in but nothing in my own places. Makes sense given all I generally use is Stravant plugins
Good idea but keeps marking all my scripts as viruses so had to uninstall the plugin.
The settings GUI could use work too, way too messy.
Yeah, the GUIs are terrible. They are meant to be temporary as I just kinda threw this plugin together rather quickly and such.
As far as the system marking your scripts as viruses I apologize for that. If you could send me one of the scripts that it’s incorrectly marking then I’ll look and find why it is marking the script as a virus. If it is a false negative I’ll remove the corresponding string that’s flagging it since it is too general.
When I activated my plugins, the scripts were detected as a virus