Stored XSS
이번에 알아볼 것은 Stored XSS, 저장형 XSS 공격이다.
저장된다는 것만 빼면 뭔가 Reflected 하고 큰 차이가 있나?? 싶기도 하지만 공격의 단계나 미치는 영향에 있어서 많이 차이가 있다. 아래는 Reflected XSS!
Reflected XSS
Stored XSS에 대해 먼저 올리고자 했으나 비교 설명하기에 Reflected를 먼저 작성하는게 좋아서 올린다! 해석하자면 반사형 XSS로 해석할 수 있겠으나 이러면 무슨 공격인지 느낌이 잘 오지 않는다. XSS
ragdo11.tistory.com
Reflected는 공격을 하기 위해 victim이 링크를 클릭하게 만들어야 하니 사회공학적인 방법이 사용되었으나 Stored는 그런 일련의 과정들이 전혀 필요하지 않다.
우선 Stored XSS 공격의 단계를 살펴보자면 악의적인 사용자가 먼저 XSS 공격을 서버에 저장한다. 일반 사용자가 취약한 페이지를 보기만 하면 XSS 공격이 저장된 웹이 사용자에게 악성 스크립트와 함께 response 해주고, 이 악성 스크립트가 실행이 되어 악의적인 사용자가 쿠키나 세션 토큰값을 받아올 수 있게 된다.
일반적으로 Reflected보다 Stored XSS 공격이 훨씬 위험하다고 여겨지는데 이유는 다음과 같다.
1. XSS 공격이 서버에 저장되므로 사용자가 링크를 누르게끔 유도할 필요가 없다.
2. 취약한 페이지가 인증된 사용자만 접근할 수 있기 때문에 (회원 게시판) 사용자는 공격이 일어나기 전 인증이 되어 있다.
3. 취약한 페이지를 방문하는 모든 사람들에게 공격이 가해진다.
4. 한 번만 일어나지 않고 해당 페이지가 호출될 때마다 실행된다.
5. Reflected는 브라우저 자체에서 차단하는 경우가 많다.
Stored XSS! dvwa에서 실습해보자!
올린 글이 저장되는 환경이다.
글을 올려주는 김에 XSS를 하기 전에 자주 사용되는 특수문자들이 어떻게 처리되는지 확인해준다.
Security level을 low로 설정해놔서 정말 그대로 처리된다. POC 코드를 삽입하여 이곳에 XSS 취약점이 있다는 것을 보여준다.
들어갈 때 마다 계속 alert 창이 뜬다. 이게 정말 기초적인 Stored XSS라고 생각하면 된다.
Stored XSS는 악성 스크립트를 저장하는 형태의 공격이므로 게시판에 악성 스크립트를 삽입해 올려놓는 공격이 대표적이라 할 수 있다.
우선 위와 같이 업로드를 해서 제목과 내용이 어떠한 형태로 저장이 될 지 살펴본다.
글이 성공적으로 업로드 되었다. 우선 제목이 게시판에 보이므로 burp로 확인해준다.
게시판 메인 사이트에서는 위와 같은 형태로 저장 중이다. 다음으로 작성한 글을 클릭해보자.
우선 제목은 보이지 않으며 사용자가 입력했던 글 내용만 content 박스에 담겨져 나와 있다. 이 역시 burp로 확인해보면
input 태그에 value라는 값으로 저장이 되고 있음을 확인할 수 있다. 이제 제목과 내용에 XSS 취약점을 확인하기 위한 특수문자를 집어넣어 본다.
제목과 내용 모두 특수문자가 어떠한 처리 과정없이 그대로 응답값에 출력되는 것을 볼 수 있고, 특히 content 부분에서는 특수문자로 인해 뒤의 " disabled>가 혼자 남는 것을 볼 수 있다.
실제로 ragdo11<' 까지만 보이고 뒤의 ">은 구문으로써 처리가 되었고, 뒤의 " disabled>만 남아 있어서 이상하게 출력되는 모습이다.
이제 실제로 Stored XSS 공격을 테스트해보자.
먼저 제목에 POC 코드를 저장하여 게시판 메인 사이트로 접속할 때마다 alert가 뜨게 할 것이다.
게시판 사이트 접속 시 alert가 뜨는 것을 확인할 수 있다.
burp로 패킷을 보면 test 제목 뒤에 script문이 그대로 들어가 응답 페이지가 전달될 때 alert문이 실행되는 것을 볼 수 있다.
이번엔 제목이 아닌 내용 부분에 스크립트를 작성해본다.
이번엔 제목에 스크립트를 넣을 때와는 다르게 앞뒤로 뭐가 좀 있다. 아까 제목 때는 고려해야할 태그가 없었지만 본문 같은 경우 아래와 같이 코드가 작성되어 있기 때문에 일부러 input 태그를 닫아주기 위해 ">로 끝내주고 script 문을 삽입해준 후, 뒤에 남은 disabled>를 위해 input 태그를 다시 열어준 방법이다. 굳이 이렇게 열어주지 않고 대충 script 문만 삽입해줄 수는 있지만 그러면 에러가 나는 경우가 있어서 최대한 맞춰주는게 좋다.
참고로 document.cookie은 현재 페이지의 쿠키 값을 가져온다.
아래는 스크립트 삽입 후 코드
스크립트문이 정직하게 응답값에 출력되어 나왔다.
결과는 위와 같다.