저 개인적으론 Js 코드 탈출 이후 특수문자~문자열 등 원하는 구문 삽입이 어려울 떄 종종 사용하는 방법입니다.
// alert(1)
this[(+{}+[])[+!![]]+(![]+[])[!+[]+!![]]+([][+[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]](++[[]][+[]])
// alert(1)
this[(+{}+[])[-~[]]+(![]+[])[-~-~[]]+([][+[]]+[])[-~-~-~[]]+(!![]+[])[-~[]]+(!![]+[])[+[]]]((-~[]+[]))
필터링 규칙에 따라 페이로드를 숨기는 방법이 여러가지가 있지만 이 방법은 [ ] ( ) + ! 등으로만 코드를 구성할 수 있기 때문에 때에따라 요긴하게 사용되기도 합니다.
그냥 Js가 동작할 수 있는 하나의 구문이구나 하고 넘기고, 테스트할 때 사용하기만 했었느데 오늘은 어떻게 저런 코드가 동작할 수 있는 코드가 되었는지 정리해볼까 합니다.
What is JSFuck?
처음 제가 저 코드를 봤을때 생각났던게 바로 "아희"같다 라는 느낌이였습니다. (물론 실제로 아희로 코딩하진 않아요... 예전에 지인들끼리 신기한언어다 정도만 이야기하고 해본...)자세한건 나뮈위키 보시죠..(https://namu.wiki/w/아희)
helloworld..
뱔뿌둬뱺쀠더빠뚜
터벚봃떠빠뷹붏뼤
나퍄따쀄븈뵳두받
붏타볻뚜벓탸볐밢
떠볽뻐뷦투희맣어
정말 난해한 언어지요? 이렇게 난해한 언어가 여러가지가 존재하며 쭉 이어져오고 있습니다. JSFuck(아래부턴 JF라고 하겠습니다)도 이런 언어들 중 하나입니다.
Martin Kleppe가 만든 난해한 스타일 언어이며 별도의 컴파일러, 인터프리터 없이 Javascript engine 으로 동작 가능한 언어입니다.
알파벳 없이 아래 특수문자들로만 코드를 작성할 수 있고 각 문자나 기호를 저런식으로 표현할 수 있습니다.
<(,), [, ], +, !.
문자 JF
+ => (+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]])+[])[!+[]+!+[]]
. => (+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]
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"]( CODE )()
window => []["filter"]["constructor"]("return this")()
이를 이용하면 위에서 보셨던 payload 구성이 가능해지는거죠. 이외 코드를 참조하시려면 아래 git 에서 확이하시면 편합니다. https://github.com/aemkei/jsfuck/blob/master/jsfuck.js 어떻게 동작하지?
가장 궁금증이 든 부분은 바로 이거입니다. Javascript에서 의도한 언어 포맷은 아닌데 어떻게 동작할 수 있을까입니다. 알고보니 생각보다 심플했는데, JS 자체의 기능들을 이용해서 문자를 만들고 더해 Javascript 구문으로 사용하는 것이였습니다. 대표적인게, 괄호를 문자열로 바꾸는 방법입니다. [] +[] // "" - empty string
+[] +[] // "0"
[][[]] +[] // "undefined"
++[][[]] +[] // "NaN
++[[]][+[]] +[] // "1"
10["toString"](36) // "a"
11["toString"](36) // "b"
...
34["toString"](36) // "y"
35["toString"](36) // "z"
"undefined" [ 0] // "u"
[ "undefined" ][ 0][ 0] // "u"
[ undefined +[] ][+[]][+[]] // "u"
[ [][+[]] +[] ][+[]][+[]] // "u" => 풀어서 보면 [ [][+[]] +[] ] 의 [0][0] 값, 즉 u를 가져오도록..
숫자도 가능하겠지요 true >> false // 1
true << true // 2
true << true << true // 4
타입은 이렇게 가능합니다. 이거 보니깐, alert 우회패턴들 생각나네요(이런 방식으로 만든) 0 ["constructor"] // Number
"" ["constructor"] // String
[] ["constructor"] // Array
false ["constructor"] // Boolean
[].find ["constructor"] // Function
이외에는 많은 방법들이 있으며 아래 링크들 참고하시면 도움됩니다.https://github.com/aemkei/jsfuck
https://gitter.im/aemkei/jsfuck
https://ko.wikipedia.org/wiki/JSFuck

![]() |
HAHWULSecurity engineer, Gopher and H4cker! |
0 개의 댓글:
Post a Comment