Cheaters/exploiters - Need some help

Options
Hello. I am developing an anti-cheat system for a Unity3D game which is currently using this networking plugin.
Everything I've found is already taken care of, however, there are two really important issues that I can't figure out:

1.
Players have found a way to become un-kickable via PhotonNetwork.CloseConnection(). When passing their PhotonPlayer reference to that method as the master client, nothing happens. I happened to acquire the .dll file which is viewable through most decompilers, however I can't find all that's been changed. The only noticeable change was they redefined the PhotonNetwork class as internal rather than public & static, but I don't see how that could affect CloseConnection while leaving all other functionality intact. I am unfamiliar with the way Photon uses OpRaiseEvent with these byte eventCodes sent to specific players, so I can't tell where the code to receive these event codes is, if it even exists.

2.
Removing the master client if statement in PhotonNetwork.DestroyPlayerObjects() lets anyone destroy anyone's objects. With methods like RPCs with PhotonMessageInfo, and events that have parameters to see what was affected, you can detect exploits. However I don't see anything that I can use to determine who destroyed all of my objects, or even to just determine that my objects have been destroyed (by DestroyPlayerObjects specifically, not OnDestroy, but without being able to determine who did it you can't kick them from the game so they'll continue). It's a pretty big issue as people are randomly having their players disappear leaving them in an unplayable state.

I would love to hear some suggestions about tackling these issues and I am more than willing to share the un-kickable .dll with the plugin developers if they want to check it out, and share what I know about the game's workings. I'm not going to post it now for everyone, but if anyone wants to check it out just ask.

Comments

  • Tobias
    Options
    The kick code is in NetworkingPeer usually. You should be able to find it in the source.
    We think about adding a server-side kick but that could be abused, too.

    DestroyPlayerObjects can be abused like you said. If you wanted to find out who sent this, you would have to modify OnEvent in NetworkingPeer (again). The events always contain the sender, so this piece of information could not be tampered with. Check the "originatingPlayer".

    As you develop an anti-cheat tool, do you have ideas what could help? If we can turn it into feature requests, we could improve things together.
    Maybe we discuss this by mail: developer@exitgames.com
  • Hmm, yeah looking into that I see how both work and how they prevented it, I'll take some time to see if I can figure out a workaround. Adding code to check the sender for DestroyPlayerObjects makes sense. At the moment, most abusive things/exploits in the game can be detected with PhotonMessageInfo and some events, these two issues were the only ones that made me unable to say the anti-cheat system will prevent most malicious mods. If I encounter anything else, get any ideas or need to discuss something I'll send an email instead of posting here.
  • Tobias
    Options
    The only solution I can think of would be a kick system that involves more than one client. A vote if you will. We would send a kick request and if more than half of the players "agree", the target player would be disconnected.

    As far as I can see this would prevent a single hacked client from kicking everyone and the server-side disconnect would make sure you can't keep the client connected despite the "please leave" event coming.

    What do you think?
  • That sounds pretty good to me. At first I thought it wouldn't be useful for anti-cheat as half of the players would have to agree if a cheat was detected by one client, but I believe that paired with the MC-only CloseConnection event would fix the problem. Having their connection potentially cut off could stop them from bothering to ignore the event, if not they can still be kicked.

    In my game's scenario it could work to have an RPC to agree with a kick request only if the RPC was sent by the master client (Depending on how the agreeing works), otherwise I'm not sure how auto-kicking banned player names would be possible with needing votes. Master client stealing has been prevented so I don't see any issues with that, but it'd have to be put to the test like the rest of the stuff. Either way, I think that sounds like a good solution, as long as players are unable to fake 'agrees' or 'disagrees' to that request.
  • Tobias
    Options
    The agree/disagree would be done per connection ("peer" in server), so you can't fake it with a single client. You would need to get multiple hacked clients in a room.
    I have to discuss this feature with my server colleagues and see if I can get them to integrate it soon. At the moment, I can't promise any date.
    I guess you'd want it "now" but what would be an OK timeframe from your side?
  • Alright, group vote-kick/agree abuse like that is not a problem, we already have a vote-kick system via the chat and I have yet to hear of that being abused by a group (other than in rooms they create for themselves for role-playing/similar).

    Hmm. Within the next month (like ~30 days from today) or two would be great, but I can wait as long as it takes. More players may find/share the exploit so the sooner the better. Just make sure to reply here or email me. ;)
    Thanks for taking the time to discuss and work on getting around this though.
  • Tobias
    Options
    Thanks for letting me know your timing and being relaxed about it.
    We will try to squeeze this in and I will post here in a while.
  • Alright, cool!
  • Another thing that would be useful is to have access to the targets of an event you have received from someone. Like, if the RaiseEventOptions sent with it was set to ReceiverGroup.All versus the targetActors array with only one person's ID.

    People are sending the instantiate event to individual people, spamming it rather, which causes their client to slow to a halt in a second or two. I'm not really sure what to do about that otherwise.
  • Tobias
    Options
    We can't provide the info that easily but you could (!) include it in the event you're sending. If it's really that important to know. Just let the sender add it.
    Aside from this, your clients are the sources of all in-game events. If something looks spammy to you, you need to think up some way to limit things. Photon can't set a limit for such things, so you need to take care things don't break.
    If you use Instantiate in a spammy way, something is odd! Expecially for a card game. You only need to send "i used card X from my hand". Everything else (including positions!) can be derived from the fact that someone played a card. You don't have to network instantiate and sync it's position. It just has to move from hand to table (e.g.).
  • The thing is, it's a volunteer anti-cheat, separate from the core game and is an optional download so I have to figure out how to prevent things without everyone needing the code (meaning I can only check things this client receives, can't modify what everyone sends). I probably should have clarified that before but I realize now that idea I had wouldn't help much, and probably just increase the amount of data sent over the network for little purpose.

    Since I last posted I've worked on it a lot more, I decided to just create a tracking system that counts instantiations of certain object types from each player and kicks if they're spammy. It works pretty well.

    For the un-kickable player issue, my temporary workaround is to blacklist their IDs (sending the ID to blacklist to other players in the room, though only anti-cheat users receive it) and not accept any instantiations from them, I also set up an attribute to not execute specific RPCs from kicked players. Once they're blacklisted there's not much they can do, it's not perfect but it's better than nothing for now.

    At this point I can't really suggest anything more than that server side disconnect when players are kicked, due to my situation with making an anti-cheat client for this game. The developer of the core game does nothing to prevent viewing/modifying the game's assemblies, I'm sure if it were obfuscated or something the cheater problem wouldn't be nearly as bad. People pretty much have free reign to rewrite the entire game at the moment which makes it much easier to make these cheats.

    Not sure what you could respond to this with but I figured I'd just update the status of these problems.
  • Tobias
    Options
    Thanks for the update. It helps us know your situation and gives us an impression on what's needed.
    I can't promise to post here again when we have a solution, so just take a look at the change logs of upcoming releases.
    Thanks