Socket unreacheable in the Lithtech engine (new protocol)

From: Luigi Auriemma (aluigi_at_autistici.org)
Date: 12/13/04

  • Next message: Jaroslaw Sajko: "[Full-Disclosure] Gadu-Gadu several vulnerabilities"
    Date: Mon, 13 Dec 2004 18:25:19 +0000
    To: bugtraq@securityfocus.com, bugs@securitytracker.com, news@securiteam.com, full-disclosure@lists.netsys.com, vuln@secunia.com
    
    

    #######################################################################

                                 Luigi Auriemma

    Application: Lithtech engine (new network protocol)
                  http://www.lithtech.com
    Games: Contract Jack <= 1.1
                  No one lives forever 2 <= 1.3
                  Tron 2.0 <= 1.042
                  ... others?
    Platforms: Windows and Mac
    Bug: socket unreacheable
    Exploitation: remote, versus server
    Date: 13 December 2004
    Author: Luigi Auriemma
                  e-mail: aluigi@autistici.org
                  web: http://aluigi.altervista.org

    #######################################################################

    1) Introduction
    2) Bug
    3) The Code
    4) Fix

    #######################################################################

    ===============
    1) Introduction
    ===============

    The Lithtech engine is a game engine used by many games.
    Some of the latest games released and based on this engine use a
    network protocol different than all the others (probably they use a new
    version of the engine but naturally I don't know all these details).

    Just these latest games (all developed by Monolith) are those affected
    by the bug I'm going to describe: Contract Jack (Nov 2003), No one
    lives forever 2 (Oct 2002) and Tron 2.0 (Aug 2003), but possibly others
    too.

    #######################################################################

    ======
    2) Bug
    ======

    The new network protocol used by the Lithtech engine is composed by a
    loop used to handle all the UDP packets received.

    A select() function with a time out of 30 seconds searchs for new data
    into the socket's queue. If data is received or the socket goes in
    time out, a recvfrom() is called and its return value is checked to
    know if has happened an error.
    If there is a socket error, the game calls WSAGetLastError() to catch
    the error code and returns reaching a main check that is made ever
    before the usual select() function.
    This so-called "main check" simply controls that the error returned by
    WSAGetLastError() (and stored in a specific variable) is "Operation
    would block" (10035, the only type of error accepted to continue the
    listening loop).

    If an attacker sends an UDP packet of zero bytes, recvfrom() returns
    this length and an instruction checks just if it is equal than zero. In
    this case the code flow returns to the "main check" that controls the
    error code (not set, so equal to zero) and since it is not 10035 exits
    from the loop that handles the socket's data.

    After that, the server will be no longer able to receive packets
    because the loop is completely dead.

    A similar problem happens if an attacker sends an UDP packet with a
    size major/equal than 8193 bytes (max data read by recvfrom()) and
    minor/equal than 12280 (otherwise select() doesn't catch it).
    The "main check" will fail as before because the error code will be
    different than 10035 (in fact it will be 10040, "Message too long").

    #######################################################################

    ===========
    3) The Code
    ===========

    http://aluigi.altervista.org/poc/lithsock.zip

    #######################################################################

    ======
    4) Fix
    ======

    No fix.
    Just some weeks ago I released an advisory about another bug in the
    Lithtech engine and ignored by the developers, so is useless to try to
    recontact them again.

    However I have found a work-around to avoid the problem and I have
    written an universal autopatcher that can fix both lithtech.exe (the
    server launched from the game) and server.dll (the dedicated server):

      http://aluigi.altervista.org/patches/lithsockfix.zip

    #######################################################################

    ---
    Luigi Auriemma
    http://aluigi.altervista.org


  • Next message: Jaroslaw Sajko: "[Full-Disclosure] Gadu-Gadu several vulnerabilities"

    Relevant Pages