2. The magic of the Elf

 

Any sufficiently advanced technology is indistinguishable from magic.

 Arthur C. Clarke

For the first example I'll present the simplest piece of code that still gives sufficient feedback. Our aim is to implant it into /bin/sh. On practically every recent installation of Linux/i386 the following code will emit three magic letters instead of just dumping core.

Source: pre/i386-redhat7.3-linux/magic_elf/magic_elf.c
#include <unistd.h>
int main() { write(1, (void*)0x8048001, 3); return 0; }

Command: pre/i386-redhat7.3-linux/magic_elf/cc.sh
#!/bin/bash
/usr/bin/gcc -Wall -O1 -I . -I out/i386-redhat7.3-linux -D NDEBUG \
	pre/i386-redhat7.3-linux/magic_elf/magic_elf.c \
	-o tmp/i386-redhat7.3-linux/magic_elf/magic_elf \
&& tmp/i386-redhat7.3-linux/magic_elf/magic_elf

Output: out/i386-redhat7.3-linux/magic_elf/magic_elf
ELF

2.1. How it works

2.2. Strings and dumps

What would you do if you knew nothing about ELF and just asked yourself how that example works? How can you go sure that the executable file really contains those three letters?

2.2.4. xxd

xxd is part of vim. [2] And though that can't be called installation core it comes pretty close on Linux distributions.

Source: pre/i386-redhat7.3-linux/magic_elf/xxd.sh
#!/bin/bash
/usr/bin/xxd -l 80 \
< tmp/i386-redhat7.3-linux/magic_elf/magic_elf

Output: out/i386-redhat7.3-linux/magic_elf/xxd
0000000: 7f45 4c46 0101 0100 0000 0000 0000 0000  .ELF............
0000010: 0200 0300 0100 0000 0083 0408 3400 0000  ............4...
0000020: 6029 0000 0000 0000 3400 2000 0600 2800  `)......4. ...(.
0000030: 1d00 1a00 0600 0000 3400 0000 3480 0408  ........4...4...
0000040: 3480 0408 c000 0000 c000 0000 0500 0000  4...À...À.......

Anyway, at this point we can guess that file offset 1 and 0x8048000 + 1 are not coincidental. A test program might help.

2.3. The address of main

Note that the output of %p is not standardized. Some platforms print a leading 0x, some don't. Even %#p does not guarantee a leading 0x. Anyway, output looks good. The byte at address 0x8048000 + 0 is equal to that at file offset 0. And 0x8048400 is a plausible address of function main.

2.4. Other roads to ELF

The classic tool for conversion from hex to decimal is bc, a front end to dc. Note that command n is a rather recent GNU extension and not available on bc-1.04-39 shipped with SuSE Linux 6.0.

Notes

[1]

http://www.tuxedo.org/~esr/jargon/html/entry/RTFM.html

[2]

http://www.vim.org