- JavaScript | Как получить код HTML-страницы?
- Как объект document превратить в строку с HTML-разметкой?
- Одной командой
- Видео инструкция
- Задача
- Немножко теории
- Решение
- Итог
- Информационные ссылки
- Вам также может понравиться
- DOM | Интерфейс AbortSignal
- Тип события wheel пользовательского интерфейса WheelEvent
- JavaScript | Влияние инлайновых стилей CSS-свойства «display» на работу innerText через DOMParser
- ECMAScript | Оператор continue
- HackWare.ru
- Этичный хакинг и тестирование на проникновение, информационная безопасность
- Как увидеть JavaScript код, написанный с использованием непечатных символов
- 1. Вывод кода перед последней eval
- 2. Ставим JavaScript на паузу
- 3. Невидимые символы в JavaScript всё равно можно копировать!
- 4. Деобфускация JavaScript написанного на нелатинских системах письменности
- Заключение
- Связанные статьи:
JavaScript | Как получить код HTML-страницы?
Как объект document превратить в строку с HTML-разметкой?
Одной командой
new XMLSerializer().serializeToString(document)
Куда вводить эту команду? Открываете HTML-страницу, с которой хотите получить все веб-ссылки. Включаете «Инструменты разработчика» в браузере (CTRL + SHIFT + i). Находите вкладку «Console«. Тыкаете курсор в белое поле справа от синей стрелочки. Вставляете команду. Жмёте клавишу ENTER.
Для тех кто не понял строчку кода выше, предлагаю упрощённую для понимания версию. Пошаговая инструкция и видео ниже.
Видео инструкция
В этом видео приводится пример преобразования HTML-элемента в строку при помощи JavaScript. Ввод команд осуществляется в консоль браузера Google Chrome. Результат виден сразу.
Задача
У нас открыта вкладка в браузере. В этой вкладке отрисована HTML-страница, которая пришла с сервера.
Нам нужно получить код данной HTML-страницы — разметку. Мы хотим получить разметку в виде СТРОКИ. То есть нам как-то нужно преобразовать объект HTML-элемента в строковый тип данных JavaScript.
Немножко теории
«Объектная модель документа» (DOM) преобразовывает СТРОКУ кода c сервера в объект document . Этот объект хранит в себе наборы элементов и их последовательности. Самый правильный сценарий — это сделать GET-запрос на сервер и достать данные при помощи функции fetch(). Но нам нужно понять способ КОНВЕРТАЦИИ из уже готового объекта.
У объекта document есть готовый набор атрибутов, который помогает извлекать данные из страниц. Два атрибута, на которые можно акцентировать внимание — это documentElement и doctype. Но эти данные являются объектами, а не строками.
В данной задаче извлекать их по отдельности не имеет смысла. Просто вы должны понимать структуру объекта document . Внутри объекта тоже объекты, а не строки.
Решение
Нам нужно использовать интерфейс XMLSerializer, который имеет один единственный метод serializeToString(). Этот метод вернёт нам СТРОКУ из ОБЪЕКТА.
Сперва нам нужно создать новый конструктор сериализатора разметки:
Теперь мы можем вызвать метод serializeToString() и передать в него наш объект document .
a.serializeToString(document)
На выходе мы получаем СТРОКУ с HTML-разметкой. Тип данных STRING. Даже консоль браузера нам подсвечивает её красно-коричневым цветом.
typeof(new XMLSerializer().serializeToString(document)) "string"
Можно без объявления лишних переменных сразу получить строку с HTML-разметкой
new XMLSerializer().serializeToString(document)
Итог
Мы выполнили задачу и получили весь код HTML-страницы.
Информационные ссылки
Стандарт DOM Parsing and Serialization — https://www.w3.org/TR/DOM-Parsing/
Вам также может понравиться
DOM | Интерфейс AbortSignal
IDL [Exposed=( Window , Worker )] interface AbortSignal : EventTarget < readonly attribute boolean aborted; attribute EventHandler onabort; >; Для веб […]
Тип события wheel пользовательского интерфейса WheelEvent
Тип колёсного события wheel Интерфейс WheelEvent Синх / Асин Асинхронный Всплытие Да Надежные цели Element Отменяемый Различные варианты Сдержанный Да Действие по […]
JavaScript | Влияние инлайновых стилей CSS-свойства «display» на работу innerText через DOMParser
В этой публикации хочется проверить, какую объектную модель документа создаст интерфейс DOMParser, если в передаваемой для разбора строке будут включены атрибуты style […]
ECMAScript | Оператор continue
Синтаксис оператора continue ContinueStatement [Yield, Await] : continue ; continue [не LineTerminator здесь] LabelIdentifier [?Yield, ?Await] ; 14.8.1 Статическая семантика: Ранние […]
HackWare.ru
Этичный хакинг и тестирование на проникновение, информационная безопасность
Как увидеть JavaScript код, написанный с использованием непечатных символов
В статье «Как обфусцировать JavaScript код», в самом её конце я привёл «эзотерические» примеры от автора JSFuck в которых большая часть кода просто невидима. Рекомендую посмотреть на те концепты, которые подготовил автор — они вызывают восхищение и заставляют задуматься о возможностях JavaScript. Автор кода записывает строки в виде экранированной последовательности и/или использует трюки с кодировкой. Как бы там не было, но при копировании-вставке код выглядит так:
А при просмотре исходного кода страницы JavaScript код выглядит так:
Первая мысль, это сохранить страницу и посмотреть в шестнадцатеричном редакторе. Конечно, мы увидим байты кода, но восстановить их в исполнимый код будет сложно. Давайте рассмотрим, какими способами можно увидеть невидимой код JavaScript и при этом познакомимся с ещё некоторыми возможностями Инструментов разработчика в веб-браузерах.
1. Вывод кода перед последней eval
Начнём с примера, который так и называется «Invisible Code» — невидимый исходный код: http://aem1k.com/0/
Изменения кода я буду делать в Инструментах разработчика в веб-браузере, а чтобы они сохранились после обновления страницы я воспользуюсь методом из статьи «Как сделать так, чтобы изменения в Инструментах разработчика браузера сохранялись после перезагрузки страницы».
Чуть преобразуем код, чтобы можно было вносить в него свои изменения и проверяем его работоспособность:
Код сохранил свою функциональность, поэтому продолжаем изменения:
Как можно увидеть, задумка в целом сработала, что вывод кода оборвался из-за какой-то причины:
Опять чуть меняю подход к выводу кода:
Видимо мой фокус с не сработал по той причине, что в коде также используется тег .
Для проверки работоспособности, сохраняю этот код в файл с расширением .htm:
И открываю в браузере, чтобы убедиться, что код рабочий:
Итак, я сумел получить код, который до этого был невидим и отображался в виде точек.
2. Ставим JavaScript на паузу
Следующий пример // VOID — невидимые переменные и код: https://aem1k.com/void/
Использование здесь предыдущего метода затруднено, т. к. код записан в несколько строк и вообще на последнем этапе не используется eval. Более того, большинство модификаций исходного кода (даже лишние пробелы после ) делают этот код нефункциональным.
Посмотрим структуру DOM документа:
Много интересного, но в этот раз не помогло.
Возвращаемся на вкладку Sources и ставим JavaScript на паузу:
Обратите внимание, что открылся новый файл — в нём содержится JavaScript код, выполняемый в момент поставки на паузу. Сделаем этот код более читаемым, получим:
i = setInterval(I=>< document.body.style.backgroundColor = 0; document.body.style.color = "#0FF"; document.body.innerHTML = "<script> " + document.head.textContent.replace(/ᅠ*/g, "").replace(/"'.*'"/, "\"''\"").replace(/./g, x=>`">$ `) + "</script>" > , 100)Опять сохраняю код в .htm файл:
![]()
И открываю в веб-браузере для проверки:
![]()
Всё работает! Хотя теперь переливаются другие символы. Суть в том, что переливается сам исходный код, каким бы он ни был (то есть да, на страницу выводится исходный код, который работает в данный момент, вот такой интересный скрипт).
3. Невидимые символы в JavaScript всё равно можно копировать!
Попробуем деобфусцировать невидимый код с помощью JStillery.
Вновь возьмём предыдущий пример (https://aem1k.com/void/), скопируем исходный код в его оригинальном виде и вставим в JStillery. Поразительно, но этот фокус удался:
![]()
Получен код после деобфускации:
undefined; ᅠ = '"'; ᅠ = true; ᅠ = false; ᅠ = 'true'; ᅠ = 'false'; ᅠ = 0; ᅠ = 1; ᅠ = <>; ᅠ = 2; ᅠ = 3; ᅠ = 5; ᅠ = '[object Object]'; ᅠ = 'undefined[object Object]'; ᅠ = 'n'; ᅠ = 't'; ᅠ = 'r'; ᅠ = 'c'; ᅠ = 'u'; ᅠ = 'o'; ᅠ = 's'; ᅠ = 'e'; ᅠ = 'a'; ᅠ = '\\)('; ᅠ = '\\'; ᅠ = '('; ᅠ = ')'; ᅠ = 'return '; ᅠ = 'constructor'; ᅠ = Function; (function anonymous() < i = setInterval(I =>/* Called:undefined | Scope Closed:false| writes:false*/ < document.body.style.backgroundColor = 0; document.body.style.color = '#0FF'; document.body.innerHTML = '<script> ' + document.head.textContent.replace(/ᅠ*/g, '').replace(/"'.*'"/, '"\'\'"').replace(/./g, x => /* Called:undefined | Scope Closed:false| writes:false*/ '' + x + '') + '</script>'; >, 100);; >());Как можно увидеть, в нём выведены дополнительные строки, но вторая часть совпадает с деобфусцированным кодом, полученной предыдущим образом.
![]()
Код из первого примера (http://aem1k.com/0/) не получилось деобфусцировать таким образом. Думаю, дело скорее всего в том, что
код портится при копировании и вставке(примечание: позже я понял, что дело в том, что нужно было убрать HTML теги, копипаст бы тоже сработал, как и в примере выше). Поэтому попробуем другим образом — сохраним файл с невидимым JavaScript. Но сохранять будем не в веб браузере — веб-браузеры добавляют много лишнего. Сохраним с помощью wget или cURL, например:wget http://aem1k.com/0/ -O 0.htmИз сохранённой страницы убираем всё, что не относится к JavaScript, например, в данном случае я убрал и >.
Запускаем деобфускацию в командной строке с помощью jstillery:
![]()
Всё сработало, и мы вновь получили фрагмент кода, который уже видели раньше.
4. Деобфускация JavaScript написанного на нелатинских системах письменности
Возьмём ещё один пример: aurebesh.js — перевод JavaScript на другие системы письменности: https://aem1k.com/aurebesh.js/
К примеру, следующий код работает в веб-брауезре:
Но как узнать, что именно в нём записано?
Если из этого кода убрать тег … , то его можно деобфусцировать с помощью JStillery:
ก = ''; ว = 'true'; อ = 'false'; ซ = '[object Object]'; ฝ = 't'; ค = 'true'[ง = 1]; ญ = 3; ฒ = 'c'; 'true'[ฒ = 'constructor'].constructor('alert(ก)')();Деобфускация удалась, но нужно отметить, что полученный код не в полной мере сохранил функциональность (вместо единицы alert выводит пустую строку).
Попробуем ещё один вариант. Откроем файл с кодом в веб-браузере и нажмём кнопку «Форматирование». Также поставим выполнение скриптов на паузу:
![]()
Поскольку скрипт уже завершил выполнение, перезагрузим страницу и будем нажимать F9 для пошагового выполнения JavaScript.
В результате будет показан выполняемый код в обычном виде, в том, каким его видеть движок JavaScript:
![]()
Заключение
Мне эти примеры понравились в качестве головоломок. Рассмотренные фрагменты кода, несмотря на их «аномальность», ещё раз подтверждают — защитить от анализа и изменения код JavaScript и HTML очень трудно и в большинстве случаев невозможно.
Связанные статьи: