#######################################################################
Luigi Auriemma
Application: Empire
http://www.wolfpackempire.com
http://sourceforge.net/projects/empserver
Versions: <= 4.3.2
Platforms: Windows, *nix, *BSD and more
Bug: crash caused by strncat misuse
Exploitation: remote, versus server
Date: 12 May 2006
Author: Luigi Auriemma
e-mail: [email protected]
web: aluigi.org
#######################################################################
1) Introduction
2) Bug
3) The Code
4) Fix
#######################################################################
Empire is a well known multiplayer Internet war game.
#######################################################################
The bug is a server's crash caused by the access to an invalid zone of
the memory.
That happens due to the misuse of strncat in the client_cmd function
for adding the text strings sent by the attacker to the player->client
buffer.
>From lib/player/login.c:
static int
client_cmd(void)
{
int i;
if (!player->argp[1])
return RET_SYN;
for (i = 1; player->argp[i]; ++i) {
if (i > 1)
strncat(player->client, " ", sizeof(player->client) - 1);
strncat(player->client, player->argp[i], sizeof(player->client) - 1);
}
player->client[sizeof(player->client) - 1] = '\0';
pr_id(player, C_CMDOK, "talking to %s\n", player->client);
return RET_OK;
}
#######################################################################
http://aluigi.org/poc/empiredos.zip
#######################################################################
Current CVS has been patched.
Anyway the following is the diff created by the developers:
— login.c.~1.37.~ 2006-04-26 20:50:40.000000000 +0200
+++ login.c 2006-05-09 08:36:04.000000000 +0200
@@ -133,17 +133,23 @@ player_login(void *ud)
static int
client_cmd(void)
{
int i, sz;
char *p, *end;
if (!player->argp[1])
return RET_SYN;
p = player->client;
end = player->client + sizeof(player->client) - 1;
for (i = 1; player->argp[i]; ++i) {
if (i > 1)
strncat(player->client, " ", sizeof(player->client) - 1);
strncat(player->client, player->argp[i], sizeof(player->client) - 1);
*p++ = ' ';
sz = strlen(player->argp[i]);
sz = MIN(sz, end - p);
memcpy(p, player->argp[i], sz);
p += sz;
}#######################################################################
Luigi Auriemma
http://aluigi.org
http://mirror.aluigi.org
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/