JavaScript는 이상하고 흥미로운 언어이므로 여전히 작동하는 미친 코드를 작성할 수 있습니다. 이는 우리가 사물을 처리하는 방식에 따라 사물을 특정 유형으로 변환하는 데 도움을 줍니다.
문자열을 추가하면 JavaScript는 텍스트 표현을 원한다고 가정하므로 이를 문자열로 변환합니다. 양수 또는 음수 접두사 기호를 추가하면 JavaScript는 숫자 형식으로 표시되기를 원한다고 가정하고 가능하면 문자열을 숫자로 변환합니다. 부정 기호를 추가하면 JavaScript는 문자열을 부울 값으로 변환합니다.
Javascript에서 6개의 기호 [,],(,),!를 사용하여 마법의 코드를 작성할 수 있습니다. 지금 휴대폰을 사용하고 있지 않다면 브라우저의 콘솔을 열고 코드 값이 true인 콘솔에 코드 예제를 붙여넣을 수 있습니다.
기억해야 할 몇 가지 황금률부터 시작하겠습니다.
뒤에 오는 문자는 부울 값으로 변환됩니다.
+ 뒤에 오는 문자는 변환됩니다. 숫자 값으로
[] 뒤에 오는 문자는 문자열로 변환됩니다.
다음 예를 살펴보세요.
![] === false +[] === 0 []+[] === ""
알아야 할 또 다른 사항 즉, 다음과 같이 대괄호를 사용하여 문자열에서 특정 문자를 검색하는 것이 가능합니다:
"hello"[0] === "h"
또한 문자열을 더한 다음 전체 표현식을 숫자로 변환하여 여러 자리 숫자를 표시할 수 있다는 점을 기억하세요. :
+("1" + "1") === 11
우리는 몇 가지를 계속해서 결합하여 문자 a를 얻습니다
![] === false ![]+[] === "false" +!![] === 1 ------------------------ (![]+[])[+!![]] === "a" // same as "false"[1]
비유적으로!
참과 거짓을 통해 비슷한 문자 a, e, f, l, r, s, t, u를 얻을 수 있으니 다른 곳에서도 문자를 얻을 수 있을까요?
[][[]]와 같은 특수 공식을 통해 정의되지 않은 값을 얻을 수 있으며 위에서 언급한 황금률을 사용하여 다른 문자 d, i 및 n을 얻을 수 있습니다.
`[][[]] + [] === "undefined"`
지금까지 획득한 모든 문자를 사용하여 철자 채우기, 필터링 및 찾기를 수행할 수 있습니다. 물론 우리가 철자를 쓸 수 있는 다른 단어도 있지만 이 단어에서 가장 중요한 점은 이 단어가 모두 배열 방법이라는 것입니다. 이는 이들이 배열 객체의 일부이며 [2,1].sort()와 같은 배열 인스턴스를 직접 호출할 수 있음을 의미합니다.
자바스크립트에 대해 알아야 할 또 다른 중요한 점은 점 표기법이나 대괄호 []를 통해 객체의 속성에 액세스할 수 있다는 것입니다. 위의 배열 메소드는 배열 객체 자체의 속성이며 점 표기법 대신 대괄호를 사용하여 이러한 메소드를 호출할 수 있습니다.
따라서 [2,1]["sort"]()는 [2,1].sort()와 동일합니다.
배열을 사용하려고 할 때 계속 살펴보겠습니다. 이 방법을 사용하면 지금까지 철자를 썼지만 부르지 않은 문자를 사용할 수 있다는 것입니다.
[]["fill"]
이것은 함수 fill() { [네이티브 코드] }를 얻게 되며 황금률을 사용하여 이 메소드 헤더를 다시 문자열로 사용할 수 있습니다.
[]["fill"]+[] === "function fill() { [native code] }"
그래서 이제 우리는 다른 문자 가져오기: c,o,v,(,),{,[,],}.
새 c와 o를 사용하여 이제 생성자라는 단어를 만들 수 있습니다. 생성자는 메서드이며 모든 JS 객체는 단순히 자체 생성자를 반환합니다.
지금까지 다룬 객체의 경우 생성자 함수를 문자열로 표시할 수 있습니다.
true["constructor"] + [] === "function Boolean() { [native code] }" 0["constructor"] + [] === "function Number() { [native code] }" ""["constructor"] + [] === "function String() { [native code] }" []["constructor"] + [] === "function Array() { [native code] }" ({})["constructor"] + [] === "function Object() { [native code] }"
이 공식을 사용하여 라이브러리에 다음 문자를 추가할 수 있습니다. :
이제 대괄호를 사용할 수 있는 "toString"` 함수를 구성할 수 있습니다. 다음과 같이 호출할 수 있습니다.
(10)["toString"]() === "10"
Using 우리의 황금률은 이미 원하는 것은 무엇이든 문자열로 변환할 수 있지만 이것이 어떻게 작동하는 걸까요?
글쎄, Number 유형의 toString 메소드에는 radix("radix")라는 비밀 인수가 있습니다. 값을 문자열로 변환하기 전에 다음과 같이 베이스로 변환합니다.
(12)["toString"](10) === "12" // 十进制 (12)["toString"](2) === "1100" // 二进制 (12)["toString"](8) === "14" // 八进制 (12)["toString"](16) === "c" // 十六进制
그런데 왜 베이스는 16에만 기록됩니까? 최대값은 0-9 및 a-z의 모든 문자를 포함하여 36이므로 이제 원하는 영숫자를 얻을 수 있습니다.
(10)["toString"](36) === "a" (35)["toString"](36) === "z"
멋지네요! 하지만 구두점이나 대문자와 같은 다른 기호도 모직 천이라고요? 좀 더 자세히 살펴보겠습니다.
JS가 실행되는 시기에 따라 사전 정의된 특정 개체나 데이터에 액세스할 수도 있고 그렇지 않을 수도 있습니다. 브라우저에서 이를 실행하면 일부 기존 HTML 래퍼 메서드에 액세스할 수 있습니다.
예를 들어 굵은 글씨는 <> 태그로 묶인 문자열 메서드입니다.
"test"["bold"]() === "<b>test</b>"
이를 통해 와 /라는 두 문자를 얻게 됩니다.
주로 문자열을 간단한 브라우저에서 해석할 수 있는 URI 친화적인 형식으로 변환하는 이스케이프 메서드에 대해 들어보셨을 것입니다. 공백 문자를 전달하면 "%20"이 표시됩니다.
각 문자를 자동으로 변환해주는 도구가 있습니다. 도구 주소: http://www.jsfuck.com/ 소스 코드 주소: https://raw.githubusercontent.com/aemkei/jsfuck/master/jsfuck.js
이 문자가 왜 유용한가요?
eBay가 얼마 전에 판매자가 이러한 문자만 사용하여 실행 가능한 JS를 페이지에 넣을 수 있도록 허용하는 나쁜 일을 한 것은 아니지만 이는 상당히 드문 공격 벡터입니다. 어떤 사람들은 난독화라고 말하지만 실제로는 난독화하는 더 좋은 방법이 있습니다.
마지막으로 이번 탐험 여행을 즐기시기 바랍니다.
자료:
https://en.wikipedia.org/wiki/JSFuck
https://esolangs.org/wiki/JSFuck
http://patriciopalladino.com/blog/2012/08/09/non-alphanumeric-javascript.html
https://raw.githubusercontent.com/aemkei/jsfuck/master/jsfuck.js