Search

XSS-Game Level 6: Follow the 🐇

목표 : Data URIs data:javascript,alert(1) / JSONP callback=foo

임무 설명

복잡한 웹 애플리케이션에는 때때로 URL 매개변수 또는 location.hash의 일부 값을 기반으로 JavaScript 라이브러리를 동적으로 로드하는 기능이 있습니다.
이는 제대로 하기가 매우 까다롭습니다. 스크립트 또는 XMLHttpRequest와 같은 기타 잠재적으로 위험한 유형의 데이터를 로드할 때 사용자 입력이 URL에 영향을 미치도록 허용하면 종종 심각한 취약점이 발생합니다.

(원문) Mission Description

임무 목표

응용 프로그램이 alert()를 실행하도록 하는 외부 파일을 요청하도록 하는 방법을 찾으십시오.

(원문) Mission Objective

Your Target

Target Code

gadget.js

index.html

level.py

문제 풀이

gadget.js를 로딩할 수 없다고 한다.
주소를 보면 #으로 분할돼있어 window.location.hash 값 default 값이 /static/gadget.js 인걸 알 수 있다.
windows.location.hash에 대한 설명은 3번 문제에서 다뤘다.
#뒤 인자를 test 로 바꿀경우 다음과 같이 바뀌는걸 확인할 수 있다.
그럼 디폴트 js 파일은 어떤 내용인지, 그리고 나머지 코드는 어떤지 확인하자.
# gadget.js /* This is a completely awesome invisible gadget */
JavaScript
복사
실제로 해당 gadget.js 파일은 주석 외에 아무런 내용도 없다.
# index.html 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); }
JavaScript
복사
다른 인자를 넣을 부분이 없나 코드를 해석해봤다.
url은 https:// http:// 를 뒤 내용에 사용할 수 없게하고, 가젯 로딩 성공 실패 여부에 따라 로그를 출력한다.
코드 내에서 특이사항은 없었고 URL 내 window.location.hash값에 있는 파일에 접근하는 메커니즘이다.
즉 해당 경로, URL 자체에 javascript 파일을 포함시킬 수 있다면 해결되는 문제다.

Data URIs

data: 스킴이 접두어로 붙은 URL은 컨텐츠 작성자가 작은 파일을 문서 내에 인라인으로 삽입할 수 있음
data:[<mediatype>][;base64],<data>
Plain Text
복사
mediatype이란, MIME 타입을 말한다(JPEG 이미지의 경우 'image/jpeg'). 만약 생략된다면, 기본 값으로 text/plain;charset=US-ASCII이 사용된다.
간단한 text/plain 데이터
data:,Hello%2C%20World!
위 예제의 base64 인코딩 버전
data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D
<h1>Hello, World!</h1>인 HTML 문서
data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E
자바스크립트 alert 실행 문서
data:text/html,<script>alert('hi');</script>
data:,alert(1)
data:javascript,alert(1)
위 방식을 사용하면 쉽게 해결할 수 있다.

다른 풀이 - JSONP(JSON with Padding)

힌트에서 https://google.com/jsapi?callback=foo를 사용하라고 안내하고 있어서 찾아봤다.
JSAPI(JavaScript API) 서비스를 사용하여 Google 서버에서 JavaScript 파일을 요청하는 URL로 callback=foo 매개변수는 요청된 JavaScript 파일이 로드되었을 때 호출되어야 하는 함수의 이름을 지정한다. foo의 값은 파일이 로드되었을 때 실행하려는 함수의 이름이 된다.
JSONP는 원격 스크립트 파일의 URL과 함께 HTML 문서에 <script> 태그를 삽입하여 작동하게 되는데 원격 서버는 callback 매개변수에 지정된 이름으로 함수 호출에 래핑된 요청된 스크립트를 반환하고 브라우저가 자동 실행하게 된다.
좀 더 개념을 잡기 좋은 글은 다음 링크에 정리돼있다.
원래 callback에 aaaa…aa 가 들어가면 이에 해당하는 함수명이 리턴돼야하는데 작동하지 않는다. 오래돼서 패치된건지 방법이 잘못된건지는 모르겠다.
다른 블로그 게시물(https://code1018.tistory.com/119)을 참조하면 alert로 넣으면 alert 함수가 실행이 되고 이러한 리턴 값을 활용할 수 있다.
http://https:// 는 필터링 되고 있으므로 대소문자를 바꿔 HtTp:// 와 같은 형태로 바꾸면 실행이 가능하고 alert 함수가 실행되는 것을 확인할 수 있다.

✓ XSS Game

✓ 다른 [워게임] 포스트

WebHacking.kr Challenge Write-Up (70/80)
In progress
WebHacking.kr Challenge Write-Up (70/80)
In progress
Load more
︎ 더 많은 게시물을 보려면
︎ 작성자가 궁금하면?
 2023. absolroot all rights reserved.