Bugtraq mailing list archives

Format String Bug in Posadis DNS Server


From: "nick" <kkr () dekode org>
Date: Wed, 27 Mar 2002 02:37:11 -0500

Date: Mar 27 02
Me: kkr (kkr () dekode org)
Software: Posadis DNS Server (http://sourceforge.net/projects/posadis/)
Ver: m5pre1
Bug: bad fmt string usage in log function, may lead to remote access
Word Life: the warez dude


Overview:

Posadis dns server is a small dns server without cache or resolving
functionality written in c++.
It is designed to be run under linux or windows.  The log_print function is
so badly written
it brings a tear to my eye.


Example of how NOT to write a logging function:
(from log.cpp)
---
void log_print(message_log_level log_level, char *logmsg, ...) {
        char buff[4096];
        long tsecs;
        struct tm *tstruct;
        va_list args;

        /* compile buffer */
        tsecs = time(NULL);
        tstruct = localtime(&tsecs);
        sprintf(buff, "%04d/%02d/%02d %02d:%02d|", tstruct->tm_year + 1900,
tstruct->tm_mon + 1, tstruct->tm_mday, tstruct->tm_hour, tstruct->tm_min);
        switch (log_level) {
                case LOG_LEVEL_INFO:    strcat(buff, "INFO: "); break;
                case LOG_LEVEL_WARNING: strcat(buff, "WARNING: "); break;
                case LOG_LEVEL_ERROR:   strcat(buff, "ERROR: "); break;
                case LOG_LEVEL_PANIC:   strcat(buff, "PANIC: "); break;
        }

        va_start(args, logmsg);
        vsprintf(&buff[strlen(buff)], logmsg, args);
        va_end(args);
        strcat(buff, "\n");

        /* and print it to various targets */
        if (!no_stdout_log) printf(buff);       <-- heh
        if (logfile) fprintf(logfile, buff);    <-- heh
#ifdef _WIN32
        w32dlg_add_log_item(buff);
#endif
#ifdef HAVE_SYSLOG_H
        syslog(log_level, "%s", strchr(buff, '|') + 1);
#endif
}

---

If you direct your attention to the two lines of code with the arrows,
you'll notice the obvious
format string violation.

Throughout the code, its obvious that the authors put great effort into
making sure there were
no format string violations in the actual calling of log_print()...no user
supplied data passed
as the format string.  Unfortunately the user supplied data only needs to be
passed normally to
take advantage.

Here are a few examples of some quick local tests.


[kkr@eightball src]$ ./posadis %s%s%s%s
Segmentation fault (core dumped)
[kkr@eightball src]$ ./posadis %08x
2002/03/27 01:53|PANIC: Unrecognized option: 4016814c


--begin posadis.conf
%08x
--end posadis.conf

[kkr@eightball src]$ ./posadis
2002/03/27 01:59|ERROR: posadis.conf:1: Unknown command 4016814c!
2002/03/27 01:59|PANIC: Loading posadis.conf failed!


It seems there are a few possible methods of remote exploitation, but i'll
leave that for others
to figure out for themselves.


Current thread: