Obfuscated код javascript с двоичными значениями?
Этот код выводит D
. Вопрос: КАК?
alert([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()[([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(![]+[])[+!+[]]](+[]+[+[]])[+!+[]]);
Я понимаю, что ![]
оценивается как false
или 0
и т.д., но как он выполняется? И как я могу преобразовать это в нечто, что могут понять люди, и не только Джон Скит?
Может кто-то сломать часть этого кода и объяснить мне, что происходит?
Ответы
Ответ 1
Ну, оценивая выражение в частях, в конце это эквивалентно:
[]['sort']['call']()["btoa"]("00")[1]; // "D"
Что можно упростить до:
btoa("00")[1]; // "D"
Как вы можете "декодировать его"?
Просто изучите используемые операторы, например, мы можем сначала увидеть, что используется литерал массива, затем выполняются несколько свойств доступа к нотам с привязкой и несколько вызовов.
Как это работает?
Хитрость заключается в цепочке преобразований нескольких типов, например, для получения буквы f
:
(![]+[])[+[]]
Если мы рассмотрим первую часть в круглых скобках ![]+[]
, мы увидим логическое отрицание, которое вернет false
, потому что объект массива всегда правдивый, а затем конкатенация.
Это создает строку "false"
, затем вторую часть мы видим скобки, применяемые к этой строке, для доступа к символу и выражение +[]
, что приводит к 0
.
+[]
дает нуль, потому что метод Array toString
возвращает пустую строку для пустого массива, подобного этой, и пустая строка генерирует нуль, когда она преобразуется в число (унарный оператор +
в этом пример).
Есть только такие трюки, вещи, которые производят строку, такие "true"
, "false"
, "null"
, "undefined"
и т.д.... и больше трюков, чтобы получить числовое значение.
Например, чтобы получить номер - для доступа к символу - они снова используют преобразование скрытого типа:
+[]; // 0, equivalent to +""
+!+[]; // 1, equivalent to +true
!+[]+!+[]; // 2, equivalent to +true+true
!+[]+!+[]+!+[]; // 3, equivalent to +true+true+true
Ответ 2
Он делает некоторые трюки с преобразованиями типа javascript. Как указывала CMS, это эквивалентно: []['sort']['call']()["btoa"]("00")[1];
Они строят строки, вытаскивая их из таких вещей, как false
и т.д.
Например, чтобы получить s
в "sort":
Получить "false": (![]+[])
- ![]
возвращает false и +[]
преобразует его в строку.
Получить значение 3 с помощью: !+[]+!+[]+!+[]
- каждый !+[]
возвращает true
, но когда вы добавляете логические значения, вы получаете целочисленное представление. например true + true = 2
Получите s
с записью доступа к индексу строки ("false"[3] = 's'
): (![]+[]) [!+[]+!+[]+!+[]]
И теперь у вас есть s
. Они продолжают делать это до тех пор, пока у них не будет достаточно доступа к тому, какой метод или свойство они хотят.
Ответ 3
! [] неверно.! [] + [] оценивает значение "false". +[]
равно 0, поэтому! + [] истинно и т.д. javascript очень странно с его подразумеваемыми преобразованиями типов