ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [WEBHACKING] XSS(Cross-Site Scripting)에 대해서
    # 웹해킹 공부중 2020. 11. 30. 04:03

    1. XSS란?

    XSS는 Cross-Site Scripting의 약자로 교차 사이트 스크립팅이라고도 한다. 이미 CSS는 Cascading Style Sheets로 사용중이어서 Cross인 'X'를 약어로 사용한듯 하다. 사용자가 요청한 페이지에 강제로 악성 스크립트를 삽입해서 브라우저에서 악의적인 동작이 실행되도록 하는 공격기법이다. 1995년에 Javascript가 발표된 이후 2000년경 'MySpace'라는 플랫폼에서 XSS 취약점이 처음으로 보고된듯하다. 20년여가 지난 지금도 XSS는 취약점이 발생하고 관련 공격이 발생하면서 꾸준히 웹 취약점 빈도수 상위 10위권에 들고있다. 공격기법이 오래된 만큼 보안기법들도 계속 연구되어 발표되고 있으나 그만큼 우회기법들도 생겨나고있고 자바스크립트가 계속 광범위하게 사용되면서 여전히 취약한 곳이 많은 것 같다. XSS는 자바스크립트로 실행되는 모든 코드가 실행될 수 있는데 특히 사용자의 세션을 공격자의 서버로 전송해서 탈취하거나 악성코드가 있는 페이지로 리다이렉트 시키는 방식으로 공격이 주로 행해진다. 그 외에도 자바스크립트를 활용해서 내부 네트워크 포트스캔과 같은 공격도 가능하다. XSS는 이렇게 다른 사이트로(cross site)의 데이터 전송이 주로 이뤄지는 공격이라 사이트간 스크립팅(Cross-Site Scripting)이라고 명명된 듯 하다. 

    XSS는 사용자가 열람한 페이지에서 필요한 정보를 얻거나 수정할 수 있으며 세션과 같은 중요 데이터를 공격자의 서버로 전송하여 탈취할 수 있다. 뿐만아니라 피싱사이트로 유도를 하거나 브라우저에 0-day가 있거나 업데이트가 되지 않은 경우 브라우저를 exploit 하는 코드를 실행시켜 RCE까지도 가능할 수 있기 때문에 주의해야한다.

    2. XSS의 종류

    XSS는 크게 Reflected-XSS, Stored-XSS, DOM-based-XSS 이렇게 세 종류로 나뉜다. 기본적인 공격배경은 사용자의 브라우저가 악성 스크립트를 실행하게 하는것이나 그 방식에 따라 종류가 나뉘게 된다.

    1. Reflected XSS

    Reflected XSS는 사용자의 요청에 포함된 스크립트가 서버로부터 그대로 반사(Reflected)되어 응답메시지에 포함돼 브라우저에서 스크립트를 실행되는 공격기법이다. 말 그대로 요청에 대해 스크립트가 반사되어 돌아와 실행되기 때문에 Reflected XSS(반사 XSS)라고 이름이 붙여졌다. 해당 공격은 스크립트가 웹앱 내에 저장되지 않고 영구적이지 않은 공격으로 한 요청에 대한 하나의 응답으로 공격이 진행된다. 보통 취약한 웹앱으로 스크립트가 포함된 요청을 보내도록 변조된 URL로 사용자가 접속하도록 하는 방식으로 공격이 진행되며 URL말고도 어떻게든 사용자가 악성스크립트가 포함된 요청을 하도록 한다. 

    <?php
    $name = $_GET['name'];
    echo "Hello $name";
    ?>

    그림 1 [reflected-xss test]

    예시로 간단한 PHP 코드를 작성해보면 위와같고  http://reflected-xss-test.com/xss.php?name=<script>alert(1)</script> 로 서버에 스크립트를 포함한 요청을 보낼 경우 스크립트가 보낸 그대로 브라우저로 응답되어 스크립트가 실행된다. 

    해당 취약점을 테스트하기 위해선 서버에서 어떤 인자를 받는지 확인하고 받은 인자가 응답메시지에 포함되어 오는지를 확인한 뒤 alert(1)과 같은 스크립트 테스트 코드를 인자로 전달하는 방식으로 테스트 해볼 수 있다.

    2. Stored XSS

    이름에서 유추할 수 있듯이 악성 스크립트가 서버측에 저장되어 사용자들의 요청이 있을때마다 저장된 스크립트가 사용자에게 응답되어 스크립트를 실행시키는 공격이다. 쉬운 예로 게시판 글 작성할 때 악성 스크립트를 포함해서 글을 작성해 서버의 DB에 저장시키고 사용자들이 해당 게시글을 열람할 때마다 저장된 스크립트가 실행되는 경우 Stored XSS라고 한다. 해당 취약점은 경우에따라 불특정다수에게 영향을 끼칠 수 있기 때문에 주의해야한다.

    $query = "INSERT INTO board VALUES(0,'$title','$content');";
    $result = mysqli_query($conn,$query);
    $query = "SELECT title, content FROM board WHERE idx=$no;";
    $result = mysqli_query($conn,$query);
    $row = mysqli_fetch_array($result);
    echo "<h1>" . $row['title'] . "</h1>";
    echo $row['content'];

    대충 이런식으로 웹앱이 동작한다면 여러 공격이 가능하겠지만 우리가 알아볼 Stored-XSS 역시 발생한다. 

    그림 2 [XSS Text]
    그림 3 [XSS Test]
    그림 4 [XSS Test]

    이렇게 글 작성시 스크립트를 포함해서 저장하면(그림 2) 해당 스크립트는 서버의 DB에 저장된다. 그리고 이 게시글(그림 3)을 열람하면 그림 4와같이 스크립트가 실행된다. 해당 게시글을 읽는 모든 사람은 모두 스크립트가 실행된다. 

    3. DOM-based XSS

    DOM(Document Object Model)은 HTML의 요소들을 프로그램에서 제어할 수 있도록 객체화한 API로 페이지에 존재하는 요소(element)들의 논리적 구조와 해당 요소들에 접근할 수 있는 방법들을 정의해둔 것이다. 자바스크립트는 이 DOM을 활용해서 동적으로 요소에 접근하거나 수정, 삭제, 추가 등의 행위를 할 수 있다.

    DOM-based XSS는 이렇게 DOM을 이용해서 요소들을 수정하거나 추가하는 등의 행위를 할 때 발생하는 XSS 취약점을 말한다. 앞의 Reflected-XSS나 Stored-XSS는 서버에서 사용자의 요청을 처리하는 과정에서 취약점이 존재해서 응답으로 해당 스크립트가 전송되는반면 DOM-based XSS는 클라이언트측에서 DOM을 이용해서 동적으로 페이지를 조작할 때 발생하는 취약점이다. 즉 공격 페이로드가 응답메시지에 포함되어있지 않을 수 있다.(순수한 DOM XSS의경우) 주로 조작된 URL로 접속했을 때 자바스크립트가 해당 URL을 이용해서 동적으로 페이지를 구성하려하거나 iframe 에 메시지를 전달할 때 해당 메시지를 처리하면서 발생한다. 

    <script>
    	var div = document.getElementById("test");
    	div.innerHTML="URL: " + decodeURI(window.location.href);
    </script>

    그림 5 [DOM XSS]

    해당 코드는 URL을 가져와서 화면에 그대로 출력해주는 코드로 해당 페이지에 "<img src='' onerror='alert(1)'>" 같은 스크립트를 함께 넘기면 그림 5와같이 스크립트가 실행된다. 

    자바스크립트에서 innerHTML을 사용해서 DOM 객체를 동적으로 조작하고 있는데 innerHTML의 경우 현대 브라우저에서는 <script>나 <svg> 와 같이 일부 태그에 대해서 실행이 안되도록 막아뒀습니다. 이 경우 <img>나 <iframe> 을 이용해서 테스트를 진행할 수 있습니다. 

    DOM-based XSS는 앞서 소개한 Reflected방식이나 Stored 방식으로도 취약점이 발생할 수 있다. 예를들어 악성 스크립트가 포함된 URL로 접속했을 때 서버에서 해당 스크립트를 자바스크립트의 String에 포함시켜서 응답할 수 있다. 이 때 응답에 포함돼있던 자바스크립트 코드가 취약하여 DOM-based XSS를 유발할 수 있다. 그리고 악성 스크립트가 서버측에 저장되어 있다가 나중에 오는 요청에 대해 응답할 때 마찬가지로 자바스크립트가 DOM을 이용할 때 스크립트가 삽입되어버릴 수 있다. 

    XSS의 종류중 Self-XSS 라고 불리는 공격도 있는데 해당 취약점은 발생하더라도 크게 파급력이 없는 경우가 대부분이다. 다른 사용자를 공격하는게 아니라 사용자 스스로 공격코드를 넣어 스크립트를 실행하기 때문이다. 예를들면 로그인 한 뒤 사용자 정보수정페이지에서 특정 정보를 변경했더니 XSS가 발생하고 다른 페이지에서는 발현이 되지 않을 때 해당 페이지는 본인만 접근가능하므로 self-xss가 된다. 그렇기 때문에 크게 대수롭지 않게 넘길 수 있지만 사회공학기법을 이용하거나 다른 취약점을 연계해서 주요 정보 탈취와 같은 피해가 발생할 수 있기 때문에 패치가 필요하다.   

    3. XSS 보안 방안

    사용자의 입력에 대해서는 무조건 의심을 하고 검증하는 작업이 필요하다. 개발하려는 어플리케이션의 요구사항에 따라 조금씩 다르겠지만 가장 기본적으로 하는 보안조치가 HTML 태그나 자바스크립트에서 사용되는 특수문자들에 대한 필터링 혹은 인코딩이다. 꺽쇠(<>)나 괄호(), &기호, 따옴표('), 쌍따옴표("), 콜론(:), 세미콜론(;) 등의 특수문자들을 HTML 인코딩 등으로 인코딩을 하면 공격 코드가 실행되지 않는다.

    경우에따라 이런 특수문자들 혹은 HTML 태그들을 허용해야할 때가 있는데 그럴땐 반드시 사용해야하는 태그와 그 태그에 대한 속성을 화이트리스트 방식으로 필터링해서 태그 사용에 제한을 둔다. 필터링 할때는 대소문자 구분없이 필터링 해야한다. 그리고 URL을 입력받을 경우 해당 URL이 정상 URL인지에 대한 검증을 수행해야한다. 이런 필터링의 경우 MS의 "AntiXSS"나 Mozila의 "Bleach"와 같은 보안라이브러리를 사용하는 것도 좋은 방법이다. 

    그리고 CSP를 이용해서 스크립트가 실행되는 조건(특정 cdn 서버에서 받은 자바스크립트만 허용 등)을 걸어주는 것도 좋은 방법이며 세션에 HTTPOnly를 설정해서 스크립트에서 해당 세션을 로드하지 못하도록 막을 수 있다. 

    XSS는 굉장히 오래된 공격 기법이면서도 취약성 테스트가 비교적 간단하기 때문에 공격시도가 매우 높다. 어플리케이션들이 계속해서 확장되면서 취약점 또한 지속적으로 발생하고 있으며 방대한 시스템에서 간과하고 넘어간 부분이 많아 여전히 빈번히 발생하는 웹 취약점 상위권에 속한다. 보안기법 또한 꾸준히 연구되고 있지만 그만큼 우회기법도 계속해서 연구되고 있으며 피해를 당했을 때의 영향력도 클 수 있기때문에 철저히 보안할 수 있어야한다. 

    댓글

Designed by Tistory.