Script Encryption

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply
User avatar
Don MacSween
Gnoblar
Posts: 2
Joined: Thu Sep 11, 2003 3:00 am
Location: Northampton, UK
Contact:

Script Encryption

Post by Don MacSween »

I am currently porting some simple RC4 encryption code over from one of my other projects, my plan is to create a little plugin that allows people to encrypt all of their external scripts (possibly even other file formats too) to prevent users from hacking or tampering with them.

I think it will be most useful for games (but people may find other uses) for example;
If you have a game where low levels of light prevent players from seeing an enemy you dont want some clever little S#!T altering your files so that all enemies have glow in the dark textures!

The encryption roughly doubles the size of the data and there will be a small overhead for decryption and so may not be suited to some situations.

It's not top of my list of priorties atm so it may take a few weeks but it will be nice to be able to give something back to the community.

This is my first real bash at creating something for OGRE and wondered if anyone else out there would find this plugin useful ?

User avatar
toastie
Gnoblar
Posts: 17
Joined: Fri Mar 07, 2003 3:49 am
Location: Gotham City
Contact:

Post by toastie »

Sounds cool, although, I think people will always find ways around encryption, if they really want to.
I've given some thought before to the problems like the one you stated above, light intenisities, wallhacks etc, and the only reasonable solution have always seemed to lay in some kind of server-side checks.
Obviously, it's pretty much impossible (not to mention, unreasonable) to verify all geometry of every client with the server, but I was thinking that a basic server-verification check for geometry crucial to a multiplayer map could be implemented.
ie, For lights, you could have something like a sum of all light intensities checked against the server (and while of course, you could dim certain lights and make others brighter, it would still pose a challenge).
Rest well this night. For tomorrow you sail for the kingdom of Daggerfall.

User avatar
Snugglebear
Gnoblar
Posts: 22
Joined: Wed Oct 01, 2003 7:38 am
Location: California

Post by Snugglebear »

It's a decent idea but not one that's too pragmatic. The problem with your average h4xor is that what they're editing happens to run on their own machine. So if you write an app to encrypt/decrypt stuff on the fly they'll eventually be able to track down where you're hiding the key. Once that happens the encryption's only value is to the local electric utility.

As for server/client data checks, same idea. The aggressor has control over everything on that machine. This includes the network stack. It's not uncommon to use a proxy server to track all the data passing out the network and figure out the protocols in use and the variable names and values. Once you know the kind of check that is done on the client data you can figure out the `good` answer, intercept the packets, and insert your own carrying the correct values. Virtual filesystems are another way of defeating checksums. What it comes down to is that the client cannot be trusted.

This is why I'm in favor of intelligent servers. They need to have enough code behind them to be able to call bullshit when they see it. There's not much that can prevent someone from changing skins or models, but you may at least be able to prevent most weapon/speed/ammo hacks.

User avatar
Antiarc
Greenskin
Posts: 120
Joined: Thu Jan 23, 2003 8:40 am
Contact:

Post by Antiarc »

Rather than encryption (which will eventually be broken), you can have the client send the entire script to the server (or a third party validation machine), which can then hash the script and compare its hash against a known good hash, thereby determining whether or not the script has been tampered with. A flagged script can simply cause the client to be denied access to the game. Of course, this is susceptible to a proxy intercepting the request and sending a clean script, but if you get sufficiently tricky, you can make it not worth the effort hack the game. Any game is hackable if the client is doing any calculations (as is the case with almost any game out there) - the trick is to make hacking it not worth the time.

Rule #1: Nothing on the client (including encrypted files) are trusted.

Rule #2: The client should make as few calculations as necessary, and even then those should be non-critical calculations. Rather, you should send events to the server (ie, player1 moves forward for 0.72 seconds) and then let the server decide where the player should be. You can use client-side scripting for display purposes (ie, the client isde script decides the player moved 3 units) but the server's settings override the client's, so the server sends back "you moved 1.2 units", and the player "rubber bands" back 1.8 units. The client never sends "The player moved 3 units". Ideally, it should only pass events and parameters to those events. That becomes less practical in reality, but you can use that model to protect your most critical pieces of game state.

User avatar
Don MacSween
Gnoblar
Posts: 2
Joined: Thu Sep 11, 2003 3:00 am
Location: Northampton, UK
Contact:

Post by Don MacSween »

My particular implimentation is going to be in an online only game so the issue of storing the key locally is not so bad, it will obviously still be in memory somewhere after it is transmitted but trawling through memory dumps is much more difficult than trawling files or reversed code.

I do agree that game servers need to intelligent but that is far easier said than done especially if you have thousands of people on one server (or cluster) as the overheads for implimenting 'clever' code can be huge.

I also agree that the client cannot be trusted, a fact that is causing me a royal pain in the ass ATM as I am trying to impliment a sever side collision map against Spoke's LandScapeSceneMangager plugin and things are not going well :? . Just to stop hackers running through the terrain!

As for network traffic capture, the routine I am porting comes from my own network lib where each batch of packets are encrypted with a key generated from the last sucessful packet :)
each 'batch' has a lifespan of about half a second so given the computational power required to crack it by the time they did it would be usless.

The bottom line is just to make life as difficult as possible for any hackers, yes this makes life more difficult for us but I consider it a fair trade :twisted:

User avatar
Antiarc
Greenskin
Posts: 120
Joined: Thu Jan 23, 2003 8:40 am
Contact:

Post by Antiarc »

Just remember: if you can decrypt it on your server, it will eventually be cracked on the client. It's a simple fact of the industry. All they have to do is decode a single packet and then they can decode all subsequent packets. It's foolish and doomed to failure to assume that crackers won't be fast enough to catch the key and rewrite packets. Hell, they could just block the socket till they have cracked the key, then start letting the packets through. It's not like the server knows the difference. A cracker just needs to find the memory position of the key once, and then it's open season on your app.

As far as ensuring terrain collisions, you know what the height are on the server, right? And you know what the maximum moving speed for a player is, so you know what are valid and invalid values for the player's position within a certain timeframe. Rather than trying to implement collisions, just check the player's position against valid positions. You shouldn't even have this problem, though. The client should never tell the server what the player position is - rather, it should only send move events, and then the server will tell the client where it is. This completely solves the problem of walking through terrain and such, as the server will have complete control over the position of the client. You only need player-terrain collision checking on the client for display purposes. The client is never authoritative.

Guest

Post by Guest »

Sorry about the guest post I've managed to lock out my account (having problems with my mailserver) :oops:

Ahh I was wondering if you'd spot it :) yes each packet batch is encrypted against the last but there is a variance cycle in there as well so even if they did break one packet the key would only be good for about 10.5 seconds and the seed for the variance cycle is generated on a per session basis. I know that it's not perfect but the hacker would have to have huge processing power (lots of machines networked) to crack the packets realtime and make use of them.

As for the my terrain / server side collision I dont think I explained myself very well.
I do keep absolute positions on server:
The client sends a move request message to the server.
The server checks to see if it is valid
Sends a message back with new co-ords

My problem is not the player's position but other players (and objects)around him/her:
the height data on the server says that 'Bob' is at x,y,z (standing on a hill) which is say 100 units away from the player, if the LOD at that location is low he will be placed in the air above the hill (where the ground used to be before the LOD reduction)

It may just be my collision implimentation or I may need to find a way to 'snap' the player or objects to the 'displayed' terrain.

Any ideas appreciated.

BTW you have my deepest respect for yor work on NURBS in the LandScapeSceneMangager plugin project the sort of maths it requires makes my teeth ache just looking at the equations :)

Don MacSween
aka Jester

User avatar
zen
Gnoblar
Posts: 9
Joined: Thu Sep 11, 2003 5:28 am
Location: Madison, WI, USA

Post by zen »

Anonymous wrote:My problem is not the player's position but other players (and objects)around him/her:
the height data on the server says that 'Bob' is at x,y,z (standing on a hill) which is say 100 units away from the player, if the LOD at that location is low he will be placed in the air above the hill (where the ground used to be before the LOD reduction)
RayQueries are your friend.

I would suggest that the server sends back the player's x and z coordinates and if the player is standing on a static structure or some piece of non-terrain to send the y coordinate. Otherwise have it send the y coordinate as something invalid (such as -1 which never occurs in the terrain) and if the client receives a -1 for the y value, it'll do a rayquery to properly set their y position based on the LOD.

The server would maintain their actual Y value and the rayquery would only be used client-side to counter the LOD.

User avatar
Snugglebear
Gnoblar
Posts: 22
Joined: Wed Oct 01, 2003 7:38 am
Location: California

Post by Snugglebear »

If the client ships the script, or even the entire collection of data files off to the server for checking, that doesn't make it secure. Using a proxy the aggressor can find what goes out, what the legit stuff looks like, then insert it into the stream. Your server won't know the difference.

User avatar
Svapne
Gnoblar
Posts: 6
Joined: Tue Apr 15, 2003 9:13 pm
Location: Uxbridge, MA
Contact:

Post by Svapne »

To stop the casual hacker I used the Rijndael cryptography library in my script resource manager... Works pretty well, but you have all the same problems listed here.

Anyone interestd in the library, it can be found here:

http://kvirc.firenze.linux.it/cgi-bin/p ... ?view=code

-Scott
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.
::41554D::

User avatar
JesterFM
Gnoblar
Posts: 3
Joined: Thu Nov 13, 2003 7:34 pm
Location: Northampton, England
Contact:

Post by JesterFM »

Praetor you are a star! Thank you for that idea I'll give it a try when I have some time free at the weekend.

On snugglebears thought;
I think that Antiarc's idea of validating the scripts against a server version is good as long as the comms with the server is secure (which in my case it is reasonably so)
Unfortunately I am developing a MMORPG so I will have a huge number of external scripts / definition files not only for the OGRE engine but bytecode for game actions, objects etc validating all of these prior to play would take a long time especially if the user is on a 56k modem.
But thinking along those lines summing the file checksums and checking that value could be fairly painless and maybe adding a random single file checking in periods of low traffic to catch the more talented hackers.

Any more thoughts ?

User avatar
Antiarc
Greenskin
Posts: 120
Joined: Thu Jan 23, 2003 8:40 am
Contact:

Post by Antiarc »

Any data sent from the client is tainted. As Snugglebear said (and as I pointed out in my original post), a cracker could use a proxy to intercept the send request and relay a clean copy of the script back to the server. MD5 sums and CRCs are also unsafe, as they can be spoofed.

A possible defense against retrieval of the encryption key is to run some kind of Punkbuster-type program, which disallows connections if there are any kind of programs running that attach themselves to the memory spaces of other programs. This prevents memory editors from being used, but it also makes debugging a pain, since deuggers attach themselves to the app's memory space in order to provide debugging information.

The best solution (and the one I stick by) is to not allow the client to send any kind of authoritative and quantiative information. By keeping quantative calculations on the server, you prevent the client from playing beyond the rules. Of course, it's still possible to use things like aimbots - aim is purely client-side, and must be dealt with differently, but the majority of gamestate-affecting exploits can be avoided by making the client responsible for as little as possible.

User avatar
Snugglebear
Gnoblar
Posts: 22
Joined: Wed Oct 01, 2003 7:38 am
Location: California

Post by Snugglebear »

Which in turn increases the cost of writing and running the server daemons. But this is what you have to pay to defeat at least some forms of hacks. We've been discussing this for months while working on our flight sim and have come to the same conclusions as Antiarc and most other professional developers.

Being open source makes hacking even easier, since they've got a good map to the protocols and can change the executables with far greater ease. Thus the most we can do is try to make that daemon smart and keep the client from making any real decisions. Since we're a flight sim this gets dicey, though, since lag by relaying events through the server can be the difference between life and death. So far the best we can think of is to have clients broadcast certain events (e.g. missile fired at Bob by Alice) so they can begin to react, then have the server check and nullify that event if it's bad.

I'm trying to come up with a decent social rank of sorts that has a basic concept of trust, as well. Probably what will be done is that each player's client will generate a pub/private key and use them for identification. The server administrator can then decide if that player is trusted, for instance the player is a regular/friend/etc., or not, someone that just joined in from out of nowhere. If the player is trusted, most of those server BS checks can be disabled, but if they aren't, we check just about everything. When something fails a check, the event is nullified and the player gets a bad mark. Have too many bad marks and the daemon takes administrator-configured action.

User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19265
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66
Contact:

Post by sinbad »

I may be way off the mark here because I don't have any experience of developing this kind of product, but how about extending the concept of 'assume everything is ok but check in the background' by only sampling the traffic from each client? By that I mean assume all the packets are good, but randomly check the packets from each client in a separate thread, and if a duff one is found, disconnect the offender and nullify their score or whatever.

I would have thought that the chances are that if a person is cheating, a good proportion of their packets are going to be hacked (if not all of them) so a sample should pick them up without weighing down the server as much as validating everything. Ok, they may get away with it for a while, but in many ways that's better because it's more difficult to test a hack if you don't have a guaranteed immediate failure.

User avatar
Antiarc
Greenskin
Posts: 120
Joined: Thu Jan 23, 2003 8:40 am
Contact:

Post by Antiarc »

Something to consider Snugglebear:

Have clients do validations for other clients. If you have 6 clients, and each client picks two peers (with the server being a valid peer) to send events to, the peers can then vfalidate events. Statistics tell us that so long as there are more valid client than hacked/invalid clients, then you can perform multiple validations and more valid clients will agree than invalid clients. Client 1 sends event to Peer 1 and Peer 2. Peer1 and Peer2 decide what happens due to that event, and update their own gamestates. They then propagte the results of those changes to the other clients. If there is a discrepancy, then a) ask a third peer (probably the server, which is trusted) for an evaluation, and b) flag the "bad" peer (the one the third peer doesn't agree with) with a "bad mark". With proper synchronization, you can offload tons of processing cost onto the clients at the price of bandwidth, yet not bog any one client down too much. The practicality of that method may vary based on the application, but if you have more bandwidth than CPU power, then it's perfect.

The model needs a little refinement, but it's something I've been kicking around for a while now, and think it could be done, given the amount of bandwidth the average user has these days.
Last edited by Antiarc on Fri Nov 14, 2003 1:16 am, edited 1 time in total.

User avatar
Antiarc
Greenskin
Posts: 120
Joined: Thu Jan 23, 2003 8:40 am
Contact:

Post by Antiarc »

sinbad wrote:I may be way off the mark here because I don't have any experience of developing this kind of product, but how about extending the concept of 'assume everything is ok but check in the background' by only sampling the traffic from each client? By that I mean assume all the packets are good, but randomly check the packets from each client in a separate thread, and if a duff one is found, disconnect the offender and nullify their score or whatever.

I would have thought that the chances are that if a person is cheating, a good proportion of their packets are going to be hacked (if not all of them) so a sample should pick them up without weighing down the server as much as validating everything. Ok, they may get away with it for a while, but in many ways that's better because it's more difficult to test a hack if you don't have a guaranteed immediate failure.
Well, the only problem with that is...how do you know what packets are good? How do you determine a good packet from a bad one? There is no "control" - you have to take the client's word that the packet is good.

User avatar
Snugglebear
Gnoblar
Posts: 22
Joined: Wed Oct 01, 2003 7:38 am
Location: California

Post by Snugglebear »

That's an interesting idea for how to offload the checks. I'd be tempted to jump on it, but first my group has to solve some other multiplay design issues. We're trying to be interoperable with a couple other OSS sims and need to bang out the protocols. There are some existing comm protocols for tying dissimilar sims together that were developed by the DoD that I learned in grad skool, but they're extremely expensive in terms of bandwidth. The other problem is that we've got a faction who are quite adamant about support for 56Kers, who, frankly, make me want to punch my head through the wall. It's definitely something new to me trying to keep a steady course through this, though it's not yet reached the intensity of the OpenGL/DX battle we had a while back. Oddly enough, OGRE was the solution to that.

Guest

Post by Guest »

The first thing to consider is that using sheer computational force to break a key (of a decent strength is enormous. However as with so much in computing and especially games it is a trade off the larger the key you use the more data it requires and the more processing power it requires.

The second thing to consider is; assuming that your encryption will be broken, how long would it take to do so and what is the lifespan of your data.

One size does not fit all as for example packet data for first person shooters like Quake or UT has a much shorter life span than a MMORPG or RTS.

By constantly changing your keys on the fly using a fractal or similar technique you can create a scenario where it takes longer to crack the key than the useful lifespan of the data.

If the hacker is using a AIM bot so that they never miss a target, the data they use is no good if it takes 10 seconds to break the key & extract, as the victim in all probability will have moved by then (any player not moving in 10 seconds in a shooter has it coming anyway :) )

Cyclic keys is the method used by most ATMs and cash machines (they just use huge keys), I know this because I used to work for a company developing them.

Yes, as Antiac pointed out you need to keep the hackers out of your programs memory (to protect the key)and yes the client should be responsible for as little as possible, but half of the battle is won if you can secure your comms to a resonable extent.

As a bit of light reading for anyone interested in the subject I would recommend "Writing Secure Code" by Howard / LeBlanc it's published by Microsoft press (but dont let that put you off :) )ISBN: 0-7356-1588-8 and covers all of the issues we've been through and more.

User avatar
Snugglebear
Gnoblar
Posts: 22
Joined: Wed Oct 01, 2003 7:38 am
Location: California

Post by Snugglebear »

But the client machine is considered to be hostile. Having secure comms with any box protects from a 3rd party interloping between the client and server. The client is the hacker's machine, he has root, he has access to all memory, processes, files, etc. While you could try and make things harder by using multiple keys or obfuscating things by placing pieces of keys all over the drive (akin to FreeBSD gbde), eventually the hacker will figure out where that information is stored. He can then sit there and watch the disk or memory and capture the key as it is assembled for use. Changing keys every few seconds simply adds more load to the machine.

User avatar
JesterFM
Gnoblar
Posts: 3
Joined: Thu Nov 13, 2003 7:34 pm
Location: Northampton, England
Contact:

Post by JesterFM »

Security measures vary a lot depending on the type of game you are creating.

In my case I am working on a mmorpg so I have a client-server setup
so my issues are primarily to do with hackers tampering with material properties to give them an edge. The game comms are completely open as all player actions are validated by the server.

My strategy therefore requires that I check my scripts to see if they have been messed with both when the game starts up and randomly when the player is idle.
So I:
encript the scripts to keep Jo public out.
use dynamically assigned memory whenever I have to temporarily store a key.
Change the key at regular intervals.
Keep other programs out of my memory space

In your (snugglebear's) case you have a high twitch peer to peer, or peer to small server scenario and so you have completely different problems.
Encrypting all your comms will cause increase the size of trasmitted data and probably kill off any hopes for 56k compatability.
Peer validation is a good idea but once again kills off the 56k element and exposes one player's data to another possibly causing a security risk.
So we're back to the smart server idea, which can be done tho as said before is far from easy, if you are storing game data for league tables then it make thing easier, keep an eye open for people with 100% accuracy :)

But seriously, if you use data mining to examine your beta tester's figures you should be able to come up with a standard learning curve for the game which will give you something to compare player's data with, any sudden spikes in the players ability could then flag them for closer attention.

User avatar
bad_camel
Halfling
Posts: 74
Joined: Tue Dec 17, 2002 11:57 am
Location: Somerset, England
Contact:

Post by bad_camel »

I don't know much about this sort of thing, but isnt only random checking when they are idle also a bit useless.....they can just make sure they are never "idle"

User avatar
Snugglebear
Gnoblar
Posts: 22
Joined: Wed Oct 01, 2003 7:38 am
Location: California

Post by Snugglebear »

People with 100% accuracy are not that far off normal, especially considering the PK numbers with modern weapons. The server monitors ammunition levels and makes all decisions about hits and damage, so that also is removed from the equation. Aimbots will be hard to get right since there are limits to what an aircraft can do to get its nose (or turret) on target. If there's a violation of that limit we know there's either a cheat or a network error occuring.

User avatar
JesterFM
Gnoblar
Posts: 3
Joined: Thu Nov 13, 2003 7:34 pm
Location: Northampton, England
Contact:

Post by JesterFM »

@bad camel: Idle was possibly a poor choice of words, rather when the player is not doing something bandwith critical like combat, but the genre tends to have lots of 'idle time' such as when a player is looking for a group to play with, standing there chatting to someone or rearranging their kit, during any of which a random file check could be slipped in.

User avatar
Aklix
Goblin
Posts: 222
Joined: Mon Dec 27, 2004 5:21 am
Contact:

Post by Aklix »

Handshake the decryption key from the server?

User avatar
haffax
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4823
Joined: Fri Jun 18, 2004 1:40 pm
Location: Berlin, Germany
x 6
Contact:

Post by haffax »

No need to exhume this thread.
team-pantheon programmer
creators of Rastullahs Lockenpracht

Post Reply