개요
DOM(Document Object Model)은 웹 페이지에 대한 인터페이스로 콘텐츠, 구조, 스타일을 읽고 조작할 수 있는 API를 제공합니다.
이러한 DOM은 W3C의 표준 객체 모델이며, 계층 구조로 구성됩니다.
DOM은 원본 HTML과 구조가 비슷하지만 몇 가지 차이점이 있습니다.
1. 항상 유효한 HTML 형식입니다.
DOM은 유효한 HTML 문서의 인터페이스로써, DOM을 생성하는 동안 브라우저는 유효하지 않은 HTML 코드를 올바르게 교정합니다.
아래의 코드는 필수 태그인 <head>와 <body>가 빠져있습니다. 그렇지만 생성된 DOM 구조는 올바른 HTML 형식으로 수정되어 구성됩니다.
<html>
hacksms.tistory.com
</html>
2. 자바스크립트에 수정될 수 있는 동적 모델이어야 합니다
DOM은 HTML 문서의 내용을 볼 수 있는 인터페이스 역할을 하는 동시에 동적 자원이 수정될 수 있어야 합니다.
아래와 같은 Javascript를 통해 DOM에 새로운 노드를 추가할 수 있습니다.
var new_Div = document.createElement("div")
var new_Text = document.createTextNode("hacksms.tistory.com")
new_Div.appendChild(new_Text)
document.body.appendChild(new_Div)
3. 가상 요소를 포함하지 않습니다.
DOM은 가상 요소를 포함하지 않습니다. CSS의 ::before, ::after 선택자와 같은 가상 요소는 DOM에 포함되지 않기 때문에 Javascript에 의해 수정될 수 없습니다.
4. 보이지 않는 요소를 포함합니다.
View Page에 보이는 것은 렌더 트리로 DOM과 CSSOM의 조합이며, 렌더 트리는 오직 화면에 보이는 것으로만 구성되어 있어 DOM과 다릅니다.
<html>
<head></head>
<body>
<p>Hello World</p>
<p style="display: none;">hacksms.tistory.com</p>
</body>
</html>
참고 링크
DOM Clobbering XSS
앞서 DOM은 페이지의 콘텐츠, 구조, 스타일을 Javascript를 통해 조작할 수 있는 인터페이스라고 설명드렸습니다.
DOM Clobbering이란 사용자의 입력 값을 통해 특정 태그의 id나 name과 같은 속성을 조작할 수 있을 때, 임의의 DOM 객체를 삽입하는 공격을 의미합니다. DOM Clobbering XSS는 당연히 해당 공격을 이용하여 XSS가 발생하도록 하는 공격입니다.
위의 말만 들어서는 당연히 이해가 안될 거라고 생각합니다. 더 자세히 설명드리겠습니다.
<a id='CONFIG">라는 태그에 javascript를 이용하여 접근하기 위해서는 아래와 같은 2가지 방법이 존재합니다.
document.getElementById("CONFIG")
window.CONFIG
만약, 아래와 같은 코드가 있고 a 태그만을 수정하여 document.write('CONFIG')를 실행시키기 위해서는 어떻게 수정을 해야할까요?
<html>
<a href="#">hacksms.tistory.com</a>
<script>
if(window.CONFIG){
document.write('CONFIG');
}
</script>
</html>
네 맞습니다. 바로 a 태그에 CONFIG라는 id를 할당해주면 됩니다.
<html>
<a href="#" id="CONFIG">hacksms.tistory.com</a>
<script>
if(window.CONFIG){
document.write('CONFIG');
}
</script>
</html>
그러면 아래 사진과 같이 document.write('CONFIG')가 실행되어 HTML 상에서 출력된 것을 확인할 수 있습니다.
DOM Clobbering은 방금 했던 것처럼 사용자의 입력 값을 통해 임의의 DOM 객체를 삽입하여 window.CONFIG와 같이 global 변수를 통해 실행되는 특정 로직을 우회하거나 실행 시킬 수 있는 공격입니다.
그럼 이제 조금 더 공격을 응용해보도록 하겠습니다. 아래와 같은 HTML 코드가 있다면, 어떻게 해야 'Debug On'을 출력시킬 수 있을까요?
<html>
<a href="#" id="CONFIG">hacksms.tistory.com</a>
<script>
if(window.CONFIG.debug){
document.write('Debug On');
}
</script>
</html>
만약, 'CONFIG'라는 Id를 가진 a 태그가 두 개가 되면 어떤 일이 발생할까요? 아래 사진과 같이 2개의 태그가 모두 인식되는 것을 확인할 수 있습니다.
그렇다면 2개의 태그를 구분할 수 있는 방법이 있을까요? 정답은 바로 name 속성을 이용한 방법입니다.
<html>
<a href="#" id="CONFIG" name="test1">hacksms.tistory.com</a>
<a href="#" id="CONFIG" name="test2">hacksms.tistory.com</a>
<script>
if(window.CONFIG.debug){
document.write('Debug On');
}
</script>
</html>
동일한 id 명을 가진 태그는 아래와 같이 name을 통해 구분할 수 있습니다.
위에서 설명드린 방법을 이용하여 'Debug On'이라는 문자열을 출력시킬 수 있었습니다.
<html>
<a href="#" id="CONFIG" name="debug">hacksms.tistory.com</a>
<a href="#" id="CONFIG">hacksms.tistory.com</a>
<script>
if(window.CONFIG.debug){
document.write('Debug On');
}
</script>
</html>
지금까지 DOM Clobbering에 대한 기본적인 내용들은 전부 설명드렸습니다. 이번에는 DOM Clobbering을 이용하여 XSS를 실행시켜보겠습니다.
(참고로 DOM Clobbering을 이용한 XSS가 발생하기 위해서는 특정 조건이 필요합니다. 여기서는 location.href를 통한 내용만 설명드리겠습니다.)
지금까지 배운 내용을 통해서 window.CONFIG.href에 해당 하는 DOM 객체를 생성할 수 있었습니다. 그렇지만 어떻게 window.CONFIG.href에 저희가 원하는 특정 값을 넣을 수 있을까요?
<html>
<a href="#" id="CONFIG" name="debug">hacksms.tistory.com</a>
<a href="#" id="CONFIG">hacksms.tistory.com</a>
<script>
if(window.CONFIG.debug){
location.href = window.CONFIG.href;
}
</script>
</html>
먼저 이 공격을 이해하기 위해서는 2가지 사실을 알아야합니다.
1. javascript에서 String 변수에 Object가 연산될 때는 Object.toString() 함수가 실행된다.
2. a 태그의 toString() 함수는 href 속성의 값을 가져온다.
2가지 사실을 통해 해당 페이지에 접근하는 사용자를 href에 해당하는 URL로 이동시킬 수 있었습니다. 이 방법을 이용하여 우리는 XSS를 발생시킬 수 있습니다.
<html>
<a href="#" id="CONFIG" name="debug">hacksms.tistory.com</a>
<a href="#" id="CONFIG">hacksms.tistory.com</a>
<a href="javascript:alert('XSS');" id="CONFIG" name="href">hacksms.tistory.com</a>
<script>
if(window.CONFIG.debug){
location.href= window.CONFIG.href;
}
</script>
</html>
지금까지 DOM Clobbering과 DOM Clobbering XSS에 대해서 설명드렸습니다. 해당 공격과 관련된 좋은 문제가 있으니 꼭 풀어보시길 권고드립니다.
참고 링크
'Hack > Web' 카테고리의 다른 글
Proxy Setting OnOff bat file (0) | 2021.11.19 |
---|---|
SQL Injection Cheat Sheet (0) | 2021.10.02 |
Padding Oracle Attack (2) | 2021.09.03 |
[KVE-2021-0172,0329,0330] YoungCart 1Day 취약점 분석 (SQL Injection) (0) | 2021.04.19 |
strtoupper를 이용한 XSS 공격 (0) | 2021.01.06 |
댓글