Advertisement

Packet safety

Started by March 09, 2015 08:39 PM
6 comments, last by hplus0603 9 years, 8 months ago

I would like to add sequence byte to packet header against packet injections but I don't know how to implement it. What should I do?

Sequence number shouldn't be same repeatedly, and have a long period.

whats to stop the person from just creating a valid packet sequence number? what type of injections are you worried about?

Advertisement

whats to stop the person from just creating a valid packet sequence number? what type of injections are you worried about?

Against using simple tools like "Winsock packet editor" and injecting or modifying packets easily. However its easy to disassemble, just wanted to save from little hackers.


However its easy to disassemble, just wanted to save from little hackers.

I don't buy the underlying assumption that someone who is motivated enough to perform packet injection on your protocol, will be daunted by having to disassemble a random number generator.


Sequence number shouldn't be same repeatedly, and have a long period.

Any decent pseudo-random number generator will fulfil those criteria. For example, this one.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Perhaps we should analyze the data you are wanting to send from the client that you dont want to be injected?


I don't buy the underlying assumption that someone who is motivated enough to perform packet injection on your protocol, will be daunted by having to disassemble a random number generator.

Actually not for real security, just going to use it in fun project.


Any decent pseudo-random number generator will fulfil those criteria. For example, this one.

I can't find 8 bit version of this with long period.


Perhaps we should analyze the data you are wanting to send from the client that you dont want to be injected?

Yes, client generates sequence number each packet when sending it, then server verifies it.

Advertisement
I can't find 8 bit version of this with long period.

An 8-bit version could only have a maximum period of 255 without lag register (at which point it becomes silly to use an 8-bit generator, you can just as well use a larger one then).

What's wrong with the 64-bit multiplicative version with 1024 bits state? You don't have to consume all the bits that come out of it, you know. You can always do xorshiftstar1024() & 0xff if you only need 8 bits (but 8 bits make a poor sequence number... if I'm malicious, what will I do given a 8-bit sequence number? Right, simply send 256 packets...).

If the server is to "verify" the message, why not add a MAC?

I can't find 8 bit version of this with long period.

An 8-bit version could only have a maximum period of 255 without lag register (at which point it becomes silly to use an 8-bit generator, you can just as well use a larger one then).

What's wrong with the 64-bit multiplicative version with 1024 bits state? You don't have to consume all the bits that come out of it, you know. You can always do xorshiftstar1024() & 0xff if you only need 8 bits (but 8 bits make a poor sequence number... if I'm malicious, what will I do given a 8-bit sequence number? Right, simply send 256 packets...).

If the server is to "verify" the message, why not add a MAC?

Why maximum period would be 255? Actually I meant by "period" for example if it was 2bit I want it like this (2, 0, 1, 3) next (3, 2, 0, 1) (0, 3, ..) and more.

"xorshiftstar1024() & 0xff" can generate same numbers repeatedly.

Why maximum period would be 255?

8 bits of state can have 28 = 256 different states. Ideal random number generators have periods that are of length 2N-1 (don't ask me why it's 2N-1, not 2N, there sure is a mathematical reason for that too, but I wouldn't know it).

Anything you do in your pseudorandom generator is deterministic, so X inputs cannot possibly give more than X outputs (though they can give fewer if the generator doesn't have maximum period).

If you want longer periods, you need more state. One method to do that is to simply use larger integer types (but be cautious, the magic constants on the xorshift generator are not just some arbitrary, random constants, they need to have precisely chosen characteristics as described here, so if you use a different integer size (32 or 64 bits) you need different shift constants).

Another method to add state is to have a "lag register" which is nothing but an additional memory location (or an array of values) that you update one value per iteration. This is how e.g. Mersenne Twister manages to get such a long period without running excruciatingly slow -- it does one iteration for every random number that you want, reading and updating a single, different seed from an array of 623 integers.

The amount of state is not necessarily the same as the number of bits of output, though. You can easily have a generator with 1024 bits of state that outputs 4 bits at a time. You will still only have 16 possible numbers in those 4 bits, but the period will be much longer before it repeats.

The other problem with 8-bit random numbers is that 8 bits are way too little. 16 bit is something I might be able to guess in considerable time if I'm very lucky. 32 bit is something that's unfeasible to guess (I can't practically keep sending you billions of packets until one makes it through). On the other hand, if there are only 256 possible sequence numbers, I only need to send 256 packets and one of them will be guaranteed to be correct. A slow home internet access is nowadays able to send out 2,000 packets per second no problemo (some people will be able to send 20-30 times as many).

You really want 16-bit sequence numbers at the very least (32 bit is better). While it is still possible to try them all through, it's not very practical.

"xorshiftstar1024() & 0xff" can generate same numbers repeatedly.

Yes, it can and it will. That's a consequence of the fact that 1024 bits of state map to 8 bits of output, there is no other way than there be collisions (and incidentially the same number twice in a row, sometimes).

However, that is relatively harmless (OK, for a sequence number that is actually pretty bad, but what you describe isn't really a sequence number, it's more a kind of "obfuscated check number") since it will not generate the same sequence of numbers over and over again, even if some numbers repeat every now and then. In fact, this is something that makes a wire analysis much harder. If, say, both the hypothetical internal states 123456789 and 987654321 generate the number 4, you can't tell from looking at the traffic (which only shows "4") what the internal state is. (Truth being told, on a not cryptographically secure generator, you actually can... but not that easily, not by looking at one or two packets. You'll need dozens or hundreds of packets for that and a lot of knowledge.)

If you think it's a problem, you can add the output of the generator to your current sequence number, so sequence numbers will only repeat once they wrap around (be wary of possible undefined behavior on signed integer overflow).

for a sequence number that is actually pretty bad


Typically, when you talk about sequence numbers, the only randomness comes in generating the initial sequence number. Following that, further packets are numbered in sequence -- hence "sequence" number. The description of the TCP protocol in "TCP Illustrated" should server well to illustrate this in more detail.

If you want to avoid someone in the middle who can only affect one packet from editing the packet, it's much better to use integrity checking using HMAC. Agree on a secret key between server and client, and then sign each packet using that key. If someone edits a packet, it will not match the signature, and you can discard it. How to actually negotiate that secret becomes complex if you want to avoid sophisticated man-in-the-middle attacks (such as your ISP being an attacker) and is why we have the TLS protocol to solve that for us.

Anyway, an actual attacker for a game will typically do one of four things:

4) Use an in-memory editor that changes your client while it's running, and thus re-uses all the crypto/random stuff that you wrote.
3) Write a script that pretends to be your client.
2) Attack your servers using zero-day type exploits -- why attack your game, when the NTP implementation on your server is wide open?
1) Social engineer your users on forums, e-mail, messaging channels, and support staff.

Also, I have sorted these in order of "least prevalent" to "most prevalent" from my experience. "Editing packets on the network" doesn't even make the list.
Guard against #1, and most attacks disappear.

Evildoer: "Give me your password and I will power level you!"
User: "OK!"
...
Support Call: "My account got hacked!"
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement