MadAntiCheat V2 - A Much Needed Upgrade

Unfortunately, a pcall in this event does nothing to help your case. As far as I can see, your entire while true do loop will be halted until the RemoteFunction returns, regardless of the pcall. In fact, you shouldn’t even be placing this code inside of a while true do loop to begin with, this should be placed inside of something that won’t be permanently halted in the event the client messes with the callback function on it’s end to make it wait indefinitely.

I’d suggest using RunService.Stepped or some other RunService step event instead to prevent this case from ever occurring. I was well aware the ping check isn’t focused on stopping exploits from the client-side, which is why my criticism of it was more focused on how easy it was to bypass it due to this critical flaw in its design.

I have nothing against ping checks either, they are a perfectly valid and good means of preventing the exploits you mentioned as long as they don’t have such critical flaws in their design.

It can be spoofed using hookfunctions, can raise false positive

If you hover over the link you will see the actual link lol
image

I just need to memorize the links lol

Yup; okay lets not derail this conversation now lol :rofl:

1 Like

We’ll see

1 Like

In his case, the ping check cannot raise a false positive or be spoofed because it isn’t meant to make sure a player’s connection speed is within a certain range, it is meant to identify when a player is using a lag switch to simulate being completely disconnected from the server temporarily, and I highly doubt anyone who would play Roblox has internet bad enough to trigger an anti lag-switch check.

If you run PlayerInstance:GetNetworkPing() It can only run on client meaning it can be spoofed! everything on the client can be spoofed.

The DevHub only mentions that the method can only be called on the LocalPlayer when used in a LocalScript, meaning it can’t be called on other players when used in it.

“For client-side LocalScripts, this function may only be called on the LocalPlayer.” Player:GetNetworkPing (roblox.com)

If it can’t be used from a (Server) Script (Studio’s down so I can’t test it right now), the DevHub page should be updated to note this.

1 Like

This is a misunderstanding of the wording there. That actually tells you that when it is used on the client, the client can only get its own ping, and no other player’s, but the server can get the ping of any player.

Please explain to me how the client can magically fake a perfectly fine connection, whilst at the same time, intentionally causing their connection to have a temporary lag spike using a lag switch? I am trying to emphasize that unless this is magically possible, then you cannot “spoof” an anti-lag-switch check, which is precisely what he is doing here.

1 Like

If :GetNetworkPing was run on the client, I believe an exploiter could hook it to always return the same value, which I think was what @CodedJer meant.

1 Like

this isn’t what the ping check in this anti cheat is doing to begin with, it sends a request to the client and sees how long it takes the client to respond to the request. This cannot be spoofed by people using lag switches (the people the ping check is intended to catch) because a lag switch for the most part, completely blocks any requests coming from the server or being sent to the server in order to simulate a large lag spike.

Don’t you know that anything on the client can be spoofed? literally everything.

Thats what I’m saying! and also everything on the client can be spoofed.

Analysis of the source code isn’t required to conclude that this (like any other public / non-game-specific) “anti-cheat” is not suitable for use in production or any practical environment outside of a .RBXL file rotting in your home directory. Systems to prevent or mitigate exploiting must be game-specific, as they have to account for game mechanics and the attack surface of implementations (such as sprinting, teleporting, weapons). They must also compromise between being able to detect broad ranges of cheats and remain accurate enough to prevent false positives.

That being said, simple code review immediately brings out both design issues and bypass vulnerabilities in the few existing “checks”.

The ping check, to start with, is fairly redundant. No game is supposed to implement a system to punish a player specifically for having high latency or a period of no connection. This is not just because players would inevitably trigger this check, which makes it a bad idea in the first place. The underlying design problem is targeting latency instead of the broader problems that “lag switches” cause, which depends on the game, but can often be: “noclipping” through objects or avoiding obstacles, abusing client-side hit registration to damage players while being otherwise invulnerable or at a different location, etc.
This reinforces the statement that anti-exploiting systems must be game-specific. With this check you are only creating false positives while ignoring all other vectors of attack.
On top of the design flaw, the ping “check” is vulnerable to being completely bypassed due misuse of InvokeClient. A pcall is in place to prevent the server from throwing an error in the case of the client throwing one or disconnecting before returning, but this does not address the issue that the client can cause the server code to yield infinitely by never returning, with something simple like this:

RemoteFunction.OnClientInvoke = function()
	while wait() do end
end

This, of course, can be fixed by using tasks and a proper timeout (or switching to a RemoteEvent-based system), not that it would negate how useless this is. Keep in mind that this “check” is meant to just “rubber band” the player in case of a loose connection. The player character can still momentarily arrive at an otherwise inaccessible location: Ex. a badge giver, button or other type of restricted area. This would also not mitigate any issue relating to using lag-switches with insecure client hit registration weapons and such. Instead of figuring out the rest of the infinite issues this check has, it’s easier to conclude that it’s useless and will never prevent any kind of practical exploit, and would instead introduce false positives.

The speed check relies on HumanoidRootPart to provide the character’s position. Due to the player character’s network ownership being set to the player’s client, an exploiter can potentially freeze, detach or remove (this applies to any part in the character model) HumanoidRootPart entirely (in a way that replicates to the server), thus bypassing this check. Further additions and checks need to be added to prevent illegal modifications to the character, if you wish to stick to this methodology. “Lee-way” is also added to the maximum allowed travel distance, which opens up a path to a lower-priority vulnerability which allows an exploiter to have higher-than-average movement speed while avoiding detection.
The API for this check allows a player to be excluded (ex. for teleports) which opens up vulnerabilities where an exploiter can use this exclusion time to teleport to an inaccessible location. A potential fix for this is to implement checking for server-sided teleports by using the Changed event on the Position or CFrame properties, as it only fires when this value is manually changed.
Another vulnerability is caused by the “check’s” long-interval-based distance checking instead of calculating a path, which can allow for an exploiter to travel at illegal speeds as long as they stick close (running in a circular motion, for example).
The “check” introduces false positives due to lack of proper implementations as well, such as:

  1. Cases where speed is applied only momentarily and reset before Humanoid.WalkSpeed is indexed (Lack of a journaling or caching system for all player speeds during a given interval and their timings in order to calculate an accurate maximum allowed path distance)
  2. Cases where physics forces (explosions, doors, slings, etc, moving platforms) or force instances (LineForce, BodyVelocity, etc.) give the character speed above what would be allowed by the maxTravel number, which only factors in Humanoid.WalkSpeed indexed at a slow interval.
  3. Cases where the player is falling off of a taller object, attaining a speed from gravity higher than what maxTravel allows

… and many other, which aren’t hard to figure out, but would turn this post into an entire book.

I refuse to comment on the client-sided “checks” as they can always be bypassed regardless of complexity or quality of implementation. Generally speaking, client-sided anti-exploit systems are a flaw on their own and should never be something you waste time on.

This post only has two points: to give insight into the current vulnerabilities in case you want to continue this as some “for-fun” personal project, and to hopefully discourage users from ever publishing or using such public / non-game-specific anti-exploit systems, as their only purpose is to cause headaches when dealing with false-positives and to give a false sense of security.

This post may have quite a few stylistic mistakes as I wrote this fairly quickly and without much organization, so feel free to point them out or otherwise respond to the content.

3 Likes

I’d argue that this isn’t entirely true, it is possible to make a generalized anti-cheat that is useful in production, it simply needs to have a high degree of control and flexibility of how it functions and only target most generalized exploits like speed, noclip, fly, etc. Of course that is to say, it shouldn’t just be dropped in and forgotten about, it should naturally be made alongside a game-specific anti-cheat that protects against whatever exploits attempt to abuse its features for their advantage.

2 Likes

If I understand your point correctly, you’re stating that Roblox’s default mechanics enable the possibility for a generalized anti-cheat for at least a spectrum of games. That in my opinion mostly true, a lot of games rely on the common default Roblox mechanics, which include the basic character model systems (R6, R15, Rthro) and the ownership passed to the client.
The attempt to patch the most general cheats, however, is practically nearly impossible to implement in any way that allows the anti-cheat to be used anywhere outside of a (dare I say - simple) static game and map, or otherwise to have poor handling or more complex cheat implementations. Here’s why I believe so:

  • Due to Roblox’s default choice in client-server networking being based on a model of client authority (notably considered horrible practice in the world of game development) instead of the more advanced (and secure) prediction-reconciliation model, any predictive algorithm (arrival time, acquired velocity from flinging or falling, etc.) which would be necessary to implement proper anti-exploit handling for physics mechanics (and handling fly cheats, in a more sensible implementation) is therefore impossible to implement in any way that would not cause false positives due to common network issues and latency.
  • Inferring from the top point, most theoretically sensible algorithms to solve the proposed issues would be practically impossible to implement because of the amount of variables and complex mechanics that would need to be accounted for to even try and remotely enforce any accurate movement checks to solve problems like flying - this is because of pretty much every physics interaction in the game, including falling, which would inevitably once again cause issues due to even small changes in latency.
  • Due to the network model, even if a produced anti-exploit system or check does not try to be perfect, rather “good enough”, it will inevitably still cause conflicts which would not be resolvable through just editing a configuration file, and would instead require a full re-write for specific cases. Take speed checks in case a game uses vehicles, planes, kites, etc.

If your point is that a generalized “good enough” anti-cheat is possible for a select group of simple games, I agree. Anything else outside of it - not so much, as because of the reasons stated above, no foolproof algorithms exist for Roblox games which rely on the default networking model. As long as Roblox keeps their “simple” (in actuality a pathetic excuse of a system for) movement mechanics, the only practical solution to dealing with exploits is to build on a game-specific anticheat revolving around your mechanics, and even better to invest in moderation. It should also be clear that “anti-cheats” in Roblox terms are very different from how actual production-quality video game anti-cheats work. Any proper video game these days has at least partly solved the issue of cheating, to the point where the only practical cheats are macros, “wallhacks” and “aimbot”, and it is understandable because these cheats are client-specific. With no others remaining, you can safely say that they have implemented proper client-server networking. At that point, their anti-cheats serve more trivial roles (server-sided ones primarily used for player behavior predicting: ex. detecting non-human aim or interaction, such as in the case of say Valve’s AI-powered anti-cheat, or in the case of client-side, it is a lost cause of a cat and mouse battle of detecting whether game memory was modified or whether there’s cheats running in the environment - a luxury they have but Roblox games don’t due to the amount of sand-boxing in place).

1 Like

You’re right in that most generalized anti-cheats wouldn’t be able to handle some scenarios, but that is why this wouldn’t be an issue if they had a great degree of flexibility and control, as for example, you could then fine tune their settings such as the threshold beyond their max speed that would be allowed (to account for lag, which as you mentioned is an issue)

In the case of vehicles being present in a game, it only makes sense that speed or teleport related checks would automatically disable themselves whilst the player is using a vehicle, seeing as a generalized anti-cheat would only be targeting players, and not anything else.

Understandably, a generalized anti-cheat can never truly be a simple drag & drop solution and would require the flexibility and customizability for the developer to suit it towards whatever game they are using it in. On top of more general ones like speed and teleport detection, a generalized anti-cheat could also identify certain exploits that rely on abusing the way Roblox’s engine natively works (such as the one where god mode can be achieved by the client deleting their own humanoid and replacing it with a new one on the client side)

As I see it, a generalized anti-cheat could only ever be good if it offered the developer a high degree of control over how it functions, and especially so with an API for their own code to interface it and change these settings on a per-player level or disabling checks entirely for specific players.

1 Like

You’re missing the point. If I am using a lagswitch then no matter what my connection is halted, you can’t have high latency and low latency at the same time. Also ping has nothing to do with roblox injection exploits, ping is based off your internet, yes you can make it modify the speed but you can’t spoof it. If it takes 50 MS for my router to ping the server then it takes 50 MS for my router to ping the server. I can’t make for a lagswitch you disable your connection, now tell me how does one make the server think you have connection without having connection.

Everything on the client can be spoofed; ping can only be retrieved from the client the exploiter just needs to hookfunction it and boom he can make it whatever he wants.