Exploiting Explained: Second Revision
This post is a general information source on common exploiting terminology, tools, and methods. The formatting is in sections for each specific topic, and is in no specific order.
If you’re not aware of exploiting by this point, you’ve probably been living under a rock that the pioneers used to ride for miles. While Roblox is seen as open grounds for free reign of exploits, this isn’t the case, and I attempt to tackle this wrong assumption in this post.
The following sections cover common issues often brought up.
This section is dedicated to explaining asset stealing; place and source code stealing are covered here.
If you’re wondering about place stealing in general, here’s what that usually entails. Someone has some kind of script executor, and a script which serializes your place into XML or a Roblox compatible format that Studio can open. Some exploits already come with this feature, others just use a script, but the gist is that they use data that’s already available to your client, which means it’s not something you can stop, or try to stop.
Some uncommon forms of place stealing might be tricking someone into giving Team Create access, where it’s possible to steal everything by saving locally. Additionally, very rarely Roblox could have a major security vulnerability, but then anything can happen.
Script stealing is another issue similar to place stealing but quite different in practice. Script stealing is done by a process known as “decompiling”. Decompiling consists of using software to generate readable source code from already compiled Lua code, which is in a form called “bytecode”, and doesn’t contain enough information to usually convert back into its exact source counterpart. This process also can’t be stopped, but recent changes such as Luau using a new instruction set can slow down the development of the tools used.
Note that decompiling is not a perfect science. With Luau stripping debug information that Lua usually passed along, things such as local variable names and upvalue names are no longer retrievable by decompilers. On the same note, white-space, comments, and style choices are not stored in the bytecode either.
Lastly, decompiling is only possible on LocalScripts, and ModuleScripts used by LocalScripts. That is to say, Server scripts can not be decompiled, in any way shape or form. If someone obtains your server code, that’s a huge red flag of a different underlying issue. Roblox does not send bytecode from server scripts to the client, ever.
Filtering Enabled & Exploits
Filtering Enabled & Exploits
A good way to get started is to echo what you always hear: under no circumstances should you trust the client with authority over your server game logic. When implementing your RemoteEvent and RemoteFunction code remember to think as the attacker. Your code should be built around thinking, “if I had absolute control of my client, what could I send over this bridge to break everything?” Design should be based around asking the server “can I”, and not telling it “I can”.
A simple example is a store; ask the server, “can I buy this sword?”, and don’t tell it, “I can buy this sword.” The server should be the one checking everything from currency to experience points to levels, since it has the final say in what’s really happening. You should always be ready for someone on the other side of the bridge to outsmart you, and make absolutely certain the code you wrote is well tested for cases like someone throwing a
NaN at you or expecting an object and getting a table that looks like an object.
A really common pitfall is the attempt to “secure” your remotes, or “validate” your data, and anything that is done client side. As a pro-tip: anything coming from your client will not be secure. It doesn’t matter how clever your system looks, or how much time it took you, you’re not the one in control of your client. If it makes you sleep better at night, the extra headache is okay, but you should not be relying on it to ever really work.
Some exploits don’t actually rely on remote exploitation, but instead in simple things like Roblox’s rules of replicating properties. You might encounter these exploits in the form of flying, super jumps, or speed hacking. The issue stems from the fact that players have physics ownership over their characters for smoothness and fast feedback, but in turn this gives them the ability to move them anywhere. You can mitigate these on the server, or add basic checks on the client, but be sure to remember you can never actually rely on the client.
Lastly are maybe some of the peskier exploit types which are just plain local enhancements. These are usually undetectable via conventional means, if at all. You might see these in the form of aim-bots, auto-hotkey style scripts, and general automation of game-play.
It’s about time to address software such as Elysian, Synapse, and others which enable users to execute local code or do other mischievous things. The software in question tends to fall into a few categories, some more common than others. The same tips as with the
Filtering Enabled & Exploits section apply to mitigating these kinds of issues.
Possibly the most common, or at least most problematic type of exploit as of this revision are script executors. These exploits are centered around allowing users load Lua code into the Roblox client to execute as a regular script or disembodied code. Script executors tend not to be just limited to Lua you run in game or Studio, but also come with special features.
You might observe exploits of this kind bypass context level restrictions when calling functions, or have special API designed by their creators such as
saveinstance. The special API also usually is made to bypass restrictions or read and write to thinks you shouldn’t be. The names “Level 4”, “Level 7”, and “Level” alongside any number ever were made to refer to these kinds of exploits and the fact they could access functions from higher context levels. The number itself doesn’t mean anything, and the terms are usually misquoted as meaning different things. A “Level” anything is just a fancy way of saying “script executor”.
Script executors have lots of ways of executing their code, and without going into many details I will list a few which were used once upon a time:
Proto Conversion - A normal Lua compiler would create a Lua function, and then some other code would convert the normal Lua function into one that’s Roblox compliant. This technique still sees widespread use.
Bytecode Conversion - A normal Lua compiler would create and dump a Lua function, and then some other code would convert the resulting bytecode into Roblox compliant bytecode. This bytecode would then be somehow loaded by Roblox.
Precompiling a VM - A really stupid method that works. People take a Lua in Lua VM such as FiOne or LBI and pre-compile it to be Roblox compliant, and then feed it with real Lua bytecode to run through the compatibility layer.
Lua C Executors
This is a very niche exploit type which surged from people’s laziness. Lua has a C API which is officially made for C code to interact with its internals easily. What “Lua C Executors” refer to is exploits that parse simple commands and call the associated API function. These are very stick and stone exploits, and usually don’t have much of a threat.
The laziest of all, command exploits would present users with an interface with buttons. Each button would usually be bound to some string of pre-compiled calls to the previously mentioned C API, or some other code. When the user clicks the button, the code is ran. These are usually intended towards simple local exploits such as flight or teleportation.
Luau and the Future
Luau and the Future
This short section addresses Luau and the future of exploiting on the platform. Luau is Roblox’s implementation of Lua, which changes so much of Lua internally that it has its own effect on exploiting. Taking an opinionated side for a second, I don’t believe exploiting will ever cease to be a problem on the platform, but what’s going on behind the scenes to mitigate it certainly isn’t minor either. As it happens there will just always be people that want to mess with other people and games, and that’s an issue every game and platform out there faces.
What does Luau tell us? It’s an interesting change of scenery to the exploiting community. Previously it was possible to at least have a base to stand on when designing an exploit, which was Lua and its open source aspect. With Roblox now using a proprietary implementation of Lua that deviates so much from standard, only time will tell how this affects the exploiting community. It’s likely those who have always been here will stay, but the barrier for entry is certainly higher now, and developers as a whole should feel at least a little bit better.
What has Roblox done?
What has Roblox done?
Roblox has done a lot, and mostly behind the scenes. They don’t talk about every new check or encryption they implement, or what heuristic they got working this time, and even mention that they’re actually working on this issue. The truth is people vastly over-hype exploiting as if anyone with mild knowledge can walk in and develop the next big hack. Instead of shouting at engineers, take a minute to thank them for what they do, and remember as a developer it’s also on you to practice good game design.
From the client riddled with land mines to FilteringEnabled being enforced, Roblox is always working on keeping its client safe. Likewise, people on the other side are constantly working to tear it apart. It’s a cat and mouse game.
Whether exploiting is still a thing or not, it’s best for everyone to try to just focus on making their game enjoyable and playable to users. Local exploits probably won’t go anywhere, and sketchy people will always be around. Designing your game to minimize impact and thinking about who is really playing it will save a lot of thinking and over-thinking.
Remember to listen to feedback from your players.
This post is subject to change should any of the information become outdated.