Closed lunatixxx closed 2 years ago
Someone answered me it could be something called "aimware airstuck exploit", does there is a possibility to patch or detect that in any way ?
Yeah, I've seen this before. It's something cheats can do in L4D2.
As for whether or not it could be patched or detected... I think so? Depends on how it's done. But I haven't looked into it yet, and won't for a while. Sadly, real life has gotten a little busy, I hope for things to calm down so I can work again :/
I'll say this for sure tho, once things do calm down a little in my life, I'll look into this and see what I can do :)
Looks like it is even worst than what i thought, they can teleport how they want from his point of view.
More information, a plugin has been made but it does not seem to be efficient:
if ( IsClientInGame(client) && ( IS_NAN(vel[0]) || IS_NAN(angles[0]) ) )
{
char SteamID[32];
GetClientAuthId(client, AuthId_Steam2, SteamID, sizeof(SteamID));
PrintToChatAll("\x04 [Anti-cheat-test] %N is suspected of using airstuck exploit.\x01", client);
LogToFile(path, ".:[Name: %N | STEAMID: %s is suspected of using airstuck exploit (Velocity / angles).]:.", client, SteamID);
LogMessage("%N is suspected of using airstuck (NAN value!!)", client);
}
if ( IsClientInGame(client) && ( tickcount == 0xFFFFFF || IS_NAN(tickcount)) )
{
char SteamID[32];
GetClientAuthId(client, AuthId_Steam2, SteamID, sizeof(SteamID));
PrintToChatAll("\x04 [Anti-cheat-test] %N is suspected of using airstuck exploit.\x01", client);
LogToFile(path, ".:[Name: %N | STEAMID: %s is suspected of using airstuck exploit (Tickcount).]:.", client, SteamID);
LogMessage("%N is suspected of using airstuck (Tickcount)", client);
}
For airstuck they also use "tickbase" manipulation, but how to track it ?
And for the teleport like in the video of my last post they seem to use something like that: //cmd->viewangles.x = FLT_MAX; //cmd->viewangles.y = FLT_MAX; cmd->viewangles.z = FLT_MAX;
Looks like it is even worst than what i thought, they can teleport how they want from his point of view.
I don't even play the game, but seems like he waited for the elevator to reach a specific point, so I'm guessing that's the 0.0, 0.0, 0.0 coordinates of that map.
As for the plugin, I'm aware of it, and I find the source just... really odd.
vel
defines which walking direction you wanna go in, it being all 0.0 (which is what the plugin checks for) is normal when you stand still...
And angles
is just where you are looking, them being 0.0, 0.0, 0.0 is normal.
I'm aware that when you timeout, your angles may be set to 0.0, 0.0, 0.0, but that's nothing special.
As for the source you quote with tickcount being 0xFFFFFF, seems like it's just setting your tickcount to be either really large or really low.
I know where the FLT_MAX
comes from, but I haven't looked into it yet, still busy with other things.
Not sure why setting your angles to be that large would cause issues.
My best guess (warning: pure speculation, I haven't looked into this and don't even play L4D1 or 2), setting your values to be out of bounds causes the server to try "resetting" you or whatever, which moves you to location 0.0, 0.0, 0.0. No idea, again, I still haven't looked into this.
If you are really desperate for a solution, you could try this code:
#include <sourcemod>
#define ASTYPE_LOWTC 1
#define ASTYPE_HIGHTC 2
#define ASTYPE_ANG 4
int playerinfo_type[MAXPLAYERS + 1];
public void OnClientPutInServer(int client)
{
playerinfo_type[client] = 0;
}
public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon, int& subtype, int& cmdnum, int& tickcount, int& seed, int mouse[2])
{
bool send = false;
if (!is_player_valid(client) || IsFakeClient(client))
return Plugin_Continue;
if (GetClientTime(client) < 20.0)
return Plugin_Continue;
if (tickcount < 0) {
playerinfo_type[client] |= ASTYPE_LOWTC;
send = true;
}
if (tickcount - 100 > GetGameTickCount()) {
playerinfo_type[client] |= ASTYPE_HIGHTC;
send = true;
}
if (FloatAbs(angles[0]) > 3600.0 || FloatAbs(angles[1]) > 3600.0 || FloatAbs(angles[2]) > 3600.0) {
playerinfo_type[client] |= ASTYPE_ANG;
send = true;
}
if (send)
CreateTimer(0.2, timer_check, GetClientUserId(client));
return Plugin_Continue;
}
public Action timer_check(Handle timer, int userid)
{
int client;
float pos[3];
client = GetClientOfUserId(userid);
if (!is_player_valid(client))
return;
GetClientAbsOrigin(client, pos);
if (GetVectorDistance(pos, view_as<float>({0.0, 0.0, 0.0})) > 1000.0) {
playerinfo_type[client] = 0;
return;
}
PrintToChatAll("\x04 AS test for %N (%d).\x01", client, playerinfo_type[client]);
LogToFile("addons/sourcemod/logs/as_test.log", "\x04 AS test for %N (%d).\x01", client, playerinfo_type[client]);
playerinfo_type[client] = 0;
}
bool is_player_valid(int client)
{
return (client >= 1 && client <= MaxClients
&& IsClientConnected(client) && IsClientInGame(client));
}
I dunno, test that and tell me if anything gets printed to chat or the console.
Alternatively, it will log to file addons/sourcemod/logs/as_test.log
.
Again, probs won't work, haven't looked into this and I wrote this in like 5 minutes.
I will inform you but it can take time before it happens. Does your code detect tickbase manipulation too ? I only see tickcount and angles.
I haven't looked into tickbase manipulation, but will later.
I made a small change to the source above, use the latest. :)
One player used airstuck exploit in my game, it did not detect anythign with last version of your plugin.
By the way "jockey" should be removed from the title as a single survivor can trigger that too, they can do it as soon as their character is "on ground". My guess is that jockey and survivor are only one entity when he is on him, that is why he is considered on ground and that is also the reason why you don't see that happen with other special infected. Simple hypothesis.
Seems like there are multiple ways of doing this? ... umm... I'll take a deeper look into this someday, rn I am doing code restructuring.
Tested that for tickbase detection and it does not detect anything, i'm out of ideas.
char path[256];
int m_nTickBase; bool ban[MAXPLAYERS + 1], apf_mode;
public Plugin myinfo = { name = "Tckbase detection", author = "", description = "Tickbase manipulation detection", version = "1.0", url = "" };
public void OnPluginStart() { ConVar cvar; (cvar = CreateConVar("sm_apfmode", "0", "0 - Kick / 1 - Ban", , true, 0.0, true, 1.0)).AddChangeHook(OnModeChanged); apf_mode = cvar.BoolValue;
BuildPath(Path_SM, path, 256, "logs/tickbase.txt");
if ((m_nTickBase = FindSendPropInfo("CCSPlayer", "m_nTickBase")) == -1)
{
SetFailState("Property not found CCSPlayer::m_nTickBase");
}
}
public void OnModeChanged(ConVar convar, const char[] oldValue, const char[] newValue) { apf_mode = convar.BoolValue; }
public void OnClientPutInServer(int client) { ban[client] = false; }
public Action OnPlayerRunCmd(int client) { // If player is a fake client, there wills be an error in GetClientAvgPackets if (IsFakeClient(client) || ban[client]) { return; }
// Get client m_nTickBase. Check it
Ban(client, GetEntData(client, m_nTickBase));
}
void Ban(int client, int tickbase) { if (tickbase < 0) { ban[client] = true;
// Ban via command
if (apf_mode)
{
char SteamID[32];
GetClientAuthId(client, AuthId_Steam2, SteamID, sizeof(SteamID));
ServerCommand("sm_ban #%d 0 \"Cheating\"", GetClientUserId(client));
CPrintToChatAll("{green}[KCA] %N was banned for tickbase manipulation.", client);
LogToFile(path, "%L [%s] is banned for tickbase (%d) which is less than 0", client, SteamID, tickbase);
}
// Print to admin
else
{
SMAC_PrintAdminNotice("\x05%N\x01 \x04is suspected of manipulating tickbase.\x01", client);
LogToFile(path, "%L tickbase (%d) is less than 0", client, tickbase);
}
}
}
Seems to be a bug too since last stand update... it just happens way too often and that will explain why it is never detected.
@lunatixxx
could you reformat your Jan 19 comment better so its just one big long code block for copy/paste so others can test it????
I also saw the jockey teleport exploit on a valve server just yesterday
At this point i don't think it is possible to differenciate who use it intentionally or not, it even happens with bots. https://streamable.com/mudz88
thats not a bot in that video just someone who is calling themself Jockey which is not hard todo
setinfo name Jockey
@J-Tanzanite the link I sent you earlier contains info about this exploit
As far as I remember it's done using lag triggering
someone used the jockey teleport exploit on me and after they did it I was at
(0,0,0) (X, Y, Z)
next time someone tries the exploit on you check and see if you are also at 0 0 0
you can find this information by enable cl_showpos 1
which puts your client info into the top left corner of screen
thats not a bot in that video just someone who is calling themself Jockey which is not hard todo
setinfo name Jockey
I know the difference between a bot and a player and as you see there is only 2 SI on the screen hud which means it is a bot. And no it is not always on 0 0 0 position, depends the map.
quick searching of github for "Tickbase manip" and this came up....
https://github.com/User344/L4D2Simple
also that looks like copy/pasta from
https://github.com/Exle/Anti-Packets-Flood/blob/master/addons/sourcemod/scripting/apf.sp
@CanadianJeff Do you have the ability to reproduce this glitch on command? If so this would be very helpful in diagnosing the issue.
In this video, it appears that the teleport happens only briefly, and it happens at the same time as the hunter pounce lands on another player. I wonder if this is a case of failure to clean up victim
/attacker
references on the SI players. There are a lot of calls made to CancelTug
, StopBeingDragged
, etc on these pounce/leap events
If that is the case, we should try to examine previous SI attacks before the teleport happens and look for correlations between incidents.
It only happans briefly because the timer of the jockey unteleport plugin happened at this moment. The plugin does not works in all situations and even create false positives.
That would certainly be unfortunate if this is another newer-linux bug... Confogl static shotgun spread had a Ubuntu 20+-only bug like this, and in the end we resolved it by fixing some custom ASM we wrote; there was an FPU stack alignment issue
https://github.com/SirPlease/L4D2-Competitive-Rework/pull/221
It was not easy to diagnose, and I don't think that same type of issue (FPU misalignment) would happen with non-handwritten code...
I hope Sky keeps the experiment going to confirm the numbers.
Edit: SirPlease believes that the issue only occurs on 20+ ubuntu as well.
I don’t know if it’s related to the exploit, because it’s other player that triggered the teleport(position not 0,0,0)
Happens too when teams are full and have no access to spectator.
@ProjectSky, this does not apply to cheats, this is a game bug already, what you reproduced. Since there is not one problem with a jockey, but a lot and not only related to this.
This plugin should detect any teleportation in 100% cases. AFAIK, there is no other way to constantly teleport someone without sending "invalid" commands or setting your side/forward/up moves to NaN values.
@Vinillia, there is an extension that was written a long time ago :D, maybe someone will be just as interested (by the way, it still works on Linux). Yes, this is probably the same fix, but written a little differently). I hope this will just be fixed at the game level, and there will be no point in making such cheats.
@A1mDev, Yes, fixing it at game level is the most efficient way but its literally impossible to find code which sets pos to 0, 0, 0 and this is the reason why i added sm_usercmd_null_invalid_commands convar to allow reset CUserCmd. As i said earlier cheater can teleport survivors only if he sending corrupted user commands so if corrupted user command will be reseted then this will prevent cheater from teleporting anyone. But there is still a very low chance that he can crash your server by sending to many user commands right before he hit survivor collision while using charger/jockey abilities.
This is only as a temporary alternative until a more reliable fix will be founded. Thanks for the link to csgo extension, didn't know about it.
something I kinda noticed which could be of some help to people is the jockey speed matches the survivor speed......
so on my server I did the SETSPEED X4 on myself had a jockey leap on me and as the jockey was moving me around the jockeys speed was still the same at X4 I placed on me
something I kinda noticed which could be of some help to people is the jockey speed matches the survivor speed......
so on my server I did the SETSPEED X4 on myself had a jockey leap on me and as the jockey was moving me around the jockeys speed was still the same at X4 I placed on me
The setspeed, what is this?
Anyway i think our best bet to fix this issue is to improve the anti teleport jockey plugin which works fairly well but it still does not patch all situations, like teleport inside map for example.
About a month ago, I sent @azalty some code on Discord which should properly check for invalid floats.
In my original code when I tried to check for invalid floats, I naively assumed invalid floats and infinite floats could be detected by comparing them with normal floats (float > 9999.9
bad way to check for infinite float).
However, after researching how floats actually work, I realize why that might not work... I found some information stating that comparing NaN floats with anything will always yield false... Which could possibly explain why my float comparison in the first test I made, wouldn't work (Still unsure about this).
And I found out that both NaN floats and infinite floats are encoded by setting the exponent to all 1
s...
And so to check if a float is NaN or Infinite, you would have to do some bitmasking... Which you can't do directly on floats...
However, in SourceSpawn, you can do: int mask = view_as<int>(3.14);
This doesn't cast the float to an integer, it just reinterprets the float to an int. So effectively, storing the float in it's usual bitpattern inside of an int? At least... That seems to be the case?
So, based on what I found out about how computers store floats a month ago, I came up with this (HORRIBLE) code... And sent it to Azalty for testing... Sadly, he doesn't have a server to test with. And I can't set one up xD
I want to stress this... THIS PROBABLY WON'T WORK! Firstly, the code might not actually detect NaN or INF floats, my method might not work... Secondly, if cheats aren't teleporting players as jockey through NaN or INF floats, then this won't prevent shit.
#include <sourcemod>
#define FLOAT_MASK 0x7f800000
public Plugin myinfo = {
name = "Float NaN and INF detector",
author = "J_Tanzanite",
description = "This probably wont work",
version = "0.0.1",
url = ""
};
public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon, int& subtype, int& cmdnum, int& tickcount, int& seed, int mouse[2])
{
int sus = 0;
if (!is_player_valid(client))
return Plugin_Continue;
/* Test velocity */
for (int i = 0; i < 3 && !sus; i++) {
int mask = view_as<int>(vel[i]);
if ((mask & FLOAT_MASK) == FLOAT_MASK)
sus = 1;
}
/* Test angles */
for (int i = 0; i < 3 && !sus; i++) {
int mask = view_as<int>(angles[i]);
if ((mask & FLOAT_MASK) == FLOAT_MASK)
sus = 1;
}
if (sus) {
/* Terrible code... */
PrintToChatAll("Blocked %N input, Invalid Float detected...", client);
vel[0] = 0.0;
vel[1] = 0.0;
vel[2] = 0.0;
angles[0] = 0.0;
angles[1] = 0.0;
angles[2] = 0.0;
return Plugin_Handled;
}
return Plugin_Continue;
}
bool is_player_valid(int client)
{
return (client >= 1 && client <= MaxClients
&& IsClientConnected(client) && IsClientInGame(client));
}
@J-Tanzanite, teleport fix is already there. In addition, a report has already been sent to the game developers and I hope this will be fixed soon.
teleport fix is already there.
What do you mean?
@ProjectSky what did you use to record that gif?
@ProjectSky what did you use to record that gif?
NVIDIA shadowplay captures videos, gifcam make gif
I just noticed this on my server
the "rawr" player was joining the game as a spectator and has a few game bans on profile http://steamcommunity.com/profiles/76561198102065485
few seconds later francis got teleported by a jockey and everyone in the chat started complaining about it
I just noticed this on my server
the "rawr" player was joining the game as a spectator and has a few game bans on profile http://steamcommunity.com/profiles/76561198102065485
few seconds later francis got teleported by a jockey and everyone in the chat started complaining about it
Was "rawr" the jockey?
Also, in the red text; we see NaN
... Which is what my code above should prevent if he's sending NaN values in UserCMDs.
Did you try my latest code?
In case links don't work; This comment contains the latest code I'm talking about: https://github.com/J-Tanzanite/Little-Anti-Cheat/issues/48#issuecomment-939329519 This code is not in Lilac, you'll have to compile it and install to try.
Worth a try?
@J-Tanzanite, teleport fix is already there. In addition, a report has already been sent to the game developers and I hope this will be fixed soon.
If you are talking about user_commands plugin not it does not fix it. I will try the code here but i don't have high expectation, it even happens with bots so it is mainly a bug at this point.
I tested the code that you provided.
It detected a confirmed cheater but i'm not sure it blocked the exploit actually, looks like he is teleporting on the survivor then after dropping in the hole he is immortal when it should die??? By the way he was abusing a lag exploit, the whole server was freezing.
"[!] Blocked Mexican Skull input, Invalid Float detected..." (spammed the message like 30 times it is problematic)
He's probably not dying and airstucking because I wrote return Plugin_Handled;
in my code, if you replace it with return Plugin_Continue;
- he should lose the ability to airstuck and should in theory just... be unable to move while falling, thus, falling to his death. Replacing that one line should fix that at least.
Edit: As for the teleport, looks like a speedhack, nothing more.
How to reduce the spam of the message? Also anything useful against speedhacks?
You can just delete the line that says PrintToChatAll
...
Or try this untested code... Not sure it will even compile lol:
#include <sourcemod>
#define FLOAT_MASK 0x7f800000
public Plugin myinfo = {
name = "Float NaN and INF detector",
author = "J_Tanzanite",
description = "This probably wont work",
version = "0.0.2",
url = ""
};
bool allowchat[MAXPLAYERS + 1];
public void OnPluginStart()
{
CreateTimer(10.0, timer_reset, _, TIMER_REPEAT);
}
public Action timer_reset(Handle timer)
{
for (int i = 1; i <= MaxClients; i++)
allowchat[i] = true;
}
public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon, int& subtype, int& cmdnum, int& tickcount, int& seed, int mouse[2])
{
int sus = 0;
if (!is_player_valid(client))
return Plugin_Continue;
/* Test velocity */
for (int i = 0; i < 3 && !sus; i++) {
int mask = view_as<int>(vel[i]);
if ((mask & FLOAT_MASK) == FLOAT_MASK)
sus = 1;
}
/* Test angles */
for (int i = 0; i < 3 && !sus; i++) {
int mask = view_as<int>(angles[i]);
if ((mask & FLOAT_MASK) == FLOAT_MASK)
sus = 1;
}
if (sus) {
/* Terrible code... */
if (allowchat[client]) {
allowchat[client] = false;
PrintToChatAll("Blocked %N input, Invalid Float detected...", client);
}
vel[0] = 0.0;
vel[1] = 0.0;
vel[2] = 0.0;
angles[0] = 0.0;
angles[1] = 0.0;
angles[2] = 0.0;
return Plugin_Continue;
}
return Plugin_Continue;
}
bool is_player_valid(int client)
{
return (client >= 1 && client <= MaxClients
&& IsClientConnected(client) && IsClientInGame(client));
}
As for speedhacks...
VALVe did make a speedhack patch for all source games...
...
Except L4D 1&2...
... I have no clue why.
Not sure if this is still the case, but sv_maxusrcmdprocessticks
is the command that handles it. L4D1&2 doesn't have it afaik. That said, it should be easy to do what VALVe did in a plugin, however I don't have a lot of time nowadays.
SMAC does have a speedhack patch, I considered making one for Little Anti-Cheat, but since most source games don't have speedhacks anymore, I just didn't consider it worthwhile... Still don't. That said, I don't know if SMAC's solution is the same as the one VALVe has, but you could try it.
Patching speedhacks won't prevent Dashing tho (which is when a cheater speedhacks for a split second... Like you see in the video, this can't be solved).
The dashing is because i'm using smac module, they still get an advantage of it and can be difficult to differentiate with a real lagger.
I just spotted this on my server
looks like it is pissing people off?
also that person only owns 1 game
Did not see it happen since i have the plugin and still using plugin handled (but it is only been one month). Added the no spam function for chat and was never averted of anything, not sure if this is because there is nothing happening or because the new function block the message.
The code works by the way and the chat alerts also, two detections and no false positives after 6 months. That does not block the teleport bug on newer versions of linux tho.
This is solved no need to let this issue open and give them a chance to know that this is detected, already got a few banned and it's pretty rare in fact. As a reminder innocent players will not be banned with this code because of the jockey tp bug caused by recent versions of linux, as it's not caused by a client command.
You are so sure of it? There are many problems in the game and there are several bugs with the jockey, the result is the same, teleport outside the map.
Could you please look into this thing ? I already reported that back a few monhs ago on the SMAC github, the guy was detected as a speedhacker after it happened and he already has a game ban so no doubt about him.
Basically the survivor taken by the jockey got teleported out of the map and others can't help him.
It looks like this is a cheat and not a bug to me but i could be wrong, the fact is it just happened to me when i was the jockey and i did nothing special so i would like to understand. If this is a cheat does that mean the survivor could trigger it ? When it happened the player claimed it was weird mod of the server which is not, i explained it was definitely a bug and we restarted the round. He seemed honest but still it piqued my curiosity as this is something i only saw once before (my report on SMAC github) since i play the game basically since it is out.
https://www.reddit.com/r/l4d2/comments/d5ksy4/jockey_teleport_survivor_out_of_map_exploit_in/ Video example i found on reddit, except the two times it happened in my games survivors got teleported under the map but it does not make a big difference i guess : https://www.youtube.com/watch?v=PxIMeWf6GGo
Thank you if you can enlighten me on this subject.