web_security/web info

[WebHacking] XSS (Cross Site Scripting) 란?(New)

HawordFREAKEK 2022. 5. 29. 16:53

네 안녕하세요. Godhaword입니다.
Web Hacking에 대한 것은 XSS부터 Sql injection 까지 한 번씩 정리한 적이 있는데요. 그 글을 쓴 지 약 2~3년 이란 시간이 지났습니다.
이 전에 글을 쓸 당시에는 학생이였으며 CTF나 wargame으로만 해당 지식을 접하며 응용해왔고, 지금은 실무경험도 쌓아보며 짧지만 저만의 노하우로 진단 및 점검을 하고 있습니다.
이번에 새롭게 쓰는 글은 제목에 New라고 추가하여 적으며, 전에 썼던 글을 크게 고려 안하고 그냥 지금 제가 생각하는 바를 새롭게 쓰기에 그것과 많이 겹칠 수도 아니면 결이 많이 다른 글이 써질 수도 있는 점 참고 부탁드립니다.

 

목차는 

1. XSS (Cross Site Scripting) 란?
2. 3종류의 xss?
3. XSS 공격 예제
4. XSS 조치 방법

이렇게 있으므로 궁금하신점 먼저 찾아보셔도 좋을 것 같습니다.


1. XSS (Cross Site Scripting) 란?

몇 번의 검수를 통하여 그 뜻과 말하고자하는 바가 크게 다르지 않으면 나무위키 자료를 인용할 생각입니다.(나무위키)

 

SQL injection과 함께[2] 웹 상에서 가장 기초적인 취약점 공격 방법의 일종으로, 악의적인 사용자가 공격하려는 사이트에 스크립트를 넣는 기법을 말한다. 공격에 성공하면 사이트에 접속한 사용자는 삽입된 코드를 실행하게 되며,[3] 보통 의도치 않은 행동을 수행시키거나 쿠키나 세션 토큰 등의 민감한 정보를 탈취한다.

 

위 글에선 SQL Injection(이하 : SQLI)과 함께 웹에서 가장 기초적인 취약점 공격 방법이라 합니다.
이렇게만 보면 "아 sqli랑 xss랑 비슷비슷한 공격이구나"라고 생각할 수 있어 약간의 추가되어야 할 말이 있어보입니다.

최근들어 XSS와 SQLI를 비슷하거나 같은 위험도, 난이도로 보는 분들이나 글이 있어 잠깐 적어보자면,

 

1. 두 공격은 최종 공격 목적이 다릅니다.

 1) xss와 같은 경우 많이 아시는 바와 같이 쿠키 및 세션 탈취가 대표적인 공격 목적입니다.
조금 더 나아간다면 공격자가 원하는 사이트로 리다이렉트 및 특정 스크립트문 실행 가능하게 합니다.
피해자를 짐작해보면 해당 xss문이 저장되어있는 게시글을 조회한 사람으로 한정 지을 수 있습니다.
그렇기에 게시글을 조회하지 않은 유저나 계정이나 정보는 있지만 해당 서비스를 사용하지 않는 사람에게 까지는 피해가 가지 않습니다.

하지만 SQLi 같은 경우 공격이 성공한다면 피해자가 어떤 행동을 하지 않아도, 쿼리문을 주입할수만 있다면 모든 유저정보를 포함한 모든 database의 내용을 조회할 수 있습니다.
그리고 만약 서비스를 개발할 당시 만들어두었던 admin 관련 주소, 포트번호, 해당 계정정보와 같은 backup data를 database 에 저장해둔다면 추가적인 2차 피해까지 만들어 낼 수 있습니다.(아마 다음 글로는 SQLi를 정리해야겠네요..)

2.  두 공격은 공격 성공 난이도가 다릅니다.

1) XSS와 같은 경우 공격문을 입력해보면 바로바로 서비스에 피드백으로 공격성공 유무와 어떻게 해당 서비스에서 공격문을 필터링하는지 조회까지 가능합니다.

하지만 SQLi는 ', ", %, '', "", %', %'' 이런 것과 같이 어떤 문자로 쿼리문을 닫고 %00, --, # 과 같이 어떤 문자로 주석처리를 하며 해당 서비스가 MSSQL, ORACLE, MYSQL, POSTGRE 와 같이 어떤 DB서비스를 사용하고 있는지 완벽히 알아야 한 줄의 공격 쿼리를 만들어 낼 수 있기 때문에 시도 난이도 조차 다르다고 생각합니다.

 

뭐가 어렵다, 뭐가 위험하다는 지극히 개인적인 의견이며 XSS를 통하여 ADMIN 및 DEV, SUPER, SYSTEM 권한을 가진 계정의 쿠키 값이 탈취되고, 만약 그 쿠키값으로 ADMIN PAGE에 접근이 가능하다면 SQLI 없이도 DB탈취를 할 수 있는 가능성이 생깁니다.

개인적으로 XSS<=SQLI 라고 생각합니다.

 

2. 3종류의 xss?

2019년 9월 작성했던 글입니다. 점검을 하다보니 저기에 있는 2번 Stored XSS 빼고는 별로 쓸일이 없었습니다.

저 3개를 다시 짧게 설명해드리자면,

1. Reflected XSS : 검색창 같은 곳에 XSS를 주입하여 악의적인 XSS문 실행
2. Stored XSS : 게시글에 XSS를 주입하여 타 사용자가 해당 게시글을 조회 시 XSS문 실행
3. DOM XSS : 꼭 알아야하나 싶은 XSS

이렇게 되겠네요.

일단 글에서 써드린것과 같이 3번은 별로 신경 안써도 될 정도의 XSS라고 보여집니다.
1번과 같은 경우는 말 그대로 공격자 본인이 XSS문 써넣고, 다시 사이트 html문이 구성될 때 그때만 공격 XSS문이 실행되므로 타 사용자에게 별 위험이 되지 않는 공격이라 생각됩니다.
하지만 2번과 같은 경우는 특정 글에 공격 XSS 문을 Stored 시킨다면 해당 글을 조회하는 유저의 쿠키 및 세션 값을 다 탈취 할 수 있으며, 혹시라도 공지 게시판의 제목 부분에서 XSS 공격이 성공한다면 무차별적인 해당 서비스를 이용하는 모든 유저의 쿠키 및 세션값을 탈취할 수 있게 됩니다.

대부분의 wargame이나 CTF는 1번 공격으로 많이 사용합니다. 그런데 XSS문제가 그렇게 많이 나오지도 않습니다.

 

3. XSS 공격 예제

1

 

일단 XSS를 하기 위해선 게시판이건 입력창이건 뭐라도 있어야 합니다.
입력창이 있으면 Reflected XSS를 할 수 있고, 게시판이 있으면 Stored XSS를 실행해볼수 있습니다.
일단 입력창이 있으니까 대충 Reflected XSS라고 생각하고 간단한 XSS문을 넣어보도록 하겠습니다.

2

 

바로 XSS문이 성공하며 다음 단계로 넘어갈 수 있는 것을 보실 수 있습니다.
예전엔 XSS문을 외우고 다니진 않았는데 기본적으로

1.

<script>alert(document.cookie)</script>

2.

<image/src/onerror=prompt(document.cookie)>

이렇게 두 문장은 외워서 쓰시는 것을 추천드립니다. 진단할때나 CTF 문제풀때 간단하게 공격성공 유무 체크나 필터링 체크할때 쓰기도 좋고 시간도 많이 아껴줍니다.

https://github.com/payloadbox/xss-payload-list

더 자세한 공격구문은 위 github을 참고하시면 좋을 것 같습니다.
(사실 모든 XSS문을 외우는 것보다 그때그때 맞는 XSS문을 어디서 참고하고 복붙해서 쓰는게 더 좋아보입니다..)

 

※ 주의

<script>alert(document.cookie)<script>

위와 같이 닫는 스크립트 언어에 /가 빠질 경우 XSS 공격문 이후의 html 상 코드가 작동을 안할 수 도 있습니다.
항상 공격을 하심에 있어서 공격이 성공했나보다 장애가 날까 안날까를 먼저 생각하시면서 공격문 작성하시길 바랍니다.
중간의 공격문에 오타나 문제가 있으면 삭제/수정을 통하여 고칠 수 있지만, 뒤에 닫는 스크립트 </script>를 빼먹으신다면 최악의 경우 서비스 대상의 서비스 장애를 유발할 수 있어 사용에 각별히 주의하시길 바랍니다.(블랙 해커도 이렇겐 공격 안할 듯 싶네요.. 멋이 안나가지고..;;)

4. XSS 조치 방법

1. 필터링

1) 필터링이 XSS 방어에 거의 모든 것이라고 보여집니다.
대표적으로 <,> 와 같은 XSS문의 시작과 끝을 &lt;, &gt; 와 같이 수정해주면 공격자 입장에선 뭐 할께 없습니다.

2) 꺽쇠가 아니여도 <script> 이렇게 들어오면 <sc-ript> 와 같이 필터링을 할 수 있습니다.
하지만 XSS문이 모두 <script>로 시작하는것도 아니고 onclick, onerror, prompt와 같이 여러가지의 시작점을 가질 수 있으므로 그냥 꺽쇠 필터링이 가장 맘 편하다고 생각됩니다.

2. 태그 추가

1) <a>(입력받은 제목이나 내용)</a> 과 같이 겉에 태그를 하나 감싸면 시작과 끝 안에 있는 문자는 그냥 문자열로 판단하기에 XSS문이 터지지 않습니다. 하지만 서비스 내용과 버전 몇가지 조건으로 인하여 공격자가 고의로 </a> 와 같은 내용을 공격구문에 넣었는데 그걸로 위 조치 방법이 통하게 될 수 있으므로 이 방법을 사용할 시에는 자체적으로 한번 테스트 하는것도 좋다고 생각됩니다.

2) " (입력받은 제목이나 내용) " 이렇게 데이터를 받는 곳도 봤는데 쌍따옴표로 구문을 닫아주고 XSS문을 넣거나 --> 와 같이 주석으로 날려버리거나 하는등의 여러가지 방법을 시도해볼수 있습니다.

3. 모든 문자 파편화

대회문제를 풀거나 진단하면서 몇 번 못보긴 했는데 hello 이렇게 입력시

"h",
"e",
"l",
"l",
"o"

이렇게 치환하여 정보를 뿌려주는 게시판도 있었습니다. 해당 방식과 같은 경우 XSS문을 넣더라도 모든 글자가 파편화 되어 날라가기에 공격하기 까다롭게 느껴졌습니다.

 


XSS는 공격하기 쉬운만큼 방어하기도 쉬운 기법입니다.

개발자 입장에서 서비스를 open 하기전에 직접 XSS문을 몇개 넣어보는것 만으로도 자가진단을 해볼 수 있습니다.
(공격하기 어려워 보이면 그냥 XSS payload라고 깃헙에 치고 A to Z 다 복붙해봐서 쳐보기만 해도 방어가 충분히 됩니다.)

 

혹시 추가적으로 궁금하신점 있으시면 댓글 부탁드립니다.