Discuss the massively-multiplayer home defense game.
You are not logged in.
The super-easy cheats (like reading house maps from the recorded game files, or walking through walls to reach a vault) were sealed off long ago.
There are a few more lingering issues:
1. Yes, starting-state house maps are encrypted as they come from the server, but at the end of a robbery, you send back the finished house map in the clear. A simple packet sniff will get the map for you, and if you just peek in the front door before ending the robbery, the end map is very similar to the supposedly-secret start map. Yes, that sent-back map can be encrypted (and will be). In fact, the server can verify the move list without even receiving the end-state map at all (though I will probably keep the sent-back map in there as an extra check to making modding harder).
2. The server verifies your moves at the end of the robbery and kills you if you walk through a wall or if a dog that isn't supposed to see you sees you. But if you're using a second account to do this, so what? Even without modding the client, you can mod the data files to change the properties of walls. Then, you can walk through walls and get a good look at a house's internals, maybe to use later (after the chill wears off) or maybe to use in a second, non-cheat account. Yes, I can detect clients that walk through walls on the server and auto-ban those accounts. But then the clients would just quit before the end of the robbery and never submit the suspicious move list to avoid my detection. Clearly, the gameElements folder needs to be verified at start-up to prevent this. The game should refuse to run if the sigs on the various object properties don't match. The problem is that a modded client could skip this verification, or simply change the embedded key that is used to check the sigs (thus allowing modded wall properties to be falsely signed).
3. A modded client can turn off the shroud during robbery entirely, or implement changes that allow panning around the whole map without moving the robber. There would be no way for the server to detect this.
Yes, I can make it harder for people who don't want to do full-blown mods to cheat. I can make packet-sniffing useless. I can make basic fiddling in the gameElements folder useless.
But this is an open source game, and on one platform (Linux), the game currently ships as source. Meaning that a substantial chunk of players are ALREADY compiling their own version of the game on a regular basis. Thus, full-blown mods aren't just likely---they are inevitable.
And with a real mod, encrypting the protocol won't stop you. Signing stuff in the gameElements folder won't stop you. Drawing a visual shroud on the screen won't stop you.
The REAL way of doing this would be to have everything happen on the server, with the client just acting as a dumb tile display. You ask the server if you can take a step. The server sends back the tiles you can currently see. You ask to step forward onto a button, and the server tells you that the door opens.
But, as many of you have experienced, during peak load times, or internet outages, or whatever, several seconds of latency for a server request are common. That's okay when you're waiting to check in a house. You can watch the progress icon for a bit. That's not okay when you're waiting to take a step in a house. This is the reality of an indie MMO hosted inexpensively on a web server.
So, that brings me back to trusting the client. But how can I do that?
It seems that having a list of "trusted" binary builds will be necessary. The main server would only allow connections from those binaries.
But how can the server know what binary it's talking to? If you embed a private key in the binary, that key can be located and extracted, and then compiled into a modded binary.
There are various methods of obscuring keys in the binary (spreading the bytes of the key around, etc). But they aren't very satisfying. Also, since the code will eventually need to assemble the hidden key to use it at runtime, it seems like a RAM analyzer could grab that key out of memory at runtime.
The idea that I've come up with is to embed a secret algorithm itself in the binary, and mirror that same secret algorithm on the server. The request signatures attached to each client request would then be passed through that secret algorithm, and the server would use the same secret algorithm to verify these request signatures.
So, this is really the same "shared secret" idea as hiding a key in a binary, except that it's a block of machine code, which is much harder to extract and replicate from an EXE than a simple key string (and also just as hard to pull out of RAM).
Just as various encryption parts of the game ship with "placeholder" key values in the code now, the source would include "placeholder" secret algorithms as examples. To run your own server, you'd plug in your own algorithm (or just stick with the stubs, if you don't care about untrusted clients).
Each new version of the game could ship with a changed secret algorithm, making the server rejection of old versions of the game more robust than just trusting the client to report its version honestly.
Anyway, in order to trick the server in this scheme, you'd need to:
1. Study and decompile the EXE to find the secret algorithm.
2. Figure out how to re-code that secret algorithm into your own modded client.
Both things are many rungs above "sniff packets" or "tweak data files" or even "open EXE in a hex editor." And even if you accomplished that, you'd have to do it all over again when the next version comes out and the algorithms change.
The main downside of this approach is the death of flexible, compile-from-source distribution on the Linux side. Yes, I can supply Ubuntu LTS binaries.... but that won't help people on other Linux platforms.
Offline
I think that such a protection would not change anything. It would only involve you into an infinitive battle with cheaters. No matter how cool your protection is, it is breakable. Even hardly obfustaced Skype with encrypted protocol was broken.
This method can only work when you have more skills and resourses than cheaters. Unfortunately, you are alone while the number of cheaters is growing with popularity of your game.
The idea that I've come up with is to embed a secret algorithm itself in the binary, and mirror that same secret algorithm on the server. The request signatures attached to each client request would then be passed through that secret algorithm, and the server would use the same secret algorithm to verify these request signatures.
This kind of stuff works only against reimplementation of client. Changing your precompiled binary (or even just reading house map directly from process memory) is as easy as changing source. Once we are able to get map, every other protection is useless. So, no studiyng or touching your 'secret algorithm' is needed.
While game is on the client, client is boss and nothing can be done. By changing the game this way you will harm anyone, but not the cheaters. In this case you will harm poor linux gamers. Please, don't do that
So, I suggest that the only way is to move as much as possible to the server.
Probably permament banning of cheaters would also help.
Last edited by der (2014-01-02 14:06:05)
Offline
Well.. the hard part is CATCHING the cheaters at this point. Are you peeking at the map, or just really lucky? There's no way to tell, server-side.
The other problem is that stopping MOST cheaters isn't good enough... even one cheater can sweep the server quickly and destroy the top houses. That would ruin the game for everyone. So... you're right that the "blessed" binary idea won't work. If even one person bypasses it, then every other player in the game will be angry.
So... as far as "moving everything to the server" goes, this means simulating the whole map server-side (because there are cross-map effects that can't be simulated on the client with only a portion of the map).
The client would get just the states of the visible tiles, and then ask the server to move North. The server would take the full map, simulate that move, and the return to the client with the states of newly-visible tiles. The client would just be drawing those tiles.
Client would mirror the game logic to make that drawing easier, and also for self-tests and tape playback (which don't need to be simulated server-side, because the client already has the full map in those cases).
So, every move would require a complete round-trip to the server to resolve. I'm pretty sure the server would have to maintain an open socket with each client to pull this off (and this part of the protocol wouldn't be http, but compact binary for speed). So, client sends move to the socket, server responds on socket with 169 bytes representing visible objects (13x13) and 169 bytes representing the states of those objects and maybe a sparse list of mobiles.
I've been worried about how slow this round-trip would be... but then I remember that typing over SSH requires similar round trips (or paging through a text document over ssh).
In a network hiccup, it would be really annoying, of course. Press UP and wait... then a few seconds later, your guy moves.
I also have concerns about RAM (for storing current map states) and CPU (for simulating each move) server-side, especially as we get more players.
I'm becoming more convinced that doing this hard work will be necessary on my part. I hope you folks can pitch some ideas in here... what am I missing? How could I do it with less overhead?
Offline
've been worried about how slow this round-trip would be...
You should not really care about speed of network: there are online fps shooters! Of course they use client-side predictions, but you can do the same.
This game is step-based, so delay is not as vital as you threat it. With using sockets delays should be minimal.
I also have concerns about RAM (for storing current map states) and CPU (for simulating each move) server-side, especially as we get more players.
That's probably the most important issue, but it is resolvable.
About RAM:
30x30 map with 2 bytes per cell is about 2 Kb.
Let's imagine we have to store another 2 Kb for the rest of needs.
4 Kb * 128 players = 0.5 Gb of RAM for storing all the information.
You can store this data in the database, which will give the ability to restart server without losing progress.
Or you can store it in RAM: it will be a bit faster, but you will need more RAM on the server.
Sounds like a real limit for one budget server. But you have to think about scaling. In other words, you should be able to start 2 or more servers when they are nesessary.
About CPU loading:
As soon as the game is turn-based, calculating of changing the map is needed only on turn. People are slower in this case. I don't think that server will get more than 50 turns per second even if it has 512 clients.
But even 10 t/s can probably kill server (I have no idea, I didn't yet read the source). Moreover, making tons of threads is not the best idea. That's why it's better to process "turn requests" continiously in one thread (or few, depending on the number of cores on server).
Thus, the list of things I imagine have to be done:
Separate (please, don't code 2 different versions, or you will die updating it ) turn logic so it can be used on both client and server. Probably you already have it abstracted in client
Write server that uses this logic (and only logic, it should not know about textures or anything like that, or it will be slow) and works with clients. Clients sends actions and get a little area near him (probably not strictly 13x13, but only visible tiles. a good example is minecraft anti-cheat plugin which replaces invisible blocks)
Be sure that client can handle with 2 or more servers because they can be overloaded
Last edited by der (2014-01-02 15:59:18)
Offline
In a network hiccup, it would be really annoying, of course. Press UP and wait... then a few seconds later, your guy moves.
I agree with der that because it's step-based, timing isn't so critical. Personally I take more than a few seconds with each move when raiding, sometimes 10 seconds per move with sweat beading down my forehead But I'm pretty new to the game still so take that with a grain of salt.
As far as predictive behavior goes, I'm not sure that applies so well here because it's discrete steps (ok, even FPS games have discrete steps but not cognitively discrete) not a continuous stream like with FPS games.
However, maybe you could do something like signal the client that it can operate in autonomous mode while there's no "hidden activity". ie, when you walk into the house, before any animals or family see you, before you trigger any circuits, etc... It can operate asynchronously and not wait for confirmation from the server unless you've walked somewhere that revealed new data or triggered something. Once one of these triggers happens it cuts off asynchronous at that point and the server won't accept any new asynchronously made instructions after that point. It should be possible to make the client aware of when it's triggered this condition (even if it doesn't know why or what the results are) so it won't be necessary to rewind the player experience.
[edit: to be clear, after mechanisms/animals/family/etc has stopped moving, it could return to async mode]
Hard to say what % of the time it could be asynchronous as described with a hypothetical optimal async-allowed detection heuristic, but if players do a lot of walking back and forth it seems like a lot of that could be async.
Down side, of course, would be that hackers could detect when the client has gone into async mode (heck, a non-hacker could probably even tell by whether it's zippy or not, perhaps that could be alleviated by introducing a short delay always) so they could know if they tripped some mechanism which is still in motion which they perhaps might not have otherwise noticed (since it may not be in view)... But that still seems like a huge improvement over the current state of the issue as you described it.
Other downside is complexity :'(
Last edited by jcwilk (2014-01-02 19:49:41)
Offline
Also, have you played the gui nethack for windows? (I think it was nethack for windows, maybe it was a mobile version) You can click on a far away tile and it will pathfind to it if there's a visible path, but it stops part way if anything visibly changes. That kind of thing could be great in castle doctrine, you could click on a tile, tell the server you want to move to that tile, then the server could compute what happens, how far you get before you notice something, etc, all in one go and return the results to be replayed to the client.
Just a thought to another high level optimization.
Offline
I think self tests is where any latency would be an issue. Those are often inputted quickly and can involve a complex series of movements with no margin for error.
Offline
Well, for the moment, I'm focused on robbery, not self-test. It's simply not as bad if someone cheats on a self-test, because it doesn't unfairly steal the work of another player. Besides, in a self test, you already have the starting-state map, and knowing the game logic, a "hacked" client could predict where the map will change after that, step-by-step, even if the server tries to hide those changes from the client.
SO... stepping self-test server-side would mainly be there to prevent "cheating death" by modded clients that ignore a failed self-test and dump you back to the edit screen. HOWEVER, even if we were stepping server-side, a modded client (which has the whole map, unavoidably) could step locally first, without sending ANY steps to the server, cheat death, and then in the end send a "safe" set of steps to the server (like... 2 steps, where you walk right back out the door). The player actually died during the self test, but the modded client ignores this and reports to the server that the player walked safely out the door instead.
SO... moving self-test server side buys us no real security against a determined cheater anyway!
But moving robbery stepping server-side buys us everything, because the robber does not have the whole map. If the vault is hidden, it will become truly hidden to the robber (as in, there is no way for the robber to discover where the vault is by cheating).
JCWilk:
Great ideas there! The problem with any kind of client-side "prediction" (like, allowing the player to move without messaging the server if the map hasn't changed) is that the client won't have the whole map, so they cannot compute whether the map has changed or not. Just because nothing VISIBLE should move, from what the client can see, doesn't mean than nothing off-screen is moving or changing. The thing that makes this such a pain (for me as a dev) are the cross-map effects through wires. Making that work, without giving the client the whole map, requires full-map sim server-side, relegating the client to being unable to simulate anything. For example, a visible light could be on for the client, with no known, visible power source (so far, from what the client has seen). Just a wire running off screen somewhere. If the player moves, with no change to what the player can see, should that light remain on or not? Only the server knows the answer in all cases.
Offline
About delays:
I made a simple 5-minute demo that prooves that they are absolutely OK
It uses http requests, but with sockets it can be even faster
Each time player moves (by keyboard arrows) it downloads 13x13 map piece from server
Last edited by der (2014-01-05 19:02:08)
Offline
For example, a visible light could be on for the client, with no known, visible power source (so far, from what the client has seen).
Yeah I was thinking the server would include metadata with the request about whether they're go for asynchronous mode, but the client doesn't need to know why it's in asynchronous mode. So for your light example, let's say there's a small room with the light in it... After they move into the room and have it explored, the server can detect that there are no more changes occurring and tell the client they're ok to move freely. Once they go near an unexplored section or hit a button to trigger a circuit change for a circuit which isn't fully represented in the room then the client would detect that it needs more information from the server to see what happens next (since it doesn't have all the required data) so it drops back into synchronous mode.
My assumption here is that changes to the house can only be initiated from things within view (or things out of view which were initially triggered by something in-view) the server pseudocode for determining asynchronous eligibility before sending a move reply back to the client may look something like:
if there may be a reaction to the player in the tick after this one (animals/family in movement [only mechanisms that have any delay/continuation right?], on-screen or off):
suggest sync
else:
suggest async
Then client pseudocode for what to do with a new move request from the player:
if async was last suggested, no circuits potentially leading off-screen have been triggered, and no new tiles may have been revealed:
simulate change client-side and queue the movement to send to the server later
else:
send the movement, along with any queued movements, to the server and await reply synchronously
It seems like that fully prevents the client from getting out of sync from the server because of how the circuits seem to execute and finish immediately and how it seems that your family/pets only react to the player in view (which means if there are no family/pets in view and no new tiles revealed there can be no off-screen reaction). The exception is if you scare the family and they start moving off-screen (do cats move off-screen too? same thing applies if so) they will continue to move even when off-screen, correct? In that case while the server knows the family is moving it just tells the client to behave synchronously.
I suppose if the family was the only thing that could move off-screen (aside from player-triggered circuits which seem trivial to detect by the client) then the client would already know it needs to be synchronous the first time the family pops on the screen. Once the family leaves the exit the server could then notify the client to return to async mode, barring any active mobs.
Seems like it works, but I may be overlooking mechanism edge cases, and perhaps the occasional benefit it awards is exceeded by the complexity.
Edit: Also, if you move from one room to another without changing anything, the client could keep track of the tiles you'd visited since your last change (animals/family/switches) and let you return to those tiles asynchronously even though they'd since been clouded by fog of war. Once you trip a change it can clear your list of previously visited tiles so that you'll have to synchronously re-explore previous, no-longer-visible tiles.
Last edited by jcwilk (2014-01-03 12:48:32)
Offline
My assumption here is that changes to the house can only be initiated from things within view (or things out of view which were initially triggered by something in-view)
Hi jcwilk, I'm sorry to say but this assumption doesn't hold. Although in MOST CASES electronics will not change without the robber or a pet interacting with them this is certainly not always the case, the most obvious example being clocks. In any house containing a clock or something like it the state of the electronics in the house would have to be calculated server side every turn because a clock can act on the electronics of the house without your knowledge.
it seems that your family/pets only react to the player in view
This is half correct, but once a pet has been activated it will remain active for the rest of the robbery and will try to move if their path is unblocked regardless of whether they are in line of sight (this includes dogs, cats and chihuahuas). This would effectively mean that as soon as a single live pet moved anywhere which you had not explored (and thus you would not know how the pet is interacting with their environment) the robbery would have to be calculated server side until the pet re-emerged. Effectively a magic dance house would have to be calculated synchronously the whole time.
I doubt client triggered asynchronous play would occur very often with these limitations in place.
Last edited by Hippasus (2014-01-03 20:27:39)
Offline
certainly not always the case, the most obvious example being clocks
Ah! I had no idea clocks and such worked in castle doctrine since there seemed to be no delay between cause and effect with wiring, apologies, this makes my suggestions almost entirely useless. Well, to be fair the server-side async detection I was describing would just always lock them into sync mode in that case, which should work fine... Perhaps most houses don't involve such mechanisms and perhaps the optimization could still cut off a significant chunk of overall client/server roundtrips...
But yeah, looking more and more like it's way overkill for the benefit Thanks for clearing that up and again apologies for not digging further first. (now I get to read about advanced circuitry, goodbye weekend)
Offline
Yeah, I've gone back and forth about this whole scheme over the past week, and now I'm fully back to believing that I should NOT change the game to make robbery steps synchronous with the server. Looking at the calendar helped: I've now been coding this design for two full years, and a synchronous game was simply not what I set out to design two years ago. What I have now has a beautiful elegance and robustness to it that I don't want to spoil.
Even something as drastic as a server crash is harmless to the active robbers in the game, assuming that they let their clients keep retrying to end the robbery until the server comes back online. Everything important is in the database. I wake up each morning without the slightest worry about whether the game service is still running. It's that robust. It's been running for 10 months without any intervention on my part. And given that I'm a one-person "team", if there was something fragile to worry about each morning, I would be the only one doing the worrying. For the rest of my life, essentially.
There's a belief in engineering circles that if security isn't perfect (as in, breaking it would take more seconds than atoms in the known universe), then it's just as worthless as no security at all. But when "perfect" security has a an unacceptable cost, "no security at all" is not the only alternative. Just because a bike lock can be easily cut by some people does not mean it's pointless to lock your bike. Imperfect security has its place. If you can stop 99% of people from doing something, that's better than stopping 0%.
One great example is the "encryption" of the robbery maps sent by the server. Before I added that feature to the protocol, pretty much everyone in the know could peek at the map of a house they were robbing. People were slurping these maps and posting them on CastleDraft all the time. Even though the encryption is by no means uncrackable (it's based on a key that is generated by the client itself and sent to the server right there in the robbery request, but fortunately NOT saved into the recordedGames folder), it is enough to make that kind of map peeking drop off the radar screen. It's no longer a thing that "most people are doing," because each map is encrypted with a fresh key, and decrypting map after map would require more effort than it's worth to most people.
But when I talked to a programmer friend about this the other day and mentioned that the maps sent by the server are encrypted, his response was, "What's the point of that? You might as well not even do that." I've now come to see that kind of thinking as flawed.
So, if the client and the server shared a key, and that key was really hard for most people to get, that would make client-server communications even harder to mess with and using modded clients much harder. Right now, either of these things are already outside the realm of possibility for all but 5% of the player base. Making it substantially harder would shrink that number significantly.
And I could do this without degrading the quality of the game experience in any way.
The alternative, while offering perfect security against cheating, would noticeably reduce the quality of the game experience for 99 people just to thwart the hypothetical 1 person. Instead, I can make that 1 person's task annoying and painful without degrading the quality for the other 99 at all.
Security has a cost. There's a reason that we don't carry around 100-pound bike locks.
Offline
i dont know much about what you could do, or code, but maybe a solution of only sending so much of the map to the client at a time. like the first sight picture, and you only update the rest of the sight picture when you move in sight to get more. So in turn, a player wouldnt have access to the whole map, but only parts of the map as he began to explore about.
Or maybe only what is in sight is sent to the client, and whenever things come into sight the server sends them to the client as well. The map stays with the server, until its needed.
Offline
The potential for cheating was something that always worried me about this
game, so it's interesting to see it being addressed. My not-very-helpful
thoughts follow.
Regarding "trusted binaries":
It would be disappointing to see what must currently be one of the most
commercially successful open source games ever lose that status. Meanwhile,
although it would make cheating more difficult, I worry that some might see
that as a challenge to be met. Dumping RAM mid-robbery and finding the map
would be an obvious ploy; another would be to disassemble the binary and
compare it to versions without the magic encryption.
Really, it's a delicate question of psychology. What kind of lock makes your
bike least likely to be stolen? Permit me a strained analogy or three.
In the first alpha releases of the game, where the map was dumped to output
and a debug line was output every time a mobile was triggered, there was no
lock at all and the bike looked abandoned, such that a reasonable person with
some urgent need might borrow it. The current situation is a two-digit
combination lock - anyone who really wants to could break the lock, but it's
clear that doing so would be against the owner's wishes. A "trusted binary"
scheme would be a lock which blares out an obnoxious siren if anyone gets
close, with a rubik's-cube-style puzzle to solve to actually unlock it. It's
begging to be stolen precisely because it's trying so hard not to be.
In other words: one way or another, it comes down to trusting the players not
to cheat. Annoying and alienating the from-source crowd, who are likely to be
among the most tochnically competent, and who as far as I know have so far
been entirely honourable, seems an odd way to go about this.
(To clarify: however this may read, it is by no means intended as a threat!)
Regarding trying to wholly prevent cheating:
Overhauling the architecture to keep hidden information on the server indeed
doesn't really sound worth the work and the latency. And even that wouldn't
eliminate sock puppetry - and, though the situation has been improved by all
the tweaks, and charging real-life money for each puppet obviously helps, I
don't think that problem can be fully solved with the game as it stands.
Possibly interesting if unhelpful remark: the design for my game Intricacy
started out much like CD's, but at some point I decided to try to design it to
be wholly impervious to all kinds of cheating - the eventual design of the
overgame, very different from CD's, seemed like a pretty much inevitable
consequence of that constraint.
Offline
Interesting points.
First of all, it wouldn't stop being an open-source game. It would just be a closed key game. The game source would ship with a key, but not the key needed to play on the main server. The source already does this in many other instances in terms of protecting the server (the source ships with various dummy keys in place so that you can't, for example, trick my server into thinking that you've paid for an account when you really haven't---only I and the payment processor have the secret key needed to create new accounts on MY server).
For people who want to build from source and run their own servers, they could stick with the dummy keys, or generate their own. Nothing would change there. What would change is that you couldn't (easily) build from source and play on the main server.
Second, what evidence do you have that everyone has been honorable? The problem with this particular kind of cheating is that it is impossible to detect. Back when the server didn't check that you weren't walking through walls, several people were doing this (clearly not behaving honorably), but it was easy to spot. How do you know that some people aren't peeking at where the vault is with a modded client? I know that, for example, Herb and many others have modded their wire sprites to show the difference between on and off wires.
Essentially, I want more assurance that everyone who is connecting to my server is playing the same game. Right now, there is absolutely no assurance of that.
Yes, I've been playing with ram dumps on this end. I've already made some progress here (so that at least the text maps don't hang around in ram anymore).
And I fully get what you're saying about the challenge of breaking a system being tempting. I myself am a hacker, and I've been on the other side of this fence many times. I was the first guy to hack the iTunes store back in the day (to allow non-iTunes clients to search the store and listen to the sample clips). That was a real thrill. And the whole time, I was thinking, "You fuckers... this is impossible to lock, so why did you even try?"
On the other hand, there wasn't a good reason (that I could see) to keep third party apps from connecting to the iTunes servers. It was just about exclusivity.
Here, there's a pretty compelling reason to ensure that the vast majority of people are playing with the same game client on the main server. It's not just about protecting robbery.... so many other aspects of the game become slightly (or very) unfair if people are playing by different rules. What if you never have to die in a self test? Wouldn't that be nice? What if you could run your self test with no shrouds?
Offline
So, if the client and the server shared a key, and that key was really hard for most people to get, that would make client-server communications even harder to mess with and using modded clients much harder. Right now, either of these things are already outside the realm of possibility for all but 5% of the player base. Making it substantially harder would shrink that number significantly.
The game source would ship with a key, but not the key needed to play on the main server. The source already does this in many other instances in terms of protecting the server (the source ships with various dummy keys in place so that you can't, for example, trick my server into thinking that you've paid for an account when you really haven't---only I and the payment processor have the secret key needed to create new accounts on MY server).
What would change is that you couldn't (easily) build from source and play on the main server.
Your ideas of 'shared' keys is not really security. It's security through obscurity. Some people would say it's completely not security.
Yes, it's pretty possible to make a tight protection using this way. Unfortunately you have no skills (or experiance, I have no idea) for that. Thus, your bike lock is decorative, no more.
sha1 (with new line) of your download code is a50ac8a7b6644ee8e0b124ac233642c7fcadb541
My suggestion: find someone who understands security. Even if your method is kind of right, you make silly architecture mistakes.
Or find someone who can move the game process to the server side, if it's too hard for you. Your game is already useless without a server.
Yes, I've been playing with ram dumps on this end. I've already made some progress here (so that at least the text maps don't hang around in ram anymore).
RAM dumps is not the only problem. It's just the simpliest. I still can attach gdb to the game and do whatever I want. This strategy is dead. Everything that process knows is easily recoverable by user.
How do you know that some people aren't peeking at where the vault is with a modded client?
I know that they are doing it, I've seen by myself. And until there is a technical possibility they will continue doing it.
Last edited by der (2014-01-06 12:50:05)
Offline
Oh, yeah, Der, that was stupid of me. Fixing that hole now by including the email address in the sha1 to generate the key.
Also, I trust that both "derlafff@..." and "castle@..." are your email addresses, and I trust that you're not going to use my ticket ID for nefarious purposes.
Offline
Oh, yeah, Der, that was stupid of me. Fixing that hole now by including the email address in the sha1 to generate the key.
Not secure again. I do know your email
Last edited by der (2014-01-06 13:24:52)
Offline
But you don't know HMAC_SHA1( secret_key, email ) for a given email address.
And being able to compute it for your own email address (which you clearly will be able to do) won't help you compute it for my email address, unless you have the secret key (which you do not).
Offline
And being able to compute it for your own email address (which you clearly will be able to do) won't help you compute it for my email address, unless you have the secret key (which you do not).
I don't understand one thing: is there any reason to leave this ticketserver feature opened to the Internet, if only servers under your control can use it?
Last edited by der (2014-01-06 13:43:37)
Offline
Yes, because I want to be able to shard out at a moment's notice to multiple game servers (while still keeping a central ticket server). I may need to do this for load-management reasons if the game becomes hugely popular. So, I make no assumptions about whether the game server and the ticket server are running on the same machine (they may not have access to the same DB, etc... I want to keep them separate).
Granted, I could have an "allowed IP list" for that one ticketServer call, and forbid Russian IPs like "212.34.113.235," but I shouldn't need to do that, assuming that I don't do something stupid in the security method.
Offline
and forbid Russian IPs like "212.34.113.235,"
I realized that I have just commited to 'evil Russian' myth, lol
Also, I trust that both "derlafff@..." and "castle@..." are your email addresses, and
I did it only to check my ideas. Feel free to ban "derlafff@" account, and threat second purchase as a contribution to a good game
I trust that you're not going to use my ticket ID for nefarious purposes
If I wanted to do any bad, I would not reveal myself in this thread
Last edited by der (2014-01-06 14:09:42)
Offline
Okay, so put the new HMAC-based method (which includes the email in the generated key for each get_ticket_id call) in place.
I've also changed my own download code.
See if you can get my download code now.
Also, I know it was easy to get the first time because I made a stupid mistake, so I'm not sure if you have any experience cracking PHP scripts, but if you do, please give it a go. I've done all the "right" things on the server, like passing every user-submitted string through a regexp, etc., so I don't think it's vulnerable to SQL injection, but I might have missed something. If there's a weakness, having the source should make it easy to find.
During the design, I was really worried about people sniffing traffic in Internet cafes and getting people's game ticket codes, but I didn't want to use SSL for the whole thing, so I treat the game ticket codes as a shared secret between client and server and never send it back and forth. Of course, the ticket codes are sent by email, but I'm assuming people are checking their email over SSL.
And the server itself uses Yubikeys for admin authentication, so even if you install a keylogger on my home machine and get my admin passwords, you shouldn't be able to get in (again, unless I made a stupid mistake somewhere).
Offline
so I'm not sure if you have any experience cracking PHP scripts, but if you do, please give it a go.
That's exactly what I was doing. I think it is a some sort of game for me.
If I find something interestring, I will email you. This time I just explored it when I was writing an answer, so I couldn't stop myself from using it as an argument.
Offline