[TUT] Securing Your Server

– could a mod move this to ‘server tutorials’ or the proper location? thanks :slight_smile:

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 :blush:.

Performing the Exploit

The exploit is simple, and in its most basic form works like this;

  1. Download a memory editor, for this example we will be using Cheat Engine

  2. Select the game process using the memory editor

  3. Enter a vehicle shop on an ESX server, buy a cheap vehicle or bicycle.

  4. Scan for the Hex value of the vehicle you’ve just purchased, for example - 0xE823FB48

  5. Replace the results for that Hex value with something such as - 0x7E8F677F

  6. 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

CODE1

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.

d10f1d7acaeb25e65877b3551e5c1d23

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 :slight_smile:.

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 :slight_smile:

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.

Old Thread

How to Stop the Hacks

28 Likes

A fellow holder of the dancing frames gand I see!

I really like to see this kind of posts, I hope for more people to understand this very fundamental thing about how network software must be designed and implement better gamemodes on FiveM.

I just want to add something, I love paint flowcharts, they are lovely little cute images, make me smile on every design document I read when I see them. BUTT! I present you this magical tool, constructed on top of the ruins of an ancient CADilization, DRAW.IO !!

Jokes apart, I understand that you don’t care about other’s people ignorance… but using the proper wording and with little touches (like using a CAD tool to explain a networking thing) may end up in people taking what you have to say more seriously, It’s saddens me that server owners may skip very important matter.

4 Likes

TLDR: Don’t trust client input.

8 Likes

I appreciate the proper flowchart :smile:

1 Like

random side note

This isn’t just a guide for cheat engine; read this for what it is, a guide on how to network between client and server events.

1 Like

Can something like this resolve the problem?

Just newbie asking…

If the exploit is in the alley of lua injection, no; that’s not going to stop them. If it’s CEF/CE then that isn’t even relevant.

I believe the creator of that resource severely misinterpreted a few things.

@vmlinux

Not exactly understanding what point or solution you’re getting at; however…

The fact still stands, that despite all attempts at bandaging the issue with whatever obfuscation methods, key generators, etc you wish to use, people still refuse to address the actual issue. Why not just fix the problem? ;L

Can’t really speak as to what other solutions you’re referring to but I’ve not found anything like what I describe in games. Publically at least.

As for why not, well, that is a good quesiton. There is no single spot one can hook that will magically apply across all data serialization.

salty_tokenizer is close but not secure. The actual token generation is simply calling random.

This entire scenario is nullified by modifying vehicleshop to save the sale price on purchase and use that against the resale. They can change the hash to anything they’d like but the serverscript will give them the amount of money that plate has a value for.

Ok; this is going way off topic…

For the general public - don’t listen to the client, define everything server side and check it with what the client is requesting. Simple.

Bank account? Server knows the value, server gets request from client for X amount of money, server checks if serverside account has money, if it has the money it gives it to the client; but it really only transfers it into another label server-side.

Simple.

Uh… in this scenario, it is that simple.

Read the thread, read my responses. If the server knows that the value is 500, and the client tells it 400, it’s not going to listen.

– edit to above;

I understand what you mean as far as the latency issues - it’s a common problem when the server handles ALL of the networking, but here we’re simply talking about exploit blocking. FiveM will never have the networking capacity to run fully server-sided control over all player variables such as movement etc…

Not sure why you’re going all offensive now… I’m saying that the issue that most server owners are facing right now is related to unsecured events, whether it be a simple cheat engine exploit or someone literally clearing an entire database.

You’re talking about high level networking that we might see in a MMO style game where movement calculations and other fine details are indeed done by the server, however that is not the case in FiveM and never will be.

Also; maybe I’m wrong, maybe you are making some sort or valid point but your speech is too jumbled for me to comprehend.

I hope we can get back on topic instead of I know you are but what am I shitposts that end in a topic being locked. These types of topics are very interesting and helpful and I hate to see them disappear.

1 Like

Agreeing with @schwim here.

@vmlinux
Once again; you’re way off the topic of discussion. Let me try to turn this into something useful.

The short and simple of my response was ‘it won’t stop people from screwing with your server’ because it won’t. And, I’m still not sure what you’re getting at. I said the creator of that resource misinterpreted the way lua injectors work, it’s a resource to ‘stop lua injectors.’ It will NOT stop someone with a lua injector. Why? Generally speaking, if you’re using a real injector these days, you coded it yourself. If you coded it yourself, you’re probably smart enough to bypass the tokenizing system.

And it will not stop NUI based exploits for the following two reasons -

  1. NUI exploits are non identifiable. By this I mean, when you use CEF to exploit a vulnerable NUI based resource, you are sending a legitimate post command with modified data.

  2. Because it is a legitimate $.post function to the NuiCallback, it won’t matter how hard you obfuscate your resources or whether you have l33t 1337 super token encryption, because like I said - it’s a ‘legitimate’ request made by the client.

The simple solution, as I said in the main post, and in multiple replies is to handle the sensitive data on the server-side. Define the possibilities, and if the request from the client is outside of the norm, do not allow it.

Sorry, but rambling about high level networking requests that would be of consideration in a competitive e sports game, or a browser based MMO application does not assist anyone in actually resolving the vulnerabilities that stem from a lack of basic security measures.

Uh; just going to ignore the whole first half of that because again - doesn’t make any sense. I want to believe that you’re trying to say something useful, and that you do indeed know what you’re talking about, but the way it’s coming out just isn’t comprehensible.

For crying out loud, how hard is it to get this through your head? If the server knows A = A, and the client comes along and says A = B, then it tells the client to f off. Are you trying to argue that to not be the case? Seriously?

“Not only does it not scale very well but the client is still free to lie about whatever it wants.”

How is that even close to a logical statement? The server-side variables don’t just suddenly go ‘oh hey wow yeah that random dude said 30000 so now I equal 30000’ - unless you specifically implement the function to make that happen.

Brain exercise time.

Clientside -

– Trigger a server event named lowiq, pass the string ‘admin’ to it.
TriggerServerEvent(‘lowiq’, “admin”)

Serverside -

RegisterServerEvent(‘lowiq’)
AddEventHandler(‘lowiq’, function(role)

– a function that pulls identifiers off the source client, returns true if admin
local hasPower = getAdmin(source)

if hasPower then
< – insert sql query to do something and whatever other means needed to add this role to user —>
end

end)

Commented to hopefully aid your understanding.

In this example, are you telling me that the server is just all of the sudden going to go ‘hur dur, we got told to make this dood admin so lets just skip the first function and the if statement and make dat happen’ ???

Second half;

I didn’t ask for feedback.

'nuff shitposting, bye.

And now forum moderators are removing my posts? Why am I not suprised?

Perhaps its the tone that you are talking with each other. We expect a level of decency. No personal attacks for example. Have a civil discussion with no swearing at each other and nothing will be deleted

1 Like

No shit its personal when peoples servers get attacked wtf do you expect?!?!?! 0 brain

Then this idiot ioerror claims he isnt a part of it obviously lying.