XSS Filter Bypass
워게임을 풀다보면 다양한 키워드 필터링을 만나게됩니다.
공부하다보니 필터링을 우회하는 법이 되게 다양하다는걸 알게되어, 까먹지 않기 위해 글로 적어서 남겨볼까합니다.
이 글은 자바스크립트를 이용하는 공격인 XSS 에 대한 필터링 관련 내용입니다.
자바스크립트 필터링에 대해서 적어볼 예정입니다.
1. 유니코드를 활용한 우회
자바스크립트는 문자열에 유니코드 문자를 코드포인트로 나타낼 수 있는 표기법을 지원합니다.
즉 a를 유니코드 "\u0061"로 적어도 a로 인식한다는 거죠.
예로 "document"라는 키워드를 필터링한다고 할 때, d의 유니코드인 "\u0064"를 사용하여 "\u0064ocument"라고 적을 수 있습니다.
이러면 "document"라는 고정 키워드 필터링은 우회하되, 서버는 유니코드를 해석하여 document 그대로 받아드리게 됩니다.
2. 대체 구문과 동적 접근 활용
동적 접근
동적 접근이란 객체 속성에 계산식이나 변수값을 통해서 접근하는 기능입니다.
obj.key나 obj["key"] 로 표현하는게 여기에 해당됩니다.
자주 쓰는 document.cookie도 동적 접근을 활용한 구문이되네요.
이 동적접근 기능에서 유용하게 사용할만한 기능이 또 있습니다.
예로 cookie라는 키워드가 필터링 중이라면,
document["coo"+"kie"] 로 표현하여 우회할 수 있습니다.
즉 두 문자열로 쪼갠 후 합쳐줘도 서버에서는 저걸 document[cookie]로 해석하게됩니다.
document.cookie와 같은 말이고 필터링은 우회가 됩니다.
여기에 유니코드를 활용한 우회를 섞어서 더 변형할 수 있습니다.
예) document["\u0063oo"+"k\u0069e"]
window와 self, this
추가로 필터링 된 구문을 대체하는 구문을 사용하여 우회할 수 도있습니다.
alert나 document등이 필터링 중일 때 window를 사용하여 우회할 수 있습니다.
window['ale'+'rt'](1) 이런 구문은 alert(1)과 동일하게 동작하게됩니다.
window가 필터링이라면, 같은 역할을 하는 self나 this로 대체하여 우회해 볼 수 도있습니다.
eval()
eval()같은 함수를 사용하여 우회하는 페이로드도 자주 보입니다.
eval()은 전달된 문자열을 자바스크립트 코드로 해석하여 실행하는 함수입니다.
때문에 필터링에 들어가 있는 경우가 문제마다 보이는데,
eval(payload)의 형태 대신 Function(payload)() 의 형태로 대체가 가능합니다.
Function()
위에서 보았듯 Function을 사용하여 코드를 실행 시킬 수 있습니다.
Function마저 필터링 됬을 경우 자바스크립트 함수의 constructor 속성에 접근하여 이를 우회할 수 있습니다.
예) Boolean['constructor']('alert(document.cookie)')()
3. ", ', ` 우회
XSS 페이로드를 작성하다보면 문자열을 만들어야하는 경우가 많습니다.
주로 "나 '를 사용하지만 따옴표가 막혔다면 백틱(`)을 사용하여 문자열을 만들 수 도있습니다.
하지만 이 모든 방법이 다 막혔을 때도 있는데, 그럴때 역시 문자열을 만드는 방법이 존재했습니다.
RegExp 객체를 사용하여 문자열 만들기
RegExp는 문자열 패턴을 정의하는 객체 입니다.
패턴 매칭, 검색, 치환 등으로 사용되는 도구지만, 문자열을 만드는데 사용할 수 도 있습니다.
예) /hello/.source; === "hello"
자바스크립트 형 변환 규칙을 활용하여 문자열 만들기
자바스크립트엔 형 변환 규칙이 있습니다.
서로 다른 형태의 피연산자가 연산이 될 때 다른 한쪽의 형태가 변하는 규칙입니다.
예로 문자열 + 배열의 형태를 띄면, 배열이 문자열로 치환되면서 문자열 결합이 일어납니다.
문자열과 숫자의 결합도 마찬가지입니다.
다만 '-'나 '%'같은 숫자 연산자가 사용되면, 문자열 - 숫자일 시 문자열이 숫자로 바뀌게 됩니다.
이 중 더하기(+)연산자를 활용하여 문자열을 만들어 낼 수 있습니다.
"문자열" + [] 같은, 문자열+배열의 형태를 사용하면 따옴표와 같은 효과를 낼 수 있습니다.
괄호 필터링 우회법
가장 신기했던 우회법 중 하나입니다.
핵심은 내장 함수나 객체를 문자열로 변경하게되면, 함수나 객체의 형태가 문자열로 변환됩니다.
이렇게 얻은 문자열을 배열로 묶어서 한 글자 한 글자 가져올 수 있는데, 여기서 괄호를 뽑아내서 사용하는 방법입니다.
위에서 형 변환 규칙에 대해 설명할 때, 문자열과 빈 배열을 더하면 문자열이 된다고했습니다.
비슷하게 함수와 빈 배열을 더하면, 함수의 내용이 문자열이 됩니다.
예로 history라는 내장 함수가 있습니다. 이 내장 함수에 + []로 빈 배열을 더하게되면 "[object History]" 라는 문자열을 반환합니다.
이 문자열을 배열로 묶어서 원하는 글자를 빼낼 수 있는겁니다.
예) (history+[])[2] === "b" // [object History]의 3번째 (0부터 시작이므로)인 "b"를 반환
URL이라는 내장함수가 있습니다.
이 함수를 .toString()이나 빈 배열을 더하는 등 문자열로 바꾸면 "function URL() { [native code] }"라는 문자열을 반환합니다.
이걸 위에서 처럼 배열로 묶어서 소괄호와 중괄호를 얻을 수 있습니다.
예)(URL+[])[12] === "(", (URL+[])[13] === ")"
굳이 배열이 아닌 숫자를 문자열에 더해도 숫자가 문자로 치환되면서 문자열의 끝에 붙에 됩니다.
예) URL+0 === "function URL() { [native code] }0"
'보안 > 이론 정리' 카테고리의 다른 글
| 웹 해킹 - SQLi UNION에 대하여 (0) | 2026.02.11 |
|---|---|
| 웹 해킹 - PHP output buffer overflow (0) | 2025.12.04 |
| 스프링부트 - URL 매핑과 컨트롤러 (0) | 2025.10.03 |
| 웹 해킹 - 직렬화와 역직렬화 (0) | 2025.09.25 |
| 웹 해킹 - URL 필터 우회 (0) | 2025.09.23 |