모의해킹 스터디 복습

모의해킹 스터디 9-10주차: XSS

whydontyoushovel 2024. 12. 19. 00:51

 

XXS (Cross-Site Scripting attack)

  • 기본 개념
  • 종류:

                - Stored XXS (저장!)

                - Reflected XXS (반사!)

                - DOM Based XSS (조립!)

  • Stored XSS + 취약점 찾기
  • Reflected XSS + 취약점 찾기
  • DOM Based XSS
  • XSS 공격 대응 방법
  • 정리

 

 

 

XXS

Cross-Site Scripting

a.k.a 크사, 크스스, 크싸

 

 

 

기본 개념

   XSS는 클라이언트 측 스크립트를 사이트에 삽입하여 이용자 브라우저에서스크립트가 동작하게 만드는 해킹 기법으로, 여기서 클라이언트 측 스크립트란 html, css, javascript 등과 같이 이용자들의 브라우저에서 실행되는 코드를 의미한다. 보통 javascript를 활용한 XSS 공격이 많다.

 

   예를 들어, 게시글의 제목이 게시판에 표시되는 구조의 사이트를 이용한다고 해보자.

   공격자는 게시글 제목에 악성 스크립트를 작성하여 사이트 사용자의 쿠키를 자신의 서버로 전송하려 한다. 게시판 페이지에서 제목을 출력할 때 XSS 공격에 대한 대비를 하지 않으면 그 코드가 사용자들의 HTML 코드 내부에 찍히게 된다. 단지 게시판에 입장했다는 것만으로 사이트 사용자들의 쿠키가 탈취되는 등의 일이 일어날 수도 있는 것이다. 

 

   예시에서 볼 수 있듯이 SQL Injection과 달리 서버가 아닌 클라이언트를 대상으로 한 공격이다.

 

 

기본적인 설명을 읽은 후에 이런 궁금증이 생길 수 있다.

  1. 어디에  삽입되는가 (-> XSS 포인트 찾기 (공격자 입장))
  2. 어떻게 동작하는가  (-> XSS 포인트 확인하기 (피해자 입장))
  3. 무엇을 실행할 수 있는가  (->XSS 응용하기)

이번 포스팅에서는 XSS 포인트를 찾는데 중점을 두어 1번과 2번에 대해 정리해보려고 한다.

(3번 XSS로 공격하는 실습은 다음주차에 할 예정이다.)

 

 

 

종류

   어디에 삽입하여, 어떻게 동작하게 하는지는 크게 세 가지 방법으로 나누어 설명할 수 있다.

 

1) Stored XSS

  • 서버에 스크립트를 저장하여 데이터가 표시되는 페이지에 사용자가 입장할 때 스크립트를 실행시키는 방식.

 

2) Reflected XSS

  • GET메서드를 이용하여 url 파라미터를 서버에서 그대로 반사시키는 동작을 활용한 방식.

 

3) DOM Based XSS

  • Reflected와 비슷하지만 이 경우 서버에서 반사시키는 것이 아니라 사용자 브라우저가 클라이언트 측 스크립트를 다처리하며 발생.

 


POC

Proof Of Content

 

어떤 코드가 삽입될 수 있다는 것을 증명하는 코드.

XSS 취약점 진단 시 서버에 실제 공격 스크립트를 넣지 않으면서 악성 스크립트가 삽입될 수 있음을 증명하기 위해 사용하는 코드로 아래와 같은 예시가 있다.

 

1) alert(1)

2) confirm(1)

3) prompt(1)

4) console.log(xss)

 

실무에서 랜섬웨어 코드나 암호화폐 채굴 코드 등을 넣을 수는 없으니 취약점이 있는지 없는지만 확인하기 위해 사용된다.

 


 

 

 

 

                Stored XSS               

 

 

  • 작동 방식

   서버에 악성 스크립트를 저장시켜, 이용자 브라우저에 스크립트가 노출되었을 때 악성 스크립트를 작동시키는 방식.

 

  • 발생 포인트

   회원가입 페이지나 게시판 글 작성 페이지 등과 같이 서버에 저장한 데이터가 사이트 내 다른 페이지에서 표시될 때 (이용자 브라우저에 노출될 때) Stored XSS가 일어날 가능성이 있다고 볼 수 있다.

 

  • 공격자 입장: 서버에 저장
  • 피해자 입장: 스크립트가 표시되는 페이지에 입장하면 브라우저가 스크립트 렌더링, 실행

 

 

  Stored XXS 취약점 찾기               

 

 

 

****사용자가 저장한 데이터가 출력되는 곳.

 

< 절차 >

- 데이터를 서버에 저장해보기.

- 그 데이터가 사이트의 어디서 출력되는지 확인하기.

- 필터링 확인을 위해 테스트(<,",',>) 데이터 넣어서 보내기.

- html코드를 봤을 때 출력되는 곳에 특수문자가 그대로 나오면 xss 가능성 높음.

- POC 넣어 저장

- POC가 저장된 페이지에 들어가 스크립트가 실행되는지 확인

 

 

< 예제 >

 

 

사이트에 진입 후 로그인

 

 

게시물 작성 페이지에서 제목 위치에 스크립트 삽입 후 저장 (서버에 저장됨)

 

 

게시물 목록 페이지에서 스크립트 작성된 게시물 요청

(게시물 목록에서는 스크립트 코드가 필터링되고 있다.)

 

 

거북이 알 낳는 게시물을 요청했더니 삽입한 스크립트가 실행되어 alert창이 뜬 모습이다.

 

 

버프 스위트로 응답 데이터를 확인한 결과 삽입한 스크립트가 필터링 없이 작동하고 있다.

 

 

   위 예제에서 확인할 수 있듯이 Stored XSS 공격은 서버에 저장한 데이터가 화면에 출력되는 곳에서 일어난다. 공격자는 해당 포인트에서 어떤 의도를 가진 스크립트를 저장하여 불특정 사용자가 해당 페이지를 요청할 경우 사용자의 브라우저에서 스크립트가 실행되도록 만들고 있다. 코와이~

   서버에 저장한 스크립트가 출력되는 페이지에 진입할 경우 악 하고 당할 수 있기 때문에 공격 범위가 광범위하지만 서버에 그런 코드를 저장한 사용자가 누구인지 흔적이 남는다. 공격하려면 우회해서라도 공격할 것이기 때문에 기업에서 Stored XSS 공격이 Reflected XSS 공격보다 더 위험하다고 여기는 듯하다. 근데 잡으려면 다 잡더라..

 

 

 

나중에 고민하려고 적어둠

더보기

xss_1사이트에서 rarara<'">로 회원가입했더니 가입 성공 뜨길래 로그인했더니 로그인 안됨. 아 특수문자 필터인가 싶어서 rarara로 로그인 시도해봤는데 안됨. htmlspecialchars로 인코딩한 버전으로 로그인해봤더니 안됨. 어떤 부분에서 어떤 작용이 이뤄지는지 생각해보려고 적어둔다.

 

 

 

 

 

                Reflected XSS               

 

  • 작동 방식

   요청으로 보낸 파라미터가 응답 페이지에 그대로 찍혀 나오는 경우 악성 스크립트가 포함된 해당 url을 공격 대상에게 공유하여 링크를 클릭하게 유도. (파라미터가 응답 페이지에 그대로 반사되는 것을 서버의 에코 기능이라고 표현하는 듯 함.)

 

   예를 들어, naver.com/board.php?item=45 와 같은 페이지가 있다고 하자. 해당 페이지에는 item의 파라미터인 45가 그대로 반사되어 표시되고 있다. 이때 item에 대한 파라미터를 item=<스크립트>아~~주못돼먹은악성스크립트</스크립트>라고 바꿔 공격 대상에게 공유한다. 공격자가 해당 링크를 누르면 스크립트가 실행되는 페이지에 노출되어 피해를 입게 된다.

 

   악성 스크립트를 서버에 저장할 수 없는 페이지에서도 XSS를 일으킬 수 있는 공격 방식이다.

 

  • 발생 포인트

   요청으로 보낸 파라미터가 응답 페이지에 그대로 찍혀 나오면서, POST방식이 아닌 GET방식으로 파라미터를 보낼 때, Reflected XSS가 일어날 가능성이 있다고 볼 수 있다.

   POST로 파라미터 보내봤자 내 브라우저에서만 스크립트가 실행되므로 누워서 침 뱉는 격. GET으로 보내야 파라미터를 고정시켜 공격 대상에게 공유할 수 있다.

 

  • 공격자 입장: url 파라미터가 반사되는 페이지 이용.
  • 피해자 입장: 링크 클릭하여 스크립트가 포함된 페이지 요청

 

내가 만약 악성 스크립트가 포함된 url을 이메일로 공유한다면 링크를 누르지 않아도 이메일을 읽을 때 스크립트가 실행되는 거 아닌가?

더보기

 

아님. 대부분의 이메일 클라이언트는 링크를 실행시킬 코드가 아니라 단순 문자열로 처리하기 때문에 실행되지 않음.

링크를 눌러야 해당 페이지에 스크립트를 요청으로 보내 스크립트가 작동하게 됨.

 

이메일에 링크가 보임 -> 실행 안됨.

링크를 누름 -> 브라우저가 해당 페이지 요청

-> 악성 스크립트가 화면에 표시된 페이지 응답

-> 브라우저가 페이지를 렌더링하며 스크립트 실행

-> 악 당했다!!

 

대신 보안 조치가 되어있지 않은 사이트 내 메시지 기능 등을 사용하면 링크를 누르지 않아도 스크립트 코드를 a태그에 포함시키는 과정에서 실행될 수도 있다고 함. 이 경우 reflected xss라기 보단 stored xss가 실행된다고 봐야할 듯.

저 "단순 문자열로 처리"라는 게 특수문자를 필터링한다는 것과 같은 뜻인지 잘 모르겟다.

 

아무튼 특수문자 필터링은 htmlspecialchars를 이용한다고 함.

stored xss는 악성 스크립트를 서버에 저장하여 다른 페이지에서 열람할 때 실행되어서 저장시킬 때, 화면에 출력할 때 둘 다 필터링하는 게 좋고

reflected xss는 url 링크를 통하기 때문에 get으로 받는 파라미터에 특수문자 필터링을 적용하면 된다는 듯함.

 

 

 

 

  Reflected XSS 취약점 찾기           

 

 

****사용자가 입력한 데이터가 같은 페이지에서 출력(반사)되는 곳.

 

< 절차 >

- 데이터를 입력해서 요청 보내보기

- 그 데이터가 같은 페이지에서 그대로 출력되는지 확인해보기

- 필터링 확인을 위해 테스트(<,",',>) 데이터 넣어서 보내기.

- html코드를 봤을 때 출력되는 곳에 특수문자가 그대로 나오면 xss 가능성 높음.

- POC 스크립트 넣어서 실행해보기.

- POST로 보내고 있으면 GET으로 바꿔서 보내보기. (안되면 버림)

- GET요청으로 보낼 수 있으면 스크립트가 포함된 url로 재접속해서 스크립트가 실행되는지 확인하기.

 

 

< 예제 >

 

 

사이트 진입 후 로그인.

맞는 계정 정보로 로그인할 경우 인덱스 페이지에 리다이렉션 되지만

맞지 않은 계정 정보로 로그인할 경우 alert창이 출력되는 것을 발견했다.

 

 

ga로 로그인 시도한 결과. ga는 없는 계정 정보이다.

alert창에 사용자 입력 데이터를 포함시키고 있다. 이를 이용해 스크립트를 삽입해본다.

 

 

이번엔 alert 코드에 맞춰 ]')</script><script>alert('Reflected XSS')</script>로 로그인을 시도해본다.

 

]')</script><script>alert('Reflected XSS')</script>로 로그인한 결과.

서버에서 준비된 alert문과 내가 임의로 삽입한 alert문이 차례로 출력되는 것을 확인했다.

 

 

이번엔 Reflected XSS 공격으로 사용될지 여부를 알아보기 위해 POST방식으로 전달되던 데이터를 GET방식으로 변경하여 스크립트 코드를 보내보았다. GET방식으로 전달되는 데이터는 url을 통해 확인할 수 있다.

 

아이디에 you+hacked+]')</script><script>alert('Reflected+XSS+2')</script>를 입력하여 GET방식으로 데이터를 전달했다. 

 

GET방식으로 스크립트를 삽입한 결과 서버의 alert창과 내가 입력한 alert창이 순서대로 출력되었다. 

 

   해당 url을 타인에게 공유하여 잠재적 피해자가 링크를 클릭할 경우, 악성 스크립트에 노출된 피해자가 로그인을 시도할 수 있다. 약 스크립트에 쿠키 탈취 코드가 삽입되어있다면 피해자가 로그인에 성공한 경우 공격자는 피해자의 쿠키에 있는 세션 아이디 등을 이용해 사이트 내의 자원을 무분별하게 사용하려 할 수 있다.

   Reflected XSS 공격은 Stored XSS 공격과 다르게 링크를 공유해야하고 타인이 그 링크를 눌러야 스크립트가 실행되기 때문에 공격 범위가 좁은 편이지만 상대적으로 공격자의 출처를 알기 어렵다는 특징이 있다. 그래도 찾으려면 다 찾더라..2

 

 

reflected xss에서 공격자가 만든 사이트가 아닌 다른 사이트를 이용하는 이유

더보기

1) url에 수상쩍은 도메인 이름이나 ip주소가 있으면 사람들은 접근하려고 하지 않음. naver같은 그럴싸한 이름이면 마음놓고 접근하기 때문에 다른 사이트를 이용함.

 

2) 공격할 사이트의 자원을 이용하기 위해 사용자의 쿠키를 탈취하는 거라면 해당 사이트에서 쿠키 탈취를 시도해야함. 

 

 

 

 

 

                DOM Based XSS               

 

DOM (Document Object Model)이란?

더보기

웹 페이지 내 객체에 접근하여 지지고 볶고 활용할 수 있게 하는 표현.

 

객체 예시 => body, head, img, p 등의 태그

 

표현 예시

=> document.querySelector,

=> document.body.innerHTML,

=> document.getElementById("id").setAttribute, 

=> document.getElementByClassName("class")[index].addEventListener 등등..

 

예시 코드

<button id="pageReload">새로고침</button>

<!--id가 pageReload인 요소를 클릭하면 새로고침 됨.-->
<script>
  document.getElementById("pageReload").addEventListener("click", function() {
     location.reload();
  )};
</script>

 

 

WAS 대신 자바스크립트로 동적 페이지 개발할 때 필요한 요소인 듯.

 

 

https://velog.io/@hyhy9501/%EC%9B%B9-%EA%B0%9C%EB%B0%9C-%EA%B8%B0%EC%B4%88-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-7.-DOM%EC%9D%B4%EB%9E%80

 

[웹 개발 기초 자바스크립트] 7. DOM이란?

DOM (Document Object Model)은 웹 문서의 구조화된 표현입니다. 이것은 프로그래밍 언어가 웹 페이지 내의 객체에 접근하고 조작할 수 있게 하는 인터페이스로 동작합니다. 주로 자바스크립트에서 웹

velog.io

 

 

 

 

****Reflected XSS와 url 파라미터를 활용한다는 부분에서 비슷

 

  • 작동 방식

   악성 스크립트를 담은 파라미터를 요청으로 보내어 클라이언트 측 스크립트의 DOM으로 처리하게 함. Reflected XSS 공격과 비슷하게 주로 url 링크를 이용하여 공격하며 사용자가 악성 스크립트를 담은 링크를 누를 경우 사용자 브라우저에 공격 스크립트가 실행됨.

   이때 공격자의 스크립트가 화면에 출력되는 경우가 있고 출력되지 않는 경우가 있음.

 

  • 발생 포인트

  사용자 입력 값을 자바스크립트의 DOM으로 처리하는 곳에서 일어날 가능성이 있다.

  입력값이 화면에 출력되는 경우 입력값이 화면에 출력되지 않는 경우
응답 데이터 입력 값 안 찍혀있음. 입력 값 안 찍혀있음.
찾는 법 Reflected 같은데 응답에 안 찍힘. 입력값 사용하는 위치 스크립트 분석 및 테스트.
발견 코드 예시 document.write, innerHTML 등 eval, setTimeout, setInterval
혹은 사용자 입력값을 속성에 삽입 등
발견 난이도 찾으려고 하면 찾을 수 있음. 일단 안약 한 통 사놔야함.

 

- 응답에 입력 값 안 찍히는 이유: 처리를 서버에서 해서 찍어내는게 아니라 입력 값을 자바스크립트가 받아서 브라우저가 렌더링하면서 처리해서 응답엔 안 찍힘.

 

- eval(): 인자로 받은 문자열(코드)을 바로 실행해버리는 함수. 검색해보니 쓰지말라고 신신당부한다. 속도 면에서도 좋을 게 없는 듯.

<!--http://domain/#alert(1) 요청 시-->
<script>
  var input = location.hash.substring(1); <!--해시 뒤 데이터 저장-->
  eval(input); <!--alert(1) 실행-->
</script>

 

- setTimeout(): 코드와 시간을 인자로 받아 일정 시간이 지나면 코드가 실행되도록 처리하는 함수. 이걸 사용자 입력값으로 처리할까 싶긴 한데... 혹시 모르니.

<!--http://domain/?=alert(1) 요청 시-->
<script>
  var delay = loaction.search.split('=')[1]; <!--퀴리의 =뒤 데이터 저장-->
  setTimeout(delay, 2000); <!--2초 후 alert(1) 실행-->
</script>

 

- 입력 값을 속성에 삽입: input 태그의 value 등에 삽입할 때도 있는가 봄.

<!--http://domain/?mod=alert(1) 요청 -->
<script>
var search = (new URLSearchParams(window.location.search)).get('mod'); <!--alert(1)저장-->
document.getElementById('target').setAttribut("onclick",search); 
<!--id가 target인 요소가 클릭되면 <button id="target" onclick="alert(1)">돼서 스크립트 실행-->
</script>

 

 

   웹 사이트가 사용자의 어떤 정보를 이용하여 동적으로 처리하는지에 따라 발생 포인트가 다양함. (쿠키 데이터를 이용하는 사이트라면 쿠키 변조로 스크립트를 삽입할 수 있고, 입력값을 만약 이벤트 핸들러에 넣으면 그 이벤트 발생 시 의도한 스크립트가 실행되도록 할 수도 있다. 아무튼 사이트를 잘 파악하는 게 중요하다.)

 

  • 공격자 입장: url 파라미터를 DOM으로 처리하는 곳 확인
  • 피해자 입장: 링크 클릭하여 스크립트가 포함된 페이지 요청

 

 

 

 

 

                                                                                      XSS 대응 방법                                                                                           

 

 

   어떤 문자를 못 쓰게 하거나(blacklist filtering) 어떤 문자만 쓰게 하는 방법(whitelist filtering)은 한계가 있고 우회할 가능성이 크다. 그래서 단순 필터링보다 더 확실한 방법으로 html 엔티티로 치환하는 방법을 사용한다.

 

  특수문자를 HTML entity로 치환      

 

스크립트 코드를 삽입할 때 사용하는 특수문자 <. ', ", > 등을 html 엔티티 표현으로 치환시키는 방법이 있다.

특수문자 < ' " >
HTML entity &lt; &apos; &quot; &gt;

 

예를 들어 <script>alert(1)</script> 라는 입력값을 서버에서 HTML entity로 치환시키고 있다면

브라우저는 &lt;script&gt;alert(1)&lt;/script&gt;을 받지만 화면에는 <script>alert(1)</script> 그대로 출력시키게 될 것이다.

 

 

 

단지 특수문자가 HTML 엔티티로 치환됐다는 이유로 스크립트는 실행되지 않는다.

 

이걸 입출력하는 위치에 적용하면 된다.

근데 속성에 스크립트 삽입할 때라든지 꺽쇠 없이 자바스크립트를 실행시킬 수 있는 위치는 필터링을 이용하는 것도 좋은 방법일 것이다.

 

더하여 CSP (Content-Security-Polity 콘텐츠 보안 정책)을 적용하는 방법도 있는 것 같다.

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">

 

csp

 

 

 

 

정리

   XSS 공격은 클라이언트 측 스크립트를 삽입하여 사용자의 브라우저에서 스크립트가 실행되게 하는 해킹 기법으로, 스크립트를 사용자에게 노출시키는 방법에 따라 Stored XSS, Reflected XSS, 그리고 DOM Based XSS로 나누어 설명할 수 있다.

 

   Stored XSS 공격은 악성 스크립트가 저장된 페이지를 요청할 때 발생하는데, 이를 위해 공격자는 스크립트를 서버에 저장한다.

   Reflected XSS 공격은 스크립트가 포함된 url 링크를 잠재적 피해자가 클릭할 때 발생하는데, 이를 위해 공격자는 url 파라미터를 페이지에 그대로 출력(반사)시키는 곳을 이용하여 공격한다.

   마지막으로 DOM Based XSS 공격은 Reflected XSS 공격과 유사하게 스크립트가 파함된 url 링크를 클릭하여 요청할 때 발생하는데, 이때 전달되는 파라미터는 클라이언트 측 스크립트에 의해 사용자 브라우저에서 생성된다.

 

   클라이언트 측 스크립트를 사용한다는 것은 피해자가 클라이언트, 사이트 사용자라는 뜻이다. 공격자는 스크립트 코드를 이용하여 사용자의 쿠키를 탈취할 수 있고 이를 이용하여 개인정보를 탈취하거나 사이트의 자원을 착취할 가능성이 있다. 이를 막기위해 웹 애플리케이션 방화벽에 의한 탐지 및 차단, 입출력 데이터의 특수문자를 HTML 엔티티로 치환하는 등의 방식으로 대응하면 더 안전한 시스템을 구축할 수 있을 것이다.