Cache Posoning Attack은 꾀나 전통적인? 공격 방법입니다. Cache에 공격자가 의도한 데이터를 남겨 다른 사용자로 하여금 비정상적인 요청을 수행하게 하죠. (대표적으로 DNS Cache Poisoning)
Web에서도 Cache를 사용하는데요, 관련해서 올 8월에 PortSwigger 팀에서 관련해서 글(https://portswigger.net/kb/papers/7q1e9u9a/web-cache-poisoning.pdf )을 게시했었고, 지인에게 내용 공유받아 정리해봅니다.
Web Cache?
캐싱은 서비스 속도 향상을 위해서 데이터를 미리 저장해두고, 사용자에게 제공하는 형태입니다. 지금 이야기드릴 웹 서버의 캐시 말고도 우리가 사용하는 브라우저에도 캐시가 적용되고 웹 데이터를 빠르게 로드하기 위해 로컬 피씨에 이미지나, 자바스크립트 등의 데이터를 저장하고 있습니다. 사용자는 웹 페이지 접근 시 인터넷을 통해 이미지를 받아오는게 아닌, 로컬에서 이미지를 가져오기 때문에 속도면에서 굉장히 이득이 되죠.
이런 캐시는 한번 내용이 저장되면 캐시를 무시하는 액션을 받지 않는 이상 저장된 데이터를 사용자에게 제공합니다. 웹 서버의 캐시 또한 데이터를 캐싱하고 사용자에게 빠르게 제공하는데 의미가 있습니다.
대표적으로 CDN(Content Delivery Network) 서비스들이 있고 이들은 이미지나 일부 코드를 저장하고 사용자에게 빠르게 제공해줍니다.
웹 서버들은 어떤 요청에서 캐시되고 어떤 데이터를 제공해줄지 기록하는데, 이 때 요청을 식별하는(캐시를 불러와야할 요청인지?) 값이 Cache Key 입니다. 캐시 키 는 웹 요청에서 일부를 떼어내어서 Request 일부와 이에 상응하는 Response를 저장하는데요, Request의 모든 부분을 확인하지는 않습니다.
보통 Path, Host 정도를 신뢰하기 때문에 페이지에 테스틀 위해 반복적으로 붙을 때 헤더를 붙여주거나 Path를 바꿔가며 테스트하죠(의미없는 파라미터 추가 ㅋㅋ)
|
|
Attack Point, How to Test?
캐시나 포이즈닝 공격 모두 자료가 많아서 구글링 좀 해보시면 많은 자료가 있습니다. 또한 웹 공격, 네트워크 공격에서 자주 소개되는 내용이라 익숙하실텐데요, 말 그대로 캐시에 악의적인 데이터를 남겨서 다른 사용자가 의도하지 않은 동작을 하도록 캐시를 오염?? 시키는 공격입니다.
테스트 방법을 좀 정리해보는데 이정도 순서로 테스트하면 어떨가 합니다.
|
|
하나 예시로 살펴보면 PortSwigger 팀이 redhat쪽 리포팅했던 내용인데, Request
|
|
Response
|
|
요런식으로 og 태그의 데이터가 사용자 입력으로 부터 받아지는걸 체크했고, “>alertg(1) 같이 XSS 코드로 Reflected 시켜 XSS 취약점을 발생시켰습니다. 이럴 경우 일반 웹 페이지에서 해당 헤더 없이 페이지를 접근해도.. Request
|
|
Response
|
|
구문이 삽입됩니다.
Live service에 테스트하긴 위험하지 않을까?
우선은 위험한게 맞습니다. 다른 사용자에 대해서 로직을 틀어버릴 수 있는거라 실 서비스에선 테스트하지 않는 게 좋아보이긴합니다. 다만 아까 위에서 캐시의 규칙에 대해 잘 보셨다면 영향가지 않는선에서 테스트할 수 있는 방법이 있습니다.
기본적으로 캐싱은 Host, Path 데이터를 기준으로 키를 잡습니다. 그 이야기인 즉슨 Host, Path가 동일한 사용자에 대해서 영향이 가는것이기 떄문에 path에 일반 사용자가 접근하기 어려운 값들을 넣어서 테스트하는 분석가만 확인한다면 직접적인 영향은 없을 것 같습니다. (그래도 되도록이면 prod 환경은 제외하는데… 정신 건강에 좋을듯, 버그 바운티라면 뭐 어쩔 수 없고)
|
|
이런식으로 파라미터에 의미없는 값을 넣어주어, 정확하게 저 url을 사용하는 사용자 이외에는 캐시가 오염되지 않도록 해주면 크게 걱정없이 테스트가 가능할 것 같습니다.
How easy is it?
결국 위에서 이야기한 내용들을 테스트하려면 어마어마한 노가다 작업이 필요합니다. (Key에 포함되지 않고 Response를 제어하는 파라미터, 헤더 등 값을 찾아야함…) 그래서 PortSwigger 쪽은 Burp extension(Param minor)를 만들어서 테스트한 것 같고, 각자 테스트 환경에 Cache Key, Response 데이터 변조에 대해 테스트 가능한 환경이 있어야 편리할 것 같습니다. (이전에 Param minor가 새로 올라왔을 때 뭔가 했더니 이거였었군요..)
ZAP은.. 코드 완성도는 얼마나 될지 모르겠지만, 시간되면 가볍게 만들어서 공유드리겠습니다 : )
How to Protect? & Conclusion
Checked Header Base XSS & Other vulnerability point 이거 안하는 회사도? 은근 있을 것 같습니다만, 해주는게 좋습니다. Cache Poisoning 말고도 영향 있는 부분들이 있어서…
결국은 영향력이 발생하는 부분은 Header 데이터가 본문에 어떻게 삽입되느냐입니다. 분석을 하시는 기업보안담당자라면, 한번 더 생각해보는 계기가 되었으면 좋겠네요.
Use Vary Header Vary 헤더는 PC웹 환경과 모바일 웹 환경 구별을 위해 많이 사용하는 헤더인데요, Vary 헤더가 붙은 경웨 User-Agent까지 식별해서
|
|
이렇게 하면 User-Agent 헤더에 대해서도 검증하게 되죠. 자세한 내용은 모질라랑 구글쪽 문서 참고해주세요.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary https://developers.google.com/search/mobile-sites/mobile-seo/dynamic-serving?hl=ko
결국은 이 문제에 대한 근본적인 해결 방안은 자주 보안 테스팅을 하고 위협을 제거하는 것 같습니다. (그렇다고 캐시를 쓰지 말라고 하는건 좀 그렇잖아요) Header로 부터 오는 공격도 공격자가 아주 좋아할 먹잇감이니 신경써서 체크하면 좋을 것 같단 생각이 듭니다.
12월은 매우 정신 없던 달이였던 것 같습니다. 뭐 한것도 없느데 순식간에 마지막날이 되었네요.. 아마 시간을 보아하니 이글이 올해 마지막 글일 것 같습니다. 해피뉴이어!
Reference
https://portswigger.net/kb/papers/7q1e9u9a/web-cache-poisoning.pdf https://blog.cloudflare.com/cache-poisoning-protection/ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary https://developers.google.com/search/mobile-sites/mobile-seo/dynamic-serving?hl=ko https://blog.finjan.com/web-cache-poisoning/