Clearing your game of malicious scripts, plugins, and backdoors

Chances are if you’re here, your game may currently be infected with malicious scripts or plugins, or in other words, hacked. If that’s the case, keep calm! It generally can be resolved fairly easily. I’ve seen a great deal of these threads recently, so I’ve formulated this guide to help :slight_smile: . Let’s get started.

Update: July 2020

Ok, I lied; before we begin, I’d like to talk about a few changes in terms of third-party permissions since I wrote this. Roblox has since implemented options for disabling third-party sales & cross-game teleports as well as plugin HTTP requests. There’s some more info below in the respective spoilers which I would recommend taking a look at if you’re suffering from related problems; otherwise, back to the tutorial!

Third-Party Sales & Cross-Game Teleport Settings

As you can see in the image below, Roblox has added two new options to the Security tab of Game Settings! These options allow you to disable purchases from anywhere that isn’t your game as well as teleports to anywhere that isn’t a sub place of your game.


If you have no use for these features, it’s a good idea to disable them as an additional layer of security. Say goodbye to random purchase prompts and teleports in your game! That being said, if you are experiencing things like these examples, you should not simply disable these options and be done. You should disable them and follow the rest of the tutorial to remove the malicious content from your game.


Plugin HTTP Permissions

Roblox has also implemented plugin HTTP permissions (not to be confused with game HTTP permissions) which prevent plugins from making any requests to the internet. On the first occurrence of said action, you’ll see a prompt like this from Studio which you can accept or decline.

Following the initial action, you’re able to change your decision anytime in the Plugin Management window.


1. Locating Malicious Plugins

If you believe your game is infected, the first thing you should do is verify all of your plugins are legit and not interfering. If you miss this step, everything else later on is pointless since the plugin can continue to replace the backdoor at any time. To access your installed plugins:

  • Open Studio

  • Click on the Plugins tab

  • Click Manage Plugins

Once you’ve got to this list, scroll through all of them and remove any you don’t recognize. Even if they look legit, make sure they’re not a duplicate of the original one. Some plugins have a thread here on the DevForum; try searching for it if you’re unsure. Also, make sure to double-check that the creator’s names match! Tip: You can click on the creator’s name to reach their profile page.

If you’re still uncertain, you can also visit the plugins page on the Roblox website and search for the plugin. With the results, you can determine whether you may have installed a duplicate.

I would also recommend that you go through the source of your plugins and verify they’re safe. I’ve written a guide on this here:

2. Locating Malicious Scripts

Now that you hopefully are free of hostile plugins, it’s time to find everything they could have inserted. There are multiple ways of doing this, so here are some of the most commonly practiced ones:

  • Option 1: Printing All Script Instances & Identifying Rogues

This is a general starter used by most and it’s pretty simple. A small command is run to scan the place for all script instances, then their name and ancestry trace are logged to the output. Such a command looks something like this (change the ‘LOCATION’ to wherever you want to scan; like workspace for example):


for _, instance in ipairs(LOCATION:GetDescendants()) do if instance:IsA("LuaSourceContainer") then print(instance:GetFullName()) end end

After running this, you can survey through the results in the output window for unexpected scripts. All Scripts, LocalScripts, and ModuleScripts all inherit the LuaSourceContainer class and it scans all descendants of the defined location, so it’ll find everything! Here’s a quick example I whipped up:

Try to run this on as many services as you can, you used to be able to scan the entire game, but such functionality has been restricted. Make sure to check CSGDictionaryService!

  • Option 2: Using an ‘Anti-Virus’ plugin

Another method that is fairly widely used, especially by those less knowledgeable in scripting is backdoor scanning plugins. There is a wide variety of these created by other users, so a simple search like backdoor scanner or malicious script scanner yields many results. I won’t go very in-depth here as they are all quite different, so I’ll let you explore. Some reputable ones based on those search results are:

Venom by @pa00

GameTree by @Hexcede

Kronos by @WhitexHat

Hidden Backdoor/Infection Script Detector by @Christbru01

  • Option 3: Using Studio’s Builtin ‘Find in all scripts’ Feature

This handy feature is built right into Studio, and while it has fewer use cases compared to the above two options, it can still prove quite helpful. Say the malicious script is prompting random purchases in your game, you can find all the scripts where MarketplaceService is referenced. Press Cmd/Ctrl (Mac/Windows) + Shift + F to open it.

Other than that though, it can be hard to know what to search for. Some common terms include: string.reverse, string.byte, require, and getfenv. Most crooks use a variety of things to ‘hide’ what they’re doing (obfuscation) so this option isn’t often too helpful.

  • Option 4 (Last Resort): Showing All Hidden Classes in the Explorer

If you still don’t find the culprit, it’s time to resort to more intricate measures. Start by opening Studio’s settings (File > Settings) and selecting the Studio tab.

Scroll down most of the way until you come across these settings:

Enable “Show Hidden Objects in Explorer”, “Show Core GUI in Explorer while Playing”, and “Show Plugin GUI Service in Explorer”. The Explorer should now by flooded full of every class implemented by Roblox. A general place to inspect first is CSGDictionaryService as bad scripts are often placed there since it’s generally hidden:

As you can see, I gave myself a BadScript. If you do manage to find anything here that isn’t MeshData (be sure to check children if there are any), it’s very likely the culprit. Remove it and test your game to see if the problems have been resolved. If they unfortunately haven’t, try starting at the beginning of this topic and make your way down again. After multiple attempts without success, you could also reply below and we’ll help you out.

3. Preventing Problems in the Future

In the future, you can work to prevent such circumstances by operating under these basic guidelines:

  • Only install plugins from well-trusted sources, otherwise thoroughly verify the source code before installing.

  • Limit the use of free models, and if you must use them, check for scripts when inserting.

  • Don’t use scripts from random people on the internet; the DevForum is generally safe, all public topics can be seen by anyone so bad actors would get caught real quick.

  • If you are working in Team Create with others, be sure everyone follows these guidelines. If one person has a nasty plugin, it’s like everyone does.

  • If you’re ever unsure, ask. While it may seem like a dumb question, it’s much better than having your game compromised.

4. Conclusion

This ends the informative portion of this post, so I’d like to request any strategies that you use or anything else that isn’t stated which you believe would benefit others in situations like these. Once again, if you’re having trouble, feel free to post below for help. Thanks, and safe developing!

65 Likes

This is pretty well written, short and simple, and you’ve pretty much hit the nail on the head. I’d like to note, my script (GameTree) is a little outdated at this point, and I wouldn’t rely on it catching anything recently made due to very common obfuscation techniques now being used. I was thinking about writing a much more advanced plugin sandbox tool to replace GameTree, however I unfortunately am not sure when or if I’ll have time.

On the topic of obfuscated scripts, you can actually view what these scripts do with not too much hassle. You probably will see a lot of weird numbers and backslashes. This is simply a way of rewriting text within a string. Each individual character has its own number, like an id. You can simply copy any text you see and run print with that text in the middle. Additionally, a lot of obfuscated code now uses string.reverse. You can pretty much just copy and paste this exactly how you see it and print it out to see what the text really is.

getfenv is a way scripts can access different, common code with text. For example, getfenv().game will try to access the game instance which is used by code. This also includes certain function, such as require. Using square brackets is a way to simply insert text, or some value from somewhere else instead of typing it normally. This is used in combination with what I mentioned above to hide code.

Here’s an example of what you might see:

getfenv()[string.reverse("eriuqer")](1000*56/10*16)

You may also, like I said, see weird backslashes and numbers instead of something that looks like text. Again, this is just a way of writing text, and in this case it would be used to hide, aka obscure what the script is doing. You can simply take the portion within the square brackets, read to see what you think it’s doing, and simply put it within the parentheses in print(). In this case, assuming you copied everything, you’d see “require” in the output window (which you should generally have enabled, however if you don’t, you can find it in the View tab at the top of studio)

Now, finally, I’ll explain what require is. You may be familiar with what an “asset” is on Roblox. If you’re not, it’s simply something, code, model, place, gamepass, etc that has been uploaded to Roblox. Every asset on Roblox has a unique number given to it. What require does, is essentially it can be given an asset id (the number of an asset) and it can then load that asset (require it) into the game. If that asset meets certain conditions (being a free model with a ModuleScript named MainModule) it can be ran like a script.

The reason that these malicious “backdoors” are inserted into your game is because the owner of those modules can essentially change what code is a part of their module (the thing being required). This allows them to run code on your game just like any script in your game. It also allows them to load in their own asset, code, models, etc without your knowledge. Obviously, you can see why this would be bad.

Hopefully this helps explain what backdoors are, what obfuscation does, and all of that.

13 Likes

Updated the main post to match changes in the recent months and fix a few typos. Some notable changes are third-party purchase, cross-game teleport, and plugin HTTP permissions! Check out the new section to learn more if you’re having trouble with these common problems.

As always, let me know if you have any suggestions or problems below or through DMs.

2 Likes

Will Ctrl + shift + F find it even if the script is obfuscated in Lua Bytecode?

1 Like

Not likely, if you aren’t able to remove the obfuscation then you should use one of the other methods. Ultimately it depends on how it’s obfuscated, but in the majority of cases, no.

Generally, if someone has taken the effort of obfuscating something, their likely trying to hide something that they’re not wanting you to find. So, if you aren’t certain of what it does, then you should remove it as the author probably has bad intents.

1 Like

Yeah, most of my friends obfuscate there products to prevent rebranders, But if someone wants to know if they contain viruses, we are happy to show them. Thanks anyway :stuck_out_tongue:

2 Likes