상세 컨텐츠

본문 제목

Django CSRF 보호매커니즘 우회 취약점(CVE-2016-7401) 분석

국내외 보안동향

by 알약(Alyac) 2016. 9. 28. 09:49

본문

Django CSRF 보호매커니즘 우회 취약점(CVE-2016-7401) 분석


9월 26일, Django가 CSRF 보호매커니즘 우회 취약점(CVE-2016-7401) 취약점을 패치하였습니다. 취약점은 다음과 같은 부분으로 구성됩니다. 



Google Analytics로 인해 발생하는 Cookie 인젝션 취약점 


Google analytics는 다음과 같이 Cookie를 통해 사용자를 추적할 수 있도록 설정할 수 있습니다. 


__utmz=123456.123456789.11.2.utmcsr=[HOST]|utmccn=(referral)|utmcmd=referral|utmcct=[PATH]


이는 [PATH]위치를 제어함에 따라, Cookie의 일부분을 제어할 수 있다는 뜻입니다. [PATH]의 위치는 인코딩 및 필터를 하지 않기 때문에 이 부분이 다음과 같은 취약점을 발생시킬 수 있습니다.



Django의 구조적 결함 분석


각기 다른 Web Server들은 Cookie Header에 대한 각각 다른 분석방식을 사용합니다. 일반적으로 브라우저가 발생시키는 Cookie는 다음과 같습니다. 


Cookie: param1=value1; param2=value2;


많은 웹서버들은 "콤마"를 통하여 Cookie의 Header를 구분합니다. 


Cookie: param1=value2, param2=value2

Cookie: param1=value2,param2=value2


Python + Django는 잘못된 규칙으로 인하여 "]"를 구분부호로 사용할 수 있게 됩니다. 


Cookie: param1=value1]param2=value2


해당 문제는 Python의 Cookie 라이브러리의 문제로, 다음과 같은 테스트를 통하여 확인할 수 있습니다. 


>>> from http import cookies

>>> C = cookies.SimpleCookie()

>>> C.load('__utmz=blah]csrftoken=x')

>>> C

<SimpleCookie: csrftoken='x'>


위에서 확인할 수 있듯이, c.load('__utmz=blah]csrftoken=x') 후에 cookie는 Cookie[__utmz]=blah,csrftoken=x 두개 의 값을 잘못 해석합니다. 



각기 다른 브라우저가 Cookie를 처리하는 특성


Safari를 제외한 모든 브라우저는 몇몇 특수기호(빈칸, 콤마, 혹은 /등)을 Cookie 값으로 설정하는 것을 허용합니다. 예를들어 Chrome이 처리하는 Cookie 속성의 개수는 제한되어 있습니다. 


Set-Cookie: test=test; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=blah.blah.blah.google.com;


위와 같은 도메인은 blah.blah.blah.google.com이 아니라, google.com로 인식될 수 있습니다.



TOKEN을 인젝션 하여 CSRF 검증 우회


위 3개 특성을 이용하여, 다음과 같은 조건을 가진 홈페이지를 공격해 보았습니다. 


※ 조건

- Google analytics를 사용

- Cookie값을 잘못 해석하는 서버사용 (Django등)

- Cookie를 기반으로 한 CSRF 차단방식 사용(Cookie중의 Token와 리스트 중의 Token을 비교)


그 후 Cookie 중 Token을 임의의 문자열로 설정하고, 기존의 Token을 덮어씌워 해당 홈페이지의 CSRF 검증 우회가 가능합니다. 한가지 문제는 __utmz 해당 쿠키일 때, 최대 6개월까지 새로고침이 이루어지지 않습니다. 


관련하여 해결방법은 동일한 Google Analytics의 서브 도메인을 찾고, 위에서 언급한 각기 다른 브라우저가 Cookie를 처리하는 특성을 이용하여 메인 도메인의 Cookie값을 domain으로 덮어씌우면 됩니다. 다른 브라우저는 __utmz가 새로고침될 때 공격할 수 있습니다.




참고 :

https://docs.python.org/3/library/http.cookies.html

http://hg.python.org/cpython/file/3.4/Lib/http/cookies.py#l432

http://tools.ietf.org/html/rfc2109

http://tools.ietf.org/html/rfc2068

관련글 더보기

댓글 영역