3
\$\begingroup\$

What exploits does my system allow for that I can't solve or did not account for?

I'm researching on a design for multiplayer RPG that can safely allow players to have their character files and play solo offline and reliably check they haven't cheated using fully deterministic game engine, action history (replays) and cryptographic signatures. I do this in attempt to deliver much wanted from players true ownership of their characters, lag free gameplay and cheat-free economy at the same time.

So far I have established the following facts and processes:

  1. FACT: The game is fully deterministic with life-long RNG seeds embedded in characters upong creation.

  2. FACT: Game records and replays user actions (not keystrokes and mouse clicks, but rather "attack enemy ID-42". Game client CD-KEY hash is embedded in each action sequence between saves

  3. EVALUATE AND SIGN: After offline solo play, character file and action history are uploaded to server, where action history is replayed headlessly and end-state is compared with candidate-end-state. If they match, the end-state is signed with X509 private key and signature is downloaded and appended to the character file. Action history is required for play sessions since last signed state.

    1. FACT: Signing requires account authentication to prove owning the character. Characters are tied to accounts online, but can be shared between players for offline play.
    2. FACT: Hashed CD-KEY of the client is embedded in the character, so the server knows on which game client the play session happened
  4. VERIFYING: When attempting multiplayer, either LAN or developer-hosted, character signatures are verified. If latest state is not signed - go to step 3. Only signed characters can participate in official servers.

    1. If a character loses action history for whatever reason they can still play solo offline, but not on official servers.
    2. Illegal actions like use a wrong ID or attack an enemy outside your reach invalidate the action history and the character is not signed
    3. Server tracks how long (in game ticks) a CD-Key has played and verify if it's possible to have played that much since the CD-Key is issued. You could not have played 3000 hours on a CD-Key that has been issued 1000 hours ago. With multiple CD-Keys, their play-time-budget is verified for overlapping play-time with other characters that used it. E.g. if a CD-Key has been issued 1000 hours ago, someone has played for 700 hours using it and the candidate applies for a 500 hours-long play time then the candidate is rejected (500+700 = 1200 > 1000).
  5. FACT: Trade is only allowed online (no LAN) to cut off many hard-to-solve cheat scenarios.

Assume common sense security like logging, network setup and server configuration has been planned for.

Issues I have accounted for

Reverse-engineering

Most concerning issue I see with offline solo play is that hackers will completely reverse-engineer the file format and/or the game and forge game-valid godly characters, ruining the economy and the community. Solution: This takes very long time and concentrated effort from experienced professionals to do.

  1. Small patches and updates can force you to constantly do RE work and if consistent enough, RE clients may never be up-to-date.
  2. If the incentive doesn't come (game is not popular enough, gameplay offers what you would cheat for anyway, cheats are hard to monetize) hackers won't spend the effort.
  3. Anyway, assuming they could produce legit characters the damage to the economy (for which I care the most) would be minimal because CD-Keys play-time budget (fact 4.3) would limit how much hours the character could have played. Furthermore, since the game is deterministic, the character will only have whatever items the RNG says (and they cared to stash). If a character is destined by RNG to get lucky at kill number 294 942 953 291 it will happen exactly then and that may be way past the timeline that has been forged. Even using oldest possible CD-Keys won't help since they would have play-hours logged already. This also discourages exploring alternate decision making to hit the best RNG outcome.

Impersonation and theft

Cheater may acquire with or without permission somebody elses character file, then transfer his belongings or attempt to impersonate him online. Either of these won't work, because you need to authenticate online.

Branching

Cheater may copy character file to duplicate the items, but we established trade can only happen online for that reason. Trading on LAN is possible but too problematic for this very reason and is thus unavailable

Character file size

A character state would only be few kilobytes without action history or states from the past. However, I have estimated a full year of non-stop playing - 96 hours a week with APM of 200 and action being 17 bytes (which is pretty generous) the file would be ~1GB which can be problematic for storage on the server. While charactrs only need their last signed state (few KB) and action history since (~180 KB/h), the server needs it all for forensics and analysis. E.g. server may want to check players for a known bot signature.

Botting (unsolved!)

Storing replay data can be very helpful for identifying botting. However, botters have the same edge against the developer that the developer has against reverse-engineers - can consistently change their behavior footprint and make very hard to detect. The best ones would only read game memory or even screen colors to identify game state and simulate player input at the OS level which is honestly untraceable.

\$\endgroup\$
3
  • \$\begingroup\$ How would you handle balancing patches where the client is on a version behind? Let's say you reduce the drop rate of a rare Ressource by 10x but if the client does not need to have the newest version (since they can play offline), they could farm in it on mass. \$\endgroup\$
    – Zibelas
    Oct 13 '21 at 20:56
  • \$\begingroup\$ @Zibelas good point. I can't. Possible solution off the top of my head is to require the updates with a tolerance of let's say a week so you can't get a ahead more than that, even if you're playing non stop. So you won't be offline all the time. Those are the kinds of problems I could not have come up with \$\endgroup\$
    – No Thanks
    Oct 13 '21 at 21:39
  • \$\begingroup\$ I could have 100 VMs run through the same dungeon with the same character making slightly different choices, then cherry pick the best to submit for validation each day. Even if the RNG has a fixed/known seed, that's going to allow me to explore lots of different eventualities and only ever accept the best. \$\endgroup\$
    – Basic
    Oct 14 '21 at 10:10
5
\$\begingroup\$

A useful mantra to bear in mind is "the client is in the hands of the enemy".

Any capability that you build into the client that can run offline is one that you have delivered in a gift-wrapped package to anyone who wishes to hack the game.

If the client is capable of producing a valid play history that passes muster for server inspection, then a hacked client is also capable of producing a valid play history that similarly passes muster. And it can do it using simulated gameplay inputs and a forged clock, rather than real human input spanning real time — stepping your game logic as fast as the CPU can go.

(By a forged clock, I don't mean that they can run ahead of real time in the long run, but they can compress a full day's worth of play for their daily server check-in into some minutes of execution time, allowing them to farm the game without devoting a machine to a single account 24/7)

They might not even need to reverse engineer or understand your code deeply to do this. They could just call into the very same functions that run your game loop and execute them as black boxes with false input. Patching the game will not slow them down for long, because they don't need to reverse engineer the whole patch, just update their hooks to call / inject false input into the latest client you gifted them. If you support the old version for a few days' overlap to accommodate honest players who were playing offline around the transition, then by the time the new version becomes mandatory the hackers will likely have had plenty of time to adapt.

Obfuscating your input/time handling in new ways for each patch to try to fend this off is likely to be a losing game — barely a speedbump to a determined hacker, while creating risks of introducing new bugs for the majority of honest players.

The hackers are limited by how fast their total character progress can accrue on any one account/key, relative to server time between validations, but that's still a high bar compared to typical human play investment. If you've designed your game for the bulk of the audience to play 2-3 hours daily, simulated gameplay that uses all 24 hours in a day will see a character progress 8-12x faster than typical human efficiency.

You can add artificial limits, like mandating that more than 8 hours of play in a calendar day will be considered a bot, but that will catch some human players who just happen to play marathon sessions, while still allowing bots to progress 2-4x faster than typical humans for zero effort for their operator. There will be a market for players who would like to progress twice as fast without investing their own time/attention/skill.

Not to downplay what your proposed method achieves: restricting a hacker from unlimited / infinite progression rate per account down to a single-digit multiple of human efficiency is still significant and valuable. In one sense, a reduction from infinity to any finite value is an infinite win!

But it's not enough to stop cheating. Even progressing 20% faster than average — or being able to run multiple accounts in parallel without supervision — may be valuable enough to attract bot-users. If the incentive is there to progress characters faster than casual play, the system you have proposed will not stop a cheater from exploiting it. And the more enticing or prestigious you make the rewards in your game to please your honest players, the more you incentivize dishonest players to use bots to achieve those rewards at lower effort.

(You could try to artificially inflate the processing cost of each tick to reduce the time savings for folks compressing their play or farming multiple accounts by some degree, but this will mostly manifest as worse performance and battery life for your honest player majority, and higher server costs to do the validation, while not dissuading any hacker with a smart trick to to bypass it or enough compute resources to burn through it, so this too I would suggest is a losing game)

The best bang for your buck in this system is probably the recording and server-side analysis of play history. You could actually skip all the other clever signing and validation effort, and instead just run offline analysis of the history to find patterns and periodically mass-ban accounts that show unrealistic behaviour — according to a shifting definition of "unrealistic" that lives in your server-side analysis process, invisible to hackers. This denies a hacker the ability to get instant feedback from your server via its signature, validating whether their latest tweak has fooled it, making it much harder for them to isolate what telltale is giving them away. For more on this, see How to prevent automation-type cheating?.


As an aside, one other exploit is possible here due to the lifelong deterministic RNG seed per client. A hacker who reverse engineers your RNG code can copy the current RNG state and make many rolls on their copy, using it as an oracle about future random outcomes.

  • When a "bad" roll is fated to come up next, they can make their character take an action that uses up an RNG roll in a harmless way — like playing a randomized taunt or other bark. They can know when not to spend mana/stamina on an attack that's going to miss, and when to take a long shot attack that's fated to roll a critical.

  • They can know what boss move is coming up next, and react to it faster than a player who has to observe the animation/sounds for themselves.

  • When rolling a procedural dungeon instance, they can know in advance what challenges and rewards it will offer, and abort and re-start or churn the RNG on quick randomized actions until they get the optimum one for their objective, skipping any sub-par runs.

  • They can predict in advance when the "good" rolls are coming up on the horizon, so they can sequence their play so that these ideal rolls land exactly on important loot drop events, getting that epic item on their first try.

Used strategically, this can allow a hacker to progress faster than the basic time math above would suggest, despite the gameplay time validation that your server does, by emulating an exceptionally, improbably lucky player, who technically isn't breaking any gameplay rules.

You can make this some of these tricks harder / less beneficial by maintaining multiple RNG states for different purposes. Say one RNG state for "boss loot" that's not advanced by any other action in the game, limiting the rate at which the player can churn this RNG to the rate at which they can grind the fastest boss that uses it. Or you can use a biased randomizer that, say, has only one winning ticket in the hat per calendar day. But they still have perfect knowledge about what roll is coming up next, letting them strategically switch their play to get the optimal result from the hand that fate has dealt them - giving them a potential edge over a player who lacks this information to optimize their play pattern.

Being able to predict future attacks / hits / misses / criticals - and the exploitation of this knowledge for gameplay advantage - is unfortunately a necessary consequence of your deterministic model. But it's still a degree better than allowing players to forge a history where bad rolls never happen at all.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .