티스토리 뷰

Hacking

[Web] XSS(Cross Site Scripting) 공격의 개요와 실습

꿈을 위해 잠을 잊은 그대에게 2018. 8. 12. 21:28

1. XSS(Cross Site Scripting)

1.1 정의

 

사이트 간 스크립팅(또는 크로스 사이트 스크립팅, 영문 명칭 cross-site scripting, 영문 약어 XSS)은 웹 애플리케이션에서 많이 나타나는 취약점의 하나로 웹사이트 관리자가 아닌 이가 웹 페이지에 악성 스크립트를 삽입할 수 있는 취약점이다. 주로 여러 사용자가 보게 되는 전자 게시판에 악성 스크립트가 담긴 글을 올리는 형태로 이루어진다. 이 취약점은 웹 애플리케이션이 사용자로부터 입력 받은 값을 제대로 검사하지 않고 사용할 경우 나타난다. 이 취약점으로 해커가 사용자의 정보(쿠키, 세션 등)를 탈취하거나, 자동으로 비정상적인 기능을 수행하게 할 수 있다. 주로 다른 웹사이트와 정보를 교환하는 식으로 작동하므로 사이트 간 스크립팅이라고 한다.

 

1.2 위험성

 

SQL injection과 함께 웹 상에서 가장 기초적인 취약점 공격 방법의 일종으로, 악의적인 사용자가 공격하려는 사이트에 스크립트를 넣는 기법을 말한다. 공격에 성공하면 사이트에 접속한 사용자는 삽입된 코드를 실행하게 되며, 보통 의도치 않은 행동을 수행시키거나 쿠키나 세션 토큰 등의 민감한 정보를 탈취한다.

 

크로스 사이트 스크립팅이란 이름 답게, 자바스크립트를 사용하여 공격하는 경우가 많다. 공격 방법이 단순하고 가장 기초적이지만, 많은 웹사이트들이 XSS에 대한 방어 조치를 해두지 않아 공격을 받는 경우가 많다. 여러 사용자가 접근 가능한 게시판 등에 코드를 삽입하는 경우도 많으며, 경우에 따라서는 메일과 같은 매체를 통해서도 전파된다.

 

1.3 공격법

스크립트 태그

방법 : 스크립트 태그로 자바스크립트를 실행한다.

 

예제 : <script>alert('XSS');</script>

 

설명 : 스크립트 태그의 스크립트를 실행시킨다. 안타깝게도, 매우 정직한 방법이라 대부분의 사이트에서 막는 경우가 많다. 브라우저단에서 필터링 해주는 경우도 있다. 물론 예외도 있다.하지만 만들어진지 몇십 년 이상 되었거나, 무작정 막지도 않는 경우도 있다.

 

자바스크립트 태그

방법 : 링크 태그로 자바스크립트를 실행한다.

 

예제 : <a href="javascript:alert('XSS')">XSS</a>

 

설명 : 브라우저에서 about: 링크와 같이, javascript: 로 시작하는 링크는 스크립트를 실행시킨다. 스크립트 태그와 같이, javascript: 를 필터링하는 경우가 많아 많은 사이트에서 막는다.

 

이벤트 속성

방법 : 이벤트 속성을 사용한다.

 

예제 : <img src="#" onerror="alert('XSS')">

 

설명 : 이벤트 속성으로 스크립트를 실행할 수 있다. 주로 on 으로 시작하는 속성이 이벤트 속성이다. 자주 사용되는 이벤트 속성으로는 onload onerror onclick 등이 있다. 물론, 이 방법 역시 '자바스크립트 링크' 방법만큼 많이 막혔다.

 

블랙리스트 우회

방법 : 알려지지 않은 태그와 속성들을 사용한다.

 

예제 : <ruby oncopy="alert('XSS')">XSS</ruby>

 

설명 : 블랙 리스트 방식으로 막는 사이트에 사용할 수 있다. 이벤트 속성 목록을 참고하자. 위의 방법들보다는 적게 막혔으나, 여전히 최근 웹사이트들에선 화이트리스트 방식 차단이 대부분이라, 막혔을 가능성이 높다.

 

내용 난독화

방법 : 따옴표로 감싸는 문자열 사이에 공백 문자들을 넣고, HTML 인코드를 하여 난독화한다.

 

예제 : <a href="&#x6A;&#x61;&#x76;&#x61;&#x73;&#xA;&#x63;&#x72;&#x69;&#x70;&#x74;&#xA;&#x3A;&#xA;&#x61;&#x6C;&#x65;&#x72;&#x74;&#xA;&#x28;&#x27;&#x58;&#x53;&#x53;&#x27;&#x29;">XSS</a>

 

 

설명 : 일부 브라우저에서 javascript: 링크 사이에 공백 문자가 들어갈 수 있고, HTML 인코드를 해도 디코드된 내용이 출력된다는 점을 이용한다. 여기에서는 '자바스크립트 링크' 방법과 사용하였지만, 당연히 다른 방법과 함께 사용할 수 있다.

 

스크립트 난독화

방법 : http://utf-8.jp/public/aaencode.html에서 자바스크립트 난독화.

 

예제 : https://namu.wiki/w/XSS/aaaenocde 참조.

 

설명 : 스크립트를 일본어를 사용한 이모티콘들로 난독화한다. 스크립트 실행은 가능하지만, document.cookie 와 같은 단어를 막을 경우 사용하면 된다.

 

1.4 방어법

입력 필터

자바는 적당한 XSS 필터를 만든 뒤, web.xml에 선언하여 모든 파라미터가 해당 필터를 거치도록 하는것 만으로도 좋은 효과를 볼 수 있다.

 

PHP는 입력을 처리할 때, 정규식을 이용하는 preg_replace를 사용하거나, 노드를 이용하는 DOMDocument를 사용할 수 있다. 속도는 preg_replace가 더 빠르지만, 정규식의 경우 예외와 오류가 종종 발생하기 때문에, 더 안전한 DOMDocument를 사용하는 것이 권장된다.

 

필터 제작

단순히 텍스트만 입력시키거나 출력하는 데 필터를 제작할 때, 주로 필터되는 것이 <>이다. 각각 &lt; &gt; 처럼 HTML 문자로 바꾸어서 HTML 코드가 아닌 단순 문자로 인식하게 하는 것이다. 하지만, 이 경우는 모든 HTML 태그를 막아버리기 때문에, 각종 스타일을 적용시켜야하는 사이트에서는 맞지 않을 수도 있다.

 

라이브러리 제작

각종 스타일을 적용시켜 글을 꾸며야 하는 사이트의 경우, 스크립트 태그와 이벤트 속성, javascript: 링크만 제대로 막아주어도 상당수를 막을 수 있을 것이다. 하지만, EMBED 태그를 이용하여 저런 기법을 사용하지 않고도 XSS를 먹이는 경우가 있으므로, 다른 것들도 모두 막아주어야 한다.

이 때, 일부 태그 및 속성만 막기 보다는, 반대로 일부 태그 및 속성만 허용하게 하는 것이 좋다. 몇몇 태그만 막는다면 HTML 태그나 속성이 추가될 수록 주기적으로 필터를 수정해줘야 하는데, 이럴 경우 HTML 표준을 주기적으로 꼼꼼히 챙겨보지 않는 한은, 업데이트를 하는 사이에 이미 해커가 침투해놓고 유유자적하게 빠져나갔을 수도 있다.

 

라이브러리 이용

기존에 있던 라이브러리를 가져다 사용해도 좋다. 개인이나 소규모 단체가 만든 것 보다는, 전문적인 보안 업체나 거대 기업에서 만든 것이 공신력있고 편하기 때문이다. 사용할만한 것으로는 OWASP Antisamy이나 NAVER Lucy XSS Filter, ESAPI 등을 이용하는 방법이 있다.

 

BBCode 이용

글을 꾸며야 하지만, 따로 필터를 만들긴 어려운 경우, BBCode를 사용할 수도 있다. 만들기도 다른 방법에 비해 편하고, 안전성도 높은 편이기 때문에 가장 추천되는 방법이다. 또한 <>같은 HTML 코드를 단순 문자로 바꿀 수 있기 때문에 XSS가 실행될 염려가 적다. 하지만 이 때, 정규식과 같이 단순히 문자열 치환으로 수정할 경우, XSS가 발생할 수도 있다.

 

출력 필터

HTML5부터 iframesandbox 옵션으로 iframe 내의 자바스크립트, 폼과 같은 것의 제한이 가능해 졌으므로, 위의 방법을 실행한 뒤 2차적으로 써보는 것도 좋다. , 어디까지나 2차로만 사용하는 것이 좋다. 구버전의 웹 브라우저라면 호환이 되지 않아 스크립트가 그대로 실행되거나, 설령 그게 아니더라도 웹 브라우저에서 취약점이 발견될 경우, 이런 방법이 뚫릴 수 있기 때문이다.

 

iframe은 단순히 다른 웹사이트를 불러오는 것만이 아니라, 부모 창에서 마음대로 수정할 수 있기 때문에, 무식하게 다른 페이지를 불러오며 AJAXPJAX 등을 포기하며 사용하지 말자. 물론, 기존부터 라이브러리를 사용하지 않고 웹 페이지를 개발하는 사람은 물론이고, jQuery같은 라이브러리를 사용하는 사람들도 조금만 검색해보면 간단하게 iframe의 내용을 수정할 수 있는 방법이 나오니 도전해 보도록 하자.

 

쿠키의 보안 옵션 사용

쿠키 생성시 '보안 쿠키'라는 파라미터를 지정하면 TLS 상에서만 사용하게 할 수 있으며, 'HTTP ONLY'라는 파라미터로 웹 브라우저상에서만 쓸 수 있게 할 수도 있다. 물론 완전히 방어가능한 건 아니니 위의 해결법과 병행하는 것이 좋다.


기타

위 방법들과는 별개로 일반 사용자가 스크립트를 잘 알지 못하는 것을 악용하여, 사용자가 브라우저 콘솔에 악성 스크립트를 삽입해 실행되도록 속하기도 하는데, 이를 스스로 하는 XSS라는 뜻의 Self XSS라고 부른다. 이는 사용자가 스스로 실행한 것이니만큼 위 방어 방법으론 막기 어려우니, 잘 알지 못하는 스크립트 등은 절대로 실행해서는 안 된다.


2. 실습

2.1 XSS(Cross Site Scripting) 공격



모의 해킹을 위한 워드프레스 개인블로그에 접속하였다.



내 블로그에 다음과 같은 코드가 포함된 게시글을 작성해보겠다.



제목을 확인 해보니 제대로 작성이 되었다.



확인된 제목의 게시글을 클릭해보니 코드가 제대로 실행이 된다.


-> 장난스러운 스크립트 코드이지만 이게 무한하게 작성이 되면 엄청 짜증나는 악성코드가 된다.



이번에는 하이퍼링크(href)를 통하여 javascript:alert('XSS') 를 이용한 코드를 작성하여 블로그에 게시해보았다.



ALERT2라는 새로운 게시글이 작성된 것을 확인하였다.



게시글에 들어가보자.


 하이퍼링크가 생성된 것을 확인하였다.



링크를 클릭하니 다음과 같은 알림이 뜬다.


-> 게시글 내에서 링크 클릭을 유도하여 악성 스크립트를 심을 수도 있다.


이것 또한 링크를 클릭했는데, 무한한 웹페이지 창이 뜨게된다면 악성코드가 된다.



이미지 태그를 이용하여 악성 스크립트를 작성해보았다.



게시글이 생성된 것을 확인하였다.



게시글을 확인하니 다음과 같은 악성 스크립트가 뜬다.



알 수 없는 이미지가 생성된 것을 확인하였다.


-> 성인 이미지 광고같은 악성 스크립트 게시물이 이와 같은 방법으로 사용된다.



iframe 태그를 이용하여 악성 스크립트를 작성해보았다.



게시글이 생성된 것을 확인하였다.



게시글에 들어가보니 다음과 같은 iframe이 생성된다.


-> 이 또한 img 태그와 같이 ifame 태그에 포함할 수 있는 무엇인가의 악성 스크립트를 배포할 수 있다.



다음은 악성 스크립트 코드를 난독화하여 공격하는 방법에 대해서 알아보자.


다음과 같은 사이트에서 일반 코드를 ASC 코드로 변환할 수 있다.


http://www.unit-conversion.info/texttools/ascii/



난독화된 악성 스크립트를 작성하였다.



작성된 게시글을 확인하였다.



작성된 게시글을 클릭해보니 알 수 없는 내용의 난독화된 문자가 나온다.


-> 이러한 악성 코드들은 난독화되어 있기 때문에 원인을 분석하기가 어렵다.


따라서 애초에 스크립트에 노출되지 않도록 여러 방어 방법들을 연구하여 취약점을 내어주지 않는 것이 중요하다.



2.2 해킹용 서버 구축과 XSS(Cross Site Scripting)을 통한 세션 탈취



다음과 같이 해킹을 하기위한 서버를 구축하고


그에따른 데이터베이스를 생성하였다.


-> 모의해킹을 위한 개인 워드프레스 블로그이다.


서비스를 하지 않기 때문에 딱히 털어갈 취약점이 보이지 않는다.


웹사이트의 url을 확인해보면 password또한 잘 난독화 되어있는 것을 확인할 수 있다.



해당 데이터베이스에 악성 스크립트를 심기위한 모의해킹용 테이블을 생성하였다.


CREATE TABLE SCRIPTING ( script VARCHAR(500) )



본격적으로 악성스크립트를 심기 위한 php 코드를 작성하였다.


db 정보를 알고 있다는 가정 하에


해당 db에 접속할 수 있는 코드를 작성한 것이다.



생성된 php파일을 서버로 이동하였다.


-> 악의를 품은 해커가 서버 폴더를 볼 수 있다는 것은


도둑에게 집 문을 열어준 것과 같다.


지금 이 상황은 악의를 품은 누군가가 집에 몰래 들어가서


집에 무언가 위험한 물건(script.php)을 놔두고 가는 상황과 비슷하다.


물건을 개봉하게 되면 집 주인은 어떠한 함정에 빠질 수도 있다.



생성된 php파일에 sql injection을 시도한다.


-> 모든 웹 사이트들은 해커의 injection에 의해 취약점을 드러낼 수 있다.


따라서 정보를 보호하기 위한 시큐어 코딩은 중요하다.


지금 이 상황은 도둑이 털어갈 집에 함정이 든 물건을 놔두고 간 후


리모콘을 통하여 물건을 조종하는 것과 비슷한 상황이다.



injection으로 인하여 해킹하기 위한 데이터베이스 table에 a라는 정보가 생겼음을 알 수 있다.


-> 만일 이러한 코드를 이용하여


데이터베이스에 알 수 없는 정보들이 마구 뒤섞인다면


서버의 데이터베이스 포함된 중요한 정보이 뒤섞일 수 있기 때문에


이는 엄청난 피해를 입을 수도 있다.


반대로 이러한 정보들을 탈취해갈 수도 있으니 서버의 데이터를 지키기 위한 시큐어 코딩의 중요성을 알 수 있다.



블로그에 악성 코드가 포함된 injection 코드를 게시하였다.


이렇게 데이터베이스에 악성 공격을 하는 것은 스크립트를 통해서도 시도할 수 있다.



게시글이 생성되어 클라이언트가 게시글을 선택하는 것은 생략하였다.


데이터베이스에 악성 스크립트로 인하여 취약점이 드러난 것을 확인할 수 있다.



비슷한 방법으로 다른 태그를 이용하여 악성스크립트를 작성하였다.


이번에는 b라는 정보를 injection 하는 코드이다.



게시글을 확인해보자.



게시글 안에 아무 정보가 없다.



돌아와서 데이터베이스를 확인해보니


b라는 정보가 데이터베이스에 침투된 것을 알 수 있다.



다음은 쿠키 정보를 injection하는 악성 스크립트가 포함된 게시글을 작성하였다.



게시글을 확인해보자.



게시글을 확인하니 성공하였다고 한다.


웹사이트의 url을 확인해보니 쿠키 정보가 무엇인가에 의해 테스트된 것을 알 수 있다.



쿠키 정보가 데이터베이스에 침투되었다.


소스코드



댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크