PLanET ABhisEK
May 2006 >
SuMoTuWeThFrSa
  1 2 3 4 5 6
7 8 910111213
14151617181920
21222324252627
28293031   

Wed, 31 May 2006 19:06:00 IST

GAMES WITH LINUX MEMORY PERMISSIONS

Today while testing my shellcode, I suddenly had a weird idea. I used to think the mainline 2.6 branch of linux kernels from kernel.org is pretty secure these days and application level exploitation over these latest linux kernels are extinct concept because of the secure by default memory permissions.

Well, lets get going in my attempt to dig deeper into linux memory management and paging implementations.
Currently I am running Gentoo with 2.6.14 on my laptop. The memory mappings as available from /proc looks something like this:
note: I am using the gentoo-sources kernel from portage without any hack or external patches like GrSecurity/PaX or SELinux/ExecShield.

neo@compaq ~ $ cat /proc/self/maps
08048000-0804c000 r-xp 00000000 03:06 38646      /bin/cat
0804c000-0804d000 rw-p 00003000 03:06 38646      /bin/cat
0804d000-0806e000 rw-p 0804d000 00:00 0          [heap]
b7eb8000-b7fc1000 r-xp 00000000 03:06 87733      /lib/libc-2.3.5.so
b7fc1000-b7fc2000 ---p 00109000 03:06 87733      /lib/libc-2.3.5.so
b7fc2000-b7fc3000 r--p 00109000 03:06 87733      /lib/libc-2.3.5.so
b7fc3000-b7fc6000 rw-p 0010a000 03:06 87733      /lib/libc-2.3.5.so
b7fc6000-b7fc9000 rw-p b7fc6000 00:00 0
b7fe7000-b7ffc000 r-xp 00000000 03:06 87744      /lib/ld-2.3.5.so
b7ffc000-b7ffd000 r--p 00014000 03:06 87744      /lib/ld-2.3.5.so
b7ffd000-b7ffe000 rw-p 00015000 03:06 87744      /lib/ld-2.3.5.so
bf8e7000-bf8fc000 rw-p bf8e7000 00:00 0          [stack]
ffffe000-fffff000 ---p 00000000 00:00 0          [vdso]
neo@compaq ~ $

Looking at the memory mappings, its quite apparent that there doesnt exists any segment with both write ("w") _AND_ execute ("x") permission. I have been looking into such memory mappings for quite some time now, assuring my paranoid mind that I am quite secure, atleast from arbitrary code injection/execution level exploitation techniques.

Due to some reason and unable to find out the technical reasonings for some unexpected behaviour, I started playing with it.
The following code can be used to test the default memory permissions implemented by my kernel.

#include <stdio.h>
/*
BITS 32

GLOBAL _start

_start:

   call getString
   db "Hello World",0x0a,0x00

getString:
   pop ecx
   mov edx, 12
   mov ebx, 1
   mov eax, 4
   int 0x80

   xor eax,eax
   xor ebx, ebx
   inc eax
   int 0x80
*/
static char code[] =
"\xe8\x0d\x00\x00\x00\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64"
"\x0a\x00\x59\xba\x0c\x00\x00\x00\xbb\x01\x00\x00\x00\xb8\x04\x00"
"\x00\x00\xcd\x80\x31\xc0\x31\xdb\x40\xcd\x80";

int main(int argc, char **argv)
{
  int (*funct)();
  char temp;

  funct = (int (*)()) code;

  printf("code is at 0x%x\n",&code);
  printf("sizeof code is 0x%x bytes\n",sizeof(code));

  printf("Checking read/write on code's segment\n");
  temp = code[10];   /* Read works */
  code[10] = 0xff;   /* Write works */
  code[10] = temp;   /* Restore the byte */
  printf("All works\n");

  printf("Executing code\n\n");
  (int)(*funct)();
}

To my surprise (yeah may be I was wrong) I have results like this.

neo@compaq ~/CVSROOT/ $ gcc helloworld.c
neo@compaq ~/CVSROOT/ $ ./a.out
code is at 0x80496c0
sizeof code is 0x2c bytes
Checking read/write on code's segment
All works
Executing code

Hello World
neo@compaq ~/CVSROOT/ $

Yes code was actually rwx (Readable,Writable, Executable).
Looking into address of ``code'' (0x080496c0), it appears to be in the .data segment which is supposed to be non-executable as per /proc/{pid}/maps.

0x080496a0->0x080496ec at 0x000006a0: .data ALLOC LOAD DATA HAS_CONTENTS

So whats the meaning of this?
a) /proc/self/maps gives incorrect results?
b) I am doing something wrong?
c) Explanation is already available, just that I need to look for it?

I'll dig more into it and post some results if I find out something. In the mean time if somebody accidentaly lands up in this thing and have something to say, please drop me a mail at abhisek[dot]datta[at]gmail[dot]com

And oh, if anybody is interested in testing the kernel's memory permissions/protections then I'll suggest take a look at:

http://www.adamantix.org/paxtest/

Some links for Linux kernel security stuff

http://www.grsecurity.net 
http://pax.grsecurity.net 
http://www.nsa.gov/selinux/index.cfm
http://www.redhat.com/f/pdf/rhel/WHP0006US_Execshield.pdf

posted at: 19:06 | path: / | permanent link to this entry

Made with PyBlosxom