– could a mod move this to ‘server tutorials’ or the proper location? thanks
Hello! As promised; here is the follow up thread to the previous post talking about a specific exploit related to NUI callbacks.
This time, I’m here to address a much more wide-spread cheating issue that nearly every ESX/VRP/Economy based role-play server has had to deal with. It’s a pretty basic concept, and I’ll outline how it’s done here; hopefully no one picks up on this and decides to go do it themselves - but hey, if they do, you’ll know how to stop it .
Performing the Exploit
The exploit is simple, and in its most basic form works like this;
-
Download a memory editor, for this example we will be using Cheat Engine
-
Select the game process using the memory editor
-
Enter a vehicle shop on an ESX server, buy a cheap vehicle or bicycle.
-
Scan for the Hex value of the vehicle you’ve just purchased, for example - 0xE823FB48
-
Replace the results for that Hex value with something such as - 0x7E8F677F
-
Sell the vehicle back to the car shop
– So what’s the result of this?
In this example, we’ve taken a blue tri-cycles race bike, and effectively turned it into an X80 Prototipo, a significantly more valuable vehicle and sold it back to the server. We’ve essentially 100x’ed our money, and the server owner is none the wiser.
– How do we fix it?
Before I go into how to fix this specific instance of memory modification, it’s important to understand the variations that this cheat comes in, and all the different ways you are vulnerable. I want to make it clear that simply by reading my list, which has simply been dumped from my head to this page, you will not have all of the information. There are certainly dozens of other resources with a variation of this exploit, and it’s your job as a server owner to identify these resources and either resolve the issue, or cease to use them entirely. If you’re a resource developer, follow along and we’ll make this community a better place together.
Side Note
The last thread I posted with ‘exploiting’ or ‘hacking’ as the subject became an argument over the status of my moral compass. Please refrain from these sorts of responses, as I neither care about your opinion of what I do, nor does anyone else who is here to make use of the information that I’ve chosen to provide to you. Thanks.
– Exploit Variations
This thing comes in every shape and size, any time you have your prices, vehicle models, job payouts, shop prices, weapon prices, weapon models, any sort of monetarily purchasable item in-game, you can cheat cash out of it. Any variables you put clientside that the server receives and uses to modify the broad user experience, can be exploited using this method. For example, in the resource ‘Vehicle shop by Arturs’ you can easily exploit the local table in order to simply buy a vehicle for zero dollars, and then sell it for any amount you’d like. You don’t even have to scan a hex here, just a 4 byte exact value. Nothing against the resource creator, might I mention - it’s a nice design and it’s otherwise a great resource.
– Vulnerable Code & Patching
This is a client-sided table from a vehicle shop. As you can see, we have outlined the name of the vehicle, the cost and the model. All of these can be modified, and the server will accept whatever you pass to it as kosher because it has no record stating that the facts are otherwise.
Here’s where the magic happens, on line 545. The client calls ( in this framework’s case ) a server event called ‘carshop:buy’ - it passes along a few bits of information, that’s what the “vehicleProps, price, model” field tailing the event name indicates. In this instance, vehicleProps is the configuration and paintjob of the car that you saw when you went to purchase it. It does this so that when the car is spawned, it looks the same as when you previewed it. The price, is pulled directly from that table, and the server will charge you whatever amount is passed to it. The model, is simply the model of the car, and the server will spawn whatever model you pass to it there.
This isn’t isolated to just your car shop though, any resource using this method of data transaction is easily exploitable.
So how do we prevent this? What’s the best practice?
Well some resources, esx_carshop - or whatever it’s name is, have begun checking the plate and model that is associated with that plate server side before you sell it. Problem is, esx_garages isn’t on that bandwagon yet, and the system which esx_carshop uses isn’t all that great either. You can simply do what I call conversion by dropping your new BMXGatti into a garage, and pulling it back out; selling it afterwards as the server is now under the impression that you do indeed fully own this vehicle.
There’s no cut and dried solution to this problem, and my philosophy on the entire issue may be slightly warped and twisted in your opinion, and that’s OK .
I’m going to start including code snippets and my thinking when designing my own car dealer, which is the thinking I’ve followed when coding all of the resources I run on my server.
Let’s look at how things SHOULD be designed first, before I start showing you how you can implement these methods.
queue MS paint flowchart
This is my diagram of how your server works. The server, is directly linked to the database in which all of your client’s data is stored. The clients, connect to the server and ask it to retrieve and send information to the database for persistence.
In a perfect world, our networking looks like this. A client connects to the server, and requests their profile information. The server sends that information to the client, and the client receives it and displays the necessary information. Keep in mind, the client still doesn’t have the whole picture though - the server is still keeping track of everything. The client goes to purchase a vehicle, and decides they’d like a BMX bike. The client tells the server “Hey! I want a damn BMX bike, gimmie!!!” - at which point, the client will send the server no more information other than their player ID, and the requested model. The server will then access the database, retrieve the information about both the player and the requested vehicle. If the player has enough money to purchase the vehicle, the server pulls the money from the players account, adds the vehicle to their profile in the database, and then sends the new information back to the client. All this was done without the client ever taking full possession or control of any important information other than it’s own ID, and it’s request to the server.
I like to watch the world burn. I follow the same exact thought process, except I leave this nice information on the client in specific instances, because it’s fun to watch people pop in for just a few minutes before their game crashes to a bass boosted version of ‘It’s Magic’. This is fine though, for the purpose of this example.
This is what my vehicle dealership tells the server. In our previous example, the server did nothing with this information other than simply accept it. You’ll notice I do pass the cost of the vehicle off to the server, that’s only because I’m a sick and twisted bastard.
This is the money shot from the server, this is where the magic happens.
Minus some nasty looking for looping which I chose not to include for your own viewing pleasure, what we’ve done is this; we take the information from the client, we check it against the server’s information, and then we make a decision based on what the server knows as undeniable fact, and the request the client has made. This code says, first - does the model exist? If yes, then continue. Is the model requested from the client, the same that is requested on the server? Is the cost that the player has requested the same, as the cost stored on the server? And - does the player have enough money to make this purchase.
If all of this checks out, then we remove the money from the player, and we generate a new random plate for that vehicle. We insert the information into the database, and we then send the information back to the client with the new randomly generated plate and the model for spawning.
What if something’s fishy? Well, traditionally we would simply output an error message saying “sorry, try again later.” In this case, we do this -
If something isn’t right, if the client is trying to lie to the server, then we do this. Thank you to the creator of InteractSounds, for creating my all time favorite resource. It plays a bass boosted version of the song ‘Magic’ as your screen fades to black, followed by a painfully annoying to terminate game crash.
Implementing this functionality is really rather simple, and if you’re willing to do it, it’s only one extra step you need to be taking.
Move your client side information, such as tables including vehicle data, to the server. Then, modify your server events to check the information passed by the client against the server-side information. If even one piece of that puzzle doesn’t check out, terminate the transaction on the spot. Learning how to do this is quick and painless, but understanding how net-events work is important. It’s pretty well documented here on the wiki;
https://docs.fivem.net/scripting-reference/runtimes/lua/
– I didn’t understand any of this, help.
If you don’t understand any of this, that’s fine. I accept the fact that not everyone who is running a FiveM server is a networking wizard. If you’ve been the target of these exploits, contact the developer of the resource who you believe the vulnerability is originating from.
Be kind, be clear about the issue, and provide as much useful information as you can.
I hope you enjoyed reading this, and if you survived the whole thing kudos to you; I’m not proof-reading this whole thing, so if something is unclear post a response and I’ll get back to you as soon as I can and try to modify the post to help everyone else better understand.
– Edits
Post your questions so I can make a little Q/A section here
To address a reply to my now closed thread on NUI exploits - no, using a resource that ‘encrypts’ or ‘obfuscates’ your net events would not solve the problem here unfortunately; as using the NUI method we are just sending a JS $.post, and when modifying data all we are doing is changing the variable that the client sends to the server, not actually triggering any events in an unusual way.