Flair Anti-Exploit

That’s cool! I think the direction this is going is good; but you should also consider adding something on the server that is checking if stuff is reasonable like @Ax3nx mentioned.

And yes, I’ve seen your reply. Adding something on the server is still good though.

2 Likes

I was easily able to bypass your anti-cheat by deleting the scripts
https://gyazo.com/4b2f218ae9a9e73858a0892e50ce031d

(Don’t mind the twitching my roblox is bugged)

The issue with this is that its all local and exploiters have pretty much full control

I noticed that you only get detected when the scripts are deleted from StarterCharacterScripts, parenting the anti cheat scripts to the character is a terrible way to make an anti cheat just because with a little bit of searching any skilled exploiter can find it within minutes.

I recommend hiding the main “anti” and “detected” scripts, potentially even make more copies and checks
I unfortunately cannot give any more tips on how to improve it because I’ve never made an anti-cheat so I wish you best of luck with your project!

5 Likes

I’ll send out a fix to this. Thank you for reporting!

3 Likes

I’ve updated it so if you delete the detected script or disable it, it will kick the user.

2 Likes

The Remote tampering protection seems weak. The kick is performed on the client and could be bypassed.

if not remoteEvent then
	localPlayer:Kick("[Flair AE] Tampering detected.")
	break
end

A better solution would be for the server to expect a signal from the client every ~5 seconds. If the server doesn’t receive the signal, it suspects tampering and kicks the player.

3 Likes

I’m sorry I should’ve explained better

Now it’s true that your system detects deleting these scripts from “StarterCharacterScripts”
image
image

Though that is only because those 2 scripts are cloned into the character when you first join the game
Screenshot 2023-08-26 193137

Deleting these 2 scripts from your character completely removes the anti-cheat
image

No longer detects deletion

FULL VIDEO

3 Likes

I’ll look into it to detect if it gets deleted in the character.

1 Like

This seems incredibly weak, I wouldn’t use this.

  1. Exploiters can disable the Kick method when used on the client.
  2. They can delete the remote event and put a new one with the same name.
  3. Same thing with the scripts.
  4. They can also hang any part of that script to cause it to stop working.
  5. Or of course, they can delete both scripts within a 1 second timeframe.
3 Likes

Honestly, it’s best to do this on the server, anti-tampers aren’t likely to work most of the time.
On top of that this anti-cheat can be thwarted with a simple

local old; old = hookmetamethod(game, "__index", function(self, key)
   if key:lower() == "Kick" then
      return task.wait(math.huge)
   end
   return old(self, key)
end)

local function disconnect(signal)
   for _, connection in ipairs(getconnections(signal)) do
      connection:Disable()
   end
end

disconnect(humanoid.RootPart.ChildAdded)
disconnect(humanoid:GetPropertyChangedSignal("WalkSpeed"))
disconnect(humanoid:GetPropertyChangedSignal("JumpHeight"))
disconnect(humanoid:GetPropertyChangedSignal("JumpPower"))
disconnect(humanoid:GetPropertyChangedSignal("Health"))
disconnect(humanoid:GetPropertyChangedSignal("MaxHealth"))

dude i was thinking of just posting the same thing here LOL yeah no this is quite an easy way to do things

a really bad suggestion but could work idk, you could try editing the base animate script to detect this stuff

they’ll have a lot of trouble trying to figure that out

this isnt done on the server??

all client acts to those things(base character) are replicated to the server anyways (its the only way they can notice a change) so idk why theyre doing it on the client but thats a really bad idea

I fully support using the client, but please have some protection against simple hooks and also use the server for checks that the client doesn’t have to do for-example everything in this anti-exploit can be done fully on the server using magnitude and ray cast checks.

Also, I still don’t know why people use two scripts to check if they’re both alive; you can disable both at the same time. This is one of the worst methods that exist; try using a handshake.

A handshake is basically when the client sends a remote event to the server with an encrypted key, and the server resets a time variable for the user. If the key is incorrect or the server doesn’t receive a remote event in a valid amount of time, the script is disabled or destroyed, or the remote event was blocked/destroyed.

Flair Bypasses
local Old
Old = hookmetamethod(game, "__namecall", newcclosure(function(self, ...)
  if getnamecallmethod() == "FireServer" and type(self) == "Instance" and self.Name == "PropertyChangedEvent"  then
        return
 end

 return Old(self, ...)
end))
local function DisconnectSignal(Signal) --> Lazy Function
   for Index, Connection in next, getconnections(Signal) do
      Connection:Disable()
   end
end

DisconnectSignal(HumanoidRootPart.ChildAdded)
DisconnectSignal(Humanoid:GetPropertyChangedSignal("Health"))
DisconnectSignal(Humanoid:GetPropertyChangedSignal("MaxHealth"))
DisconnectSignal(Humanoid:GetPropertyChangedSignal("WalkSpeed"))
DisconnectSignal(Humanoid:GetPropertyChangedSignal("JumpPower"))

Give these a read:

PS: Also, if a user joins after the game has already loaded, the blacklisted words check will not work for him.

5 Likes

I’ve patched those bypasses just now.

It isn’t done on the server, it’s just listening for property changes on that client, in fact this can even harm innocent players or cause a hassle to the customer who used this asset (because this hinders the server from freely changing the walkspeed, jump power and such or client-sided actions like sprinting, highjumps, etc)

The code piece

local isAllowed = remoteFunction:InvokeServer("JumpPower")

and alike can easily be hooked to always return true

local old; old = hookmetamethod(game, "__namecall", function(self, ...)
   if getnamecallmethod() == "InvokeServer" and self.Name == "CheckAntiCheat" then
      return false -- because the code expects isAllowed to be true to fire the kicking part
      -- return false instead
   end
   return old(self, ...)
end)

And then just doing

workspace["Flair AE"]:Destroy()

is enough to break your anti-tampers; and again, this code is enough to thwart 90% of your anti-cheat

local function disconnect(signal)
   for _, connection in ipairs(getconnections(signal)) do
      connection:Disable()
   end
end

disconnect(humanoid.RootPart.ChildAdded)
disconnect(humanoid:GetPropertyChangedSignal("WalkSpeed"))
disconnect(humanoid:GetPropertyChangedSignal("JumpHeight"))
disconnect(humanoid:GetPropertyChangedSignal("JumpPower"))
disconnect(humanoid:GetPropertyChangedSignal("Health"))
disconnect(humanoid:GetPropertyChangedSignal("MaxHealth"))

well you dont need specific property changes for the client because since the entire character is replicated using network service, the humanoid is included… right?

try adding TOTPs for client server communication

makes it really, really, REALLY hard to fake

Changing the properties of a humanoid in the client won’t replicate to the server.

ohhhhhhhhhhh

tysm for clarifying