加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

即使在unsetenv(“LD_PRELOAD”)之后,LD_PRELOAD也会影响新的孩

发布时间:2020-12-15 19:02:41 所属栏目:安全 来源:网络整理
导读:我的代码如下:preload.c,具有以下内容: #include stdio.h#include stdlib.hint __attribute__((constructor)) main_init(void){ printf("Unsetting LD_PRELOAD: %xn",unsetenv("LD_PRELOAD")); FILE *fp = popen("ls","r"); pclose(fp);} 然后在shell中(
我的代码如下:preload.c,具有以下内容:
#include <stdio.h>
#include <stdlib.h>

int  __attribute__((constructor))  main_init(void)
{
    printf("Unsetting LD_PRELOAD: %xn",unsetenv("LD_PRELOAD"));
    FILE *fp = popen("ls","r");
    pclose(fp);
}

然后在shell中(小心做第二个命令!!):

gcc preload.c -shared -Wl,-soname,mylib -o mylib.so -fPIC
    LD_PRELOAD=./mylib.so bash

!小心使用最后一个命令,它会产生无限循环的分叉“sh -c ls”.用^ C后2秒钟停止它(或者更好^ Z然后看ps).

更多信息

>这个问题在某种程度上与bash有关;或者作为用户运行的命令,或者作为popen执行的bash.
>其他关键因素:1)从预加载的库中执行popen,2)可能需要在库的初始化部分中执行popen.
>如果您使用:

LD_DEBUG=all LD_DEBUG_OUTPUT=/tmp/ld-debug LD_PRELOAD=./mylib.so bash

而不是最后一个命令,您将获得许多ld-debug文件,名为/tmp/ld-debug.*.每个分叉进程一个.在所有这些文件中,您将看到首先在mylib中搜索符号.即使LD_PRELOAD已从环境中删除.

编辑:所以问题/问题实际上是:如果使用bash中预加载的main_init()可靠地取消设置LD_PRELOAD.

原因是你在popen之后调用的execve从(可能)获取环境

extern char **environ;

这是一个指向您的环境的全局状态变量. unsetenv()通常会修改您的环境,因此会影响** environ的内容.

如果bash试图对环境做一些特别的事情(好吧……它会成为一个shell吗?)那么你可能会遇到麻烦.

显然,bash甚至在main_init()之前就会重载unsetenv().将示例代码更改为:

extern char**environ;

int  __attribute__((constructor))  main_init(void)
{
int i;
printf("Unsetting LD_PRELOAD: %xn",unsetenv("LD_PRELOAD"));
printf("LD_PRELOAD: "%s"n",getenv("LD_PRELOAD"));
printf("Environ: %lxn",environ);
printf("unsetenv: %lxn",unsetenv);
for (i=0;environ[i];i++ ) printf("env: %sn",environ[i]);
fflush(stdout);
FILE *fp = popen("ls","r");
pclose(fp);
}

显示问题.在正常运行(运行cat,ls等)我得到这个版本的unsetenv:

unsetenv: 7f4c78fd5290
unsetenv: 7f1127317290
unsetenv: 7f1ab63a2290

但是,运行bash或sh:

unsetenv: 46d170

所以你有它. bash让你被骗了;-)

因此,只需使用您自己的unsetenv修改环境,就像**环境一样:

for (i=0;environ[i];i++ )
{
    if ( strstr(environ[i],"LD_PRELOAD=") )
    {
         printf("hacking out LD_PRELOAD from environ[%d]n",i);
         environ[i][0] = 'D';
    }
}

可以看出在strace中工作:

execve("/bin/sh",["sh","-c","ls"],[... "DD_PRELOAD=mylib.so" ...]) = 0

证明完毕

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读