[10612] in bugtraq
Re: Solaris libc exploit
daemon@ATHENA.MIT.EDU (Craig Johnston)
Mon May 24 01:12:04 1999
Mime-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Message-Id: <Pine.GSO.3.96.990523125430.7015A-100000@jane.lfn.org>
Date: Sun, 23 May 1999 14:00:52 -0500
Reply-To: Craig Johnston <caj@LFN.ORG>
From: Craig Johnston <caj@LFN.ORG>
To: BUGTRAQ@NETSPACE.ORG
In-Reply-To: <Pine.LNX.4.10.9905221721240.28732-100000@colargol.tihlde.org>
On Sat, 22 May 1999, Oystein Viggen wrote:
> On Sat, 22 May 1999, UNYUN@ShadowPenguinSecurity wrote:
>
> > libc overflows when that handles LC_MESSAGES.
> > So, If you set the long string to LC_MESSAGES and call
> > /bin/sh, the core file is dumped.
> > This is serious problem.
>
> Didn't work on my Solaris2.6/sparc box.
> It just said "Illegal instruction" when using /bin/passwd and segfaulted
> when using /bin/su.
My guess is that this is architecture-dependent. It works on my sun4m
boxes and not the ultrasparcs. It looks like it could be made to work
with some tweaking if you can get a SIGILL. I'd assume the script
kiddies have one that works on your platform.
This is a really bad one. Here's my ugly temporary fix:
Make a directory, /subin, and move all setuid root binaries into it.
Remove the setuid bits. Compile the following c program and put it
in place of the old setuid root binaries, with the setuid bit set.
I spent a small amount of time on this, so it itself may be exploitable.
Use with caution.
--- cut here ---
#include <stdio.h>
#define MAX_ENV 255
#define HOLDING_PEN "/subin/"
#define BSIZE 1024
/*
quick and dirty wrapper to defeat overflowing of libraries with
environment variables
5/99, Craig Johnston, caj@lfn.org
this comes with no guarantees except "it seems to work here."
When is security going to become a priority at Sun?
*/
int main(int argc, char **argv, char **envp)
{
char *p, *q, buf[BSIZE];
int i;
while (*envp) { /* whack off long env variables */
for (p = *envp, i = 0; *p ; ++p, ++i)
if (i >= MAX_ENV) {
*p = '\0';
break;
}
++envp;
}
for (p = q = argv[0]; *p; ++p) /* get basename */
if (*p == '/')
q = p + 1;
snprintf(buf, BSIZE, "%s%s", HOLDING_PEN, q);
execve(buf, argv, envp);
printf("exec() failed, bailing!\n");
exit(1);
}
--- cut here ---
--
Craig Johnston
caj@lfn.org