Skip to content

Anti spoof cookie #245

@dktapps

Description

@dktapps

This has been a TODO for a while, but it's quite annoying to implement due to the context-dependent structure of the packets.

OpenConnectionReply1

In RakNet official, Client reads:

  • message ID
  • magic
  • server ID
  • serverHasSecurity, if true:
    • cookie
    • if client supports libcat security, server public key (!!!)
  • MTU size

In RakNet official, Server writes:

  • message ID
  • magic
  • server ID
  • serverHasSecurity, if true:
    • cookie
    • server public key
  • MTU size

Problems:

  • Server must guess whether the client will read a key or not, as there is no way for it to know whether the client supports libcat security
  • Client does not know whether to read a key - it has no way to know whether the server supports libcat security

Likely outcomes:

Server libcat Server security (cookie) Client libcat Server writes Client reads
nothing nothing
Yes nothing nothing
Yes cookie only cookie only
Yes nothing nothing
Yes Yes key & cookie cookie only
Yes Yes nothing nothing
Yes Yes cookie only key & cookie
Yes Yes Yes key & cookie key & cookie

What a server can do:

  • Hidden field during encoding whether we expect client to support encryption (like with the system address count)

What a client can do:

  • Guess whether to read a key by the size of the packet?

Worth noting that we don't currently read cookie or key when reading this packet, irrespective of the security flag

Expected structure

  • No security: hasSecurity=0
  • Cookie security: hasSecurity=1 & cookie
  • Encryption security: hasSecurity=1 & cookie & public key

OpenConnectionRequest2

Server reads:

  • message ID
  • magic
  • if server supports libcat security (no field, client is instructed by OpenConnectionReply1)
    • cookie
    • hasChallenge, if true
      • handshake challenge
  • bind address
  • MTU
  • client ID

Client writes:

  • message ID
  • magic
  • if server requires security (no field, depends on OpenConnectionReply1)
    • cookie
    • hasChallenge, if true && if client supports libcat security (no field) (!!!):
      • handshake challenge
  • bind address
  • MTU
  • client ID

Problems:

  • Presence of cookie & challenge depends on OCReply1 setting serverHasSecurity=true
Server libcat Server security (prior packet) Client libcat Server reads Client writes
nothing nothing
Yes nothing nothing
Yes nothing (bug in wacknet) cookie & hasChallenge=false
Yes nothing nothing
Yes Yes cookie & challenge cookie only & hasChallenge=false
Yes Yes nothing nothing
Yes Yes nothing cookie & challenge (error)
Yes Yes Yes cookie & challenge cookie & challenge

What a client can do:

  • If OCReply1 enabled security but didn't provide a key (judge by packet size), send cookie & hasChallenge(0). Custom RakNet implementations should read this. Vanilla RakNet won't read it without libcat, but vanilla RakNet won't enable security or send a cookie unless libcat is supported anyway. A bit dodgy but it should work.

What a server can do:

  • Context variable to decide whether to attempt reading cookie & challenge, as cookie, hasChallenge & challenge will not be present otherwise. This will depend whether OCReply1 set hasSecurity=true. Probably easiest to just set it to true for all clients so that IP specific context isn't needed.

Checking packet size during decode is probably not viable, since this packet writes the system address, so it may be hard to determine the correct size range.

Expected structure

  • No security requested (depends on OCReply1): nothing
  • Cookie security: cookie & hasChallenge=0
  • Encryption security: cookie & (hasChallenge=0 OR hasChallenge=1 & challengeBytes)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions