Denial of service bugs in OpenTTD 0.4.7
#######################################################################
Luigi Auriemma
Application: OpenTTD
http://www.openttd.org
Versions: <= 0.4.7
Platforms: Windows, *nix, *BSD, Mac and others
Bugs: A] program termination through big error number
B] broadcast clients disconnection in multiplayer menu
Exploitation: A] remote, versus server and client (in-game)
B] remote, versus clients (broadcast)
Date: 23 Apr 2006
Author: Luigi Auriemma
e-mail: aluigi@xxxxxxxxxxxxx
web: http://aluigi.altervista.org
#######################################################################
1) Introduction
2) Bugs
3) The Code
4) Fix
#######################################################################
===============
1) Introduction
===============
OpenTTD is a widely played open source clone of the old Transport
Tycoon Deluxe game.
Supports LAN and Internet multiplayer.
#######################################################################
=======
2) Bugs
=======
-----------------------------------------------
A] program termination through big error number
-----------------------------------------------
Both client and server handle a type of command (PACKET_SERVER_ERROR
and PACKET_CLIENT_ERROR) for the visualization of some pre-built errors
in the console.
The problem happens when an attacker sends an invalid big error number
(8 bit) which forces the program to terminate spontaneously through the
usage of the error() function.
The bug is exploitable only in-game so the attacker must have access to
the server: his IP must not be banned, he must know the password if it
has been set and the server must not be full.
>From strings.c:
char *GetStringWithArgs(char *buffr, uint string, const int32 *argv)
{
uint index = GB(string, 0, 11);
uint tab = GB(string, 11, 5);
...
if (index >= _langtab_num[tab]) {
error(
"!String 0x%X is invalid. "
"Probably because an old version of the .lng file.\n",
string
);
}
return FormatString(buffr, GetStringPtr(GB(string, 0, 16)), argv,
GB(string, 24, 8));
}
------------------------------------------------------
B] broadcast clients disconnection in multiplayer menu
------------------------------------------------------
Clients are affected by an harmless bug when they handle UDP packets.
The first 2 bytes of each UDP packet are a 16 bit number which
specifies the size of the packet.
If this value in a received packet is invalid (for example too small)
the client returns immediately to the main menu.
This bug becomes problematic when a malicious server visible in the
master server list sends invalid replies to the queries sent from the
clients which want to play online and will be no longer able to do it
due to the returning to the main menu.
#######################################################################
===========
3) The Code
===========
http://aluigi.altervista.org/poc/openttdx.zip
#######################################################################
======
4) Fix
======
The current SVN and nightly builds (pre-compiled for many platforms)
have been fixed:
http://www.openttd.org/nightly.php
These new versions (major/equal than r4531) fix also a garbage problem
which causes the termination of the server on some machines when the
attacker uses a big nickname (major than NETWORK_CLIENT_NAME_LENGTH).
#######################################################################
---
Luigi Auriemma
http://aluigi.altervista.org