EggRun

EggRun is a very small program to test shellcodes (aka eggs) I wrote for a chapter of Security Power Tools (at O'Reilly, someday between Feb and Jul 2007) It is best served as an interpreter using linux kernel's binfmt_misc feature. It gives you the ability to run raw shellcodes without needing to integrate them into C files, or whatever. Just run them. Additionnal features like firing up a gdb on crashpoints or on first instruction or echoing a C string to paste into an exploit definitely makes shellcode developping even more fun.

Downloading EggRun

Download Eggrun source.

Installing EggRun

Compile it and install it wherever you want. Then ask Linux kernel to run it for every file with the .egg extension with the following command

echo ':shellcode:E::egg::/path/to/eggrun:' > /proc/sys/fs/binfmt_misc/register

Using EggRun

First, find a shellcode and put it raw inside a file whose extension is .egg. Here is mine, an ultra-classic execve(/bin/sh) of 23 bytes.

$ hd binsh.egg
00000000  6a 0b 58 99 52 68 6e 2f  73 68 68 2f 2f 62 69 89  |j.X.Rhn/shh//bi.|
00000010  e3 52 53 89 e1 cd 80                              |.RS....|
00000017
Now let's make it executable

$ chmod +x binsh.egg
Here we go. Our shellcode is now runnable as a normal executable:

$ ./binsh.egg 
sh-3.00$ 
Actually, you can give it options :

$ ./binsh.egg -h
Usage: shcode.egg [-d[d]|-c|-s|-n]
 -d:    debug mode 1: launch gdb at first error
 -dd:   debug mode 2: stop gdb at first instruction
 -c,-x: dump hexa string in c mode or raw
 -n:    run 'ndisasm -u' on the shellcode

Debugging modes

Debug mode 1 will launch gdb only if an error occurs.

Without debug mode, working shellcode works, crashing shellcode crashes, possibly dumping a core.

$ ./binsh.egg 
sh-3.00$ exit        
$ ./crash.egg 
Segmentation fault (core dumped)
With debug mode 1, working shellcode works, crashing shellcode fires gdb at fault

$ ./binsh.egg -d
sh-3.00$ exit
$ ./crash.egg -d
Using host libthread_db library "/lib/tls/libthread_db.so.1".
Attaching to program: /home/pbi/work/prog/c/shcode_interp/eggrun, process 8765
Reading symbols from /lib/tls/libc.so.6...Reading symbols from /usr/lib/debug/lib/tls/libc-2.3.6.so...done.
done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...Reading symbols from /usr/lib/debug/lib/ld-2.3.6.so...done.
done.
Loaded symbols for /lib/ld-linux.so.2
0xb7f22ace in __waitpid_nocancel () from /lib/tls/libc.so.6
Continuing at 0xb7f22ace.

Program received signal SIGSEGV, Segmentation fault.
0xb7fe8040 in ?? ()
(gdb) x/i $eip
0xb7fe8040:     xor    %eax,0x49(%ecx)
(gdb) i reg ecx
ecx            0x104    260

Debug mode 2 will break shellcode at its entry point and fire up a gdb.

$ ./binsh.egg -dd
Using host libthread_db library "/lib/tls/libthread_db.so.1".
Attaching to program: /home/pbi/work/prog/c/shcode_interp/eggrun, process 8813
Reading symbols from /lib/tls/libc.so.6...Reading symbols from /usr/lib/debug/lib/tls/libc-2.3.6.so...done.
done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...Reading symbols from /usr/lib/debug/lib/ld-2.3.6.so...done.
done.
Loaded symbols for /lib/ld-linux.so.2
0xb7f22ace in __waitpid_nocancel () from /lib/tls/libc.so.6
Continuing at 0xb7f22ace.

Program received signal SIGSEGV, Segmentation fault.
0xb7fe8000 in ?? ()
(gdb) c
Continuing.
sh-3.00$ 
$ ./crash.egg -dd
Using host libthread_db library "/lib/tls/libthread_db.so.1".
Attaching to program: /home/pbi/work/prog/c/shcode_interp/eggrun, process 8836
Reading symbols from /lib/tls/libc.so.6...Reading symbols from /usr/lib/debug/lib/tls/libc-2.3.6.so...done.
done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...Reading symbols from /usr/lib/debug/lib/ld-2.3.6.so...done.
done.
Loaded symbols for /lib/ld-linux.so.2
0xb7f22ace in __waitpid_nocancel () from /lib/tls/libc.so.6
Continuing at 0xb7f22ace.

Program received signal SIGSEGV, Segmentation fault.
0xb7fe8000 in ?? ()
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0xb7fe8040 in ?? ()

Miscellaneous stuff

You can output the shellcode in many shapes. This is a bit out of scope for an interpreter, but so handy.
$ ./binsh.egg -c
"\x6a\x0b\x58\x99\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89"
"\xe3\x52\x53\x89\xe1\xcd\x80";
$ ./binsh.egg -x
\x6a\x0b\x58\x99\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\xcd\x80
$ ./binsh.egg -n
00000000  6A0B              push byte +0xb
00000002  58                pop eax
00000003  99                cdq
00000004  52                push edx
00000005  686E2F7368        push dword 0x68732f6e
0000000A  682F2F6269        push dword 0x69622f2f
0000000F  89E3              mov ebx,esp
00000011  52                push edx
00000012  53                push ebx
00000013  89E1              mov ecx,esp
00000015  CD80              int 0x80

Known bugs

Terminal mess up. gdb hanging.