-1

I want to write shellcode for kernel mode on 32-bit Linux that will do this:

commit_creds (prepare_kernel_cred(0));

So I create a file with:

xor eax, eax
call 0x1234567
call 0x1234568
ret

Where 0x1234567 is the address of prepare_kernel_cred and 0x1234568 is the address of commit_creds, both found from /proc/kallsyms.

I assemble it with nasm -f elf and objdump -d it to get the machine code.

I get something like:

31 c0               which is xor eax, eax
e8 7c 67 06 c1      which is call prepare_kernel_cred
e8 7c 65 06 c1      which is call commit_creds
c3                  which is ret

This doesn't work. However, using e8 79 instead of e8 7c and e8 74 instead of the second e8 7c, works. I don't remember where I got this second machine code from (I had it in a different file), but I'm very curious why this would work and not simply assembling it like that would work.

What type of CALL is this? Why doesn't it work to simply assemble the code as it is shown above? My toy exploit works fine against my artificial kernel bug if I use the e8 79 and e8 74 for the CALLs, but fails when I use the assembled machine code from nasm/objdump.

osgx
  • 90,338
  • 53
  • 357
  • 513
ioctlvoid
  • 311
  • 1
  • 3
  • 7

2 Answers2

1

The CALL variants beginning with E8h are near calls to an address specified by a displacement relative to the current instruction. This explains why the values need to be different for different instructions. I'm at a loss for how you got nasm to emit that code, though. Are you sure this isn't homework?

Andy Ross
  • 11,699
  • 1
  • 34
  • 31
  • Thanks. No, this is not homework. I'm just trying to make my own toy exploit work against my own kernel (null pointer dereferencing). If I assemble "call 0xc1066480" and "call 0xc1066380" I get e8 7c on both of them. (nasm -f elf, objdump -d on the .o file). – ioctlvoid Feb 19 '13 at 15:51
0

I found that I had used the following command to compile this before:

gcc -m32 -Ttext=0 -nostdlib

This gives me the same result as I had from before. I also get a warning that it defaults to starting from 0x0.

However why doesn't nasm reproduce this? I checked with objdump and the starting address seems to be 0x0 in both files.

ioctlvoid
  • 311
  • 1
  • 3
  • 7