[Full-Disclosure] [ESA-1] Denial of Service in thy

Type securityvulns
Reporter Securityvulns
Modified 2004-06-15T00:00:00


Ebat Advisory #01

NULL Pointer dereference Denial of Service in Thy httpd

date: 15/06/04 author: jethro - securirynerds - docisland - ebat


Thy is a lightweight and fast http daemon. A denial of service condition can occur when the daemon is sent a crafted request. A manual restart is needed in order to recover the denial of service.

homepage: http://bonehunter.rulez.org/Thy.phtml

Vulnerable versions:

All versions prior to 0.9.2 are vulnerable.


The Dos condition is fairly easy to achieve, but no threat of code execution upon exploitation of this vulnerability has been raised.


Upgrade to thy 0.9.2 or apply this fix:

--- src/session.c +++ src/session.c @@ -127,7 +127,7 @@ free (session->request->host); session->request->host = bhc_strdup (&tmp1[7]); free (session->request->url); - session->request->url = NULL; + session->request->url = bhc_strdup ("/"); } }

Technical Details:

The vulnerability is triggered in session.c, through session_update():

(from src/session.c)

void session_update (session_t session) { session->request = (request_t )bhc_malloc (sizeof (request_t));

session->result = http_request_parse (session->request, session->body.buffer); if (session->request->url) { asprintf (&session->absuri, "http%s://%s%s", (session->ssl) ? "s" : "", session->request->host, session->request->url); _session_parse_absoluteuri (session); urldecode (session->request->url); <--- cgi_setup (session); <--- session->request->file = fabs_urlmap (session->request->url, session->request->host, session->absuri); [...]

having a look at _session_parse_absoluteuri, we can spot the problem:

(from src/session.c) static void _session_parse_absoluteuri (session_t session) { char tmp1, *tmp2;

if (!session->request->url) return;

if (strncmp ("http://", session->request->url, 7)) return;

tmp1 = strstr (session->request->url, "http://"); tmp2 = bhc_strdup (strchr (&tmp1[7], '/')); <---- if (tmp2) { size_t l = strlen (tmp1); tmp1[l - strlen (tmp2)] = 0; free (session->request->host); session->request->host = bhc_strdup (&tmp1[7]); free (session->request->url); session->request->url = tmp2; } else { free (session->request->host); session->request->host = bhc_strdup (&tmp1[7]); free (session->request->url); session->request->url = NULL; } }

thy does expect a trailing / when parsing an absolute uri, and if no one is set, tmp2 will feed session->request->url with a NULL value. Later on, in urldecode

(from src/misc.c) / Decode URL in-place. / void urldecode (char url) { char *p = url;

while (p) <---- { if (p == '%') { url = _misc_hextochar ((int)(p+1), (int)(p+2)); p += 2; } else url = *p;


*url = '\0'; }

if url is undefined, then p won't be either, so while (p) will cause thy to segv.

Disclosure Timeline:

14/06 - 18h - found the vuln in the RER (train for the suburbs near paris) while trying some fancy tool I just wrote. 14/06 - 19h - went on #debian so as to find some clues about reporting incidents to the debian project 14/06 - 19h30 - dropped an email to security officer team @ debian .org 12/06 - 19h35 - got an answer by mdz, redirecting me to debian maintainer and upstream author 14/06 - 20h - starting idling on #thy @ oftc.net, waiting for algernon. 15/06 - 00h - finaly cought up with algernon, told him about the vuln, and stuff. 15/06 - 01h - after a few more investigation, writing of this advisory.

Thanks to algernon for his quickness.

About Ebat:

E-bat is a non profit organisation which aims at helping clueless amongst us feeling less stupid. Thanks to oci@, ski@, tfo@, lbe@, and others. We have no official website to provide you with anything, but who cares. We'll keep the arm in the concrete!