#14 Gray Hat C#. Руководство для хакера по созданию и автоматизации инструментов безопасности. Использование SQL-инъекций. Программное выполнение эксплойта на основе UNION.
Здравствуйте, дорогие друзья.
Теперь давайте посмотрим, как мы можем реализовать этот эксплойт программно, используя некоторые классы C# и HTTP. Поместив полезную нагрузку, показанную в листинге выше, в параметр searchquery, мы должны увидеть на веб-странице таблицу элементов с именами пользователей и хэшами паролей, вместо реальных элементов. Все, что нам нужно сделать, это выполнить один HTTP-запрос, а затем использовать регулярное выражение для извлечения электронных писем и хэшей паролей между маркерами из ответа HTTP-сервера.
Создание маркеров для поиска имен пользователей и паролей
Во-первых, нам нужно создать маркеры для регулярного выражения, как показано в листинге ниже. Эти маркеры будут использоваться для разграничения значений, возвращаемых из базы данных во время внедрения SQL. Мы хотим использовать случайные строки, которые вряд ли можно будет найти в исходном коде HTML, чтобы наше регулярное выражение извлекало только те имена пользователей и хэши паролей, которые нам нужны, из HTML, возвращаемого в ответе HTTP.
Для начала мы создаем три строки, которые будут использоваться в качестве маркеров front [1], middle [2] и end [3]. Они будут использоваться для поиска и разделения имен пользователей и паролей, которые мы извлекли из базы данных в ответе HTTP. Нам также необходимо создать шестнадцатеричные представления маркеров, которые будут включены в полезную нагрузку. Для этого каждый маркер нужно немного обработать.
Мы используем метод LINQ Select() [5] для перебора каждого символа в строке маркера, преобразования каждого символа в его шестнадцатеричное представление и возврата массива обработанных данных. В этом случае он возвращает массив двухбайтовых строк, каждая из которых представляет собой шестнадцатеричное представление символа исходного маркера.
Чтобы создать полную шестнадцатеричную строку из этого массива, мы используем метод Join() [4], чтобы объединить каждый элемент массива, создавая шестнадцатеричную строку, представляющую каждый маркер.
Создание URL-адреса с полезной нагрузкой
Теперь нам нужно создать URL-адрес и полезную нагрузку для выполнения HTTP-запроса, как показано в листинге ниже.
Мы создаем URL-адрес [1], чтобы выполнить запрос, используя первый аргумент [2], переданный эксплойту: IP-адрес экземпляра BadStore. После создания базового URL-адреса мы создаем полезную нагрузку, которая будет использоваться для возврата имен пользователей и хэшей паролей из базы данных, включая три шестнадцатеричные строки, которые мы создали из маркеров, чтобы отделить имена пользователей от паролей. Как говорилось ранее, мы кодируем маркеры в шестнадцатеричном формате, чтобы гарантировать, что в случае, если маркеры будут возвращены без нужных нам данных, наше регулярное выражение случайно не совпадет с ними и не вернет ненужные данные. Наконец, мы объединяем полезную нагрузку и URL [3], добавляя параметры уязвимой строки запроса к полезной нагрузке базового URL-адреса. Чтобы гарантировать, что полезные данные не содержат символов, уникальных для протокола HTTP, мы передаем полезные данные в EscapeUriString() [4], прежде чем вставлять их в строку запроса.
Выполнение HTTP-запроса
Теперь мы готовы выполнить запрос и получить HTTP-ответ, содержащий имена пользователей и хэши паролей, полученные из базы данных с помощью SQL-инъекции (см. листинг ниже).
Мы создаем базовый запрос GET, создавая новый HttpWebRequest [1] с URL-адресом, который мы создали ранее и содержащим полезную нагрузку SQL-инъекции. Затем мы объявляем строку для хранения нашего ответа, присваивая ей по умолчанию пустую строку. В контексте оператора using мы создаем экземпляр StreamReader [2], и читаем ответ в нашу строку ответа [3]. Теперь, когда у нас есть ответ от сервера, мы можем создать регулярное выражение, используя наши маркеры, для поиска имен пользователей и паролей в ответе HTTP, как показано в листинге ниже.
Здесь мы находим и печатаем значения, полученные с помощью SQL-инъекции из ответа HTTP. Сначала мы используем класс Regex [1] (в пространстве имен System.Text.RegularExpressions), для создания регулярного выражения. Это регулярное выражение содержит две группы выражений, которые фиксируют хеш имени пользователя и пароля из совпадения, используя передний, средний и конечный маркеры, определенные ранее. Затем мы вызываем метод Matches() [2] в регулярном выражении, передавая данные ответа в качестве аргумента Matches(). Метод Matches() возвращает объект MatchCollection, который мы можем перебирать с помощью цикла foreach для получения каждой строки в ответе, которая соответствует регулярному выражению, созданному ранее с помощью наших маркеров.
Перебирая каждое совпадение выражения, мы печатаем хеш имени пользователя и пароля. Используя метод WriteLine() [3] для печати значений, мы создаем строку, используя захваты групп выражений для имен пользователей [4], и паролей [5], которые сохраняются в свойстве Groups совпадения выражений.
Запуск эксплойта должен привести к выводу, показанному в листинге ниже.
Как видите, с помощью одного запроса мы смогли извлечь все имена пользователей и хэши паролей из таблицы userdb, в базе данных BadStore MySQL с помощью внедрения UNION SQL.
На этом все. Всем хорошего дня!