Пентест в стиле Матрицы

Пентест в стиле «Матрица»

Предисловие

В первой части фильма Матрица 1999 года есть занятный эпизод. Мы видим спящего Томаса Андерсона, известного хакера под псевдонимом Нео (кстати, кто не знал — Neo является анаграммой слова «One» — «Избранный»). При этом, на экране его компьютера происходит автоматизированный поиск в интернете.

Эпизод, про который я говорю
Эпизод, про который я говорю

Как в последствии мы узнаем, Нео долгое время ищет в сети другого хакера с псевдонимом Морфеус. Да, уже тогда, в 1999 году, Нео автоматизировал свой поиск в интернете, чтобы нужная информация искалась даже ночью, пока он спит.

В предыдущей части мы с вами подобрали инструменты и разработали относительно простой скрипт автоматизации для пентеста конкретного сайта, а в этой части, вдохновившись Матрицей, мы его улучшим.

Идея

1) Скрипт автоматически запускается вечером в определённое время;

2) Он случайным образом выбирает сайт в зоне Ru;

3) Проводится анализ сайта сканером ZAP, а результаты анализа сохраняются в файл;

4) п.2 и п.3 повторяются в цикле всю ночь до самого утра, пока скрипт принудительно не остановится Планировщиком задач;

5) Для анализа полученных за ночь отчётов, напишем отдельный скрипт-анализатор.

Т.е. вечером мы оставляем компьютер включенным, а утром просыпаемся и видим результаты сканирования случайных сайтов в зоне RU, проводим анализ отчётов по ним и принимаем дальнейшие решения о том, как этим ресурсам помочь улучшить безопасность.

Ну как вам идея? Давайте начнём!

Но прежде чем начнём, хочу уточнить! Да, в этой части уже надо написать, что все описанное ниже надо использовать только в образовательных целях и неправомерный взлом преследуется по закону!

Реализация идеи

Скрипт случайным образом выбирает сайт в зоне Ru

Надо сказать, что тут я сразу столкнулся с трудностями. Ранее меня никогда не заботила подобная задача, но как оказалось, удобных сервисов, которые можно было бы «дёрнуть» и получить действительно рандомный рабочий URL в зоне RU просто нет. Пришлось думать и экспериментировать. В итоге тестирования нескольких вариантов, я остановился на сервисе:

a89c37141ca8d1989b0ea8ac54376455.jpg

Первое, я надеюсь, что автор сервиса, Пахолков Юрий, не будет против, что мы таким образом будем использовать его сайт. Второе — Юрий, вам персональный респект, потому что за 3 дня пассивного поиска, я не нашёл в интернете сервиса, удобнее Вашего для целей нашего исследования.

Есть конечно и минусы. Основной — Юрий немного слукавил в заголовке «Настоящий случайный сайт». Мои эксперименты показали, что при 130 запросах, сайт выдаёт от 50 до 70 уникальных URL, а после где-то 150 найденных «уникальных» URL, сайт вообще практически перестаёт выдавать новые уникальные результаты. Не знаю, баг это или так и задумано, но за неимением лучшего решения будем использовать это. Важна сама концепция, а улучшать можно будет сколько угодно в будущем!

Алгоритм следующий:

В рамках бесконечного цикла;

1) Дёргаем сайт «Настоящий случайный сайт»;

2) Получаем весь html-контент страницы;

3) Выдергиваем из всего контента «случайный» URL. Тут пришлось тоже экспериментировать, потому что во всём html-коде страницы много разных URL, но оказалось, что нужная нам ссылка в коде присутствует несколько раз, но только один раз в формате «URL/favicon.ico». Поэтому ищем её в таком виде, а после «favicon.ico» просто обрезаем;

4) В рамках сессии сохраняем все уникальные ссылки в хэш-таблицу. Если URL приходит та, которую уже получали ранее, снова переходим в начало к п. 1, а если URL уникальна, то успех.

Ниже представлен PowerShell-скрипт, который реализует описанный выше алгоритм: как всегда — каждая строка прокомментирована, чтобы у вас не осталось вопросов по логике его работы.

Кстати, все описанные ниже скрипты я выложил на свой GitHub, чтобы вам было удобно забирать их себе.

# Указываем URL страницы, с которой будем получать случайные ссылки
$randomurl = "https://upread.ru/random_site.php"

# Создаем хэш-таблицу для хранения уникальных URL, чтобы не проверять одни и те же адреса в рамках одной сессии.
$uniqueUrls = @{}

# Бесконечный Цикл, который можно разорвать только принудительно 
while ($true) {
    try {
        # Выполняем запрос к странице и получаем HTML-контент
        $response = Invoke-WebRequest -Uri $randomurl -ErrorAction Stop
        #Получаем весь HTML-контент страницы
        $htmlContent = $response.Content

        # Используем регулярное выражение для поиска URL в HTML-контенте
        # Ищем ссылки, заканчивающиеся на /favicon.ico, и захватываем основную часть URL (этот способ подобран экспериментально)
        $urlPattern = '(https?://[^"\s]+)/favicon\.ico'
        $match = [regex]::Match($htmlContent, $urlPattern)

        # Если URL найден
        if ($match.Success) {
            $baseUrl = $match.Groups[1].Value  # Извлекаем основную часть URL (без /favicon.ico)

            # Проверяем, был ли этот URL уже сохранён
            if (-not $uniqueUrls.ContainsKey($baseUrl)) {
                $uniqueUrls[$baseUrl] = $true  # Добавляем URL в хэш-таблицу
                
                Write-Output "Найден уникальный URL: $baseUrl" #это, собственно то место, где мы получили уникальный URL
            } 
        } 
    } catch {
        # На всякий случай отлавливаем ошибки и показываем их в консоли
        Write-Output "Ошибка при запросе к $randomurl"
    }
}

Проводится анализ сайта сканером ZAP, а результаты сохраняются анализа в файл

Тут уже проще, потому что мы должны теперь объединить скрипт выше с тем скриптом, который у нас получился в прошлой части и убрать всё лишние. Итак, вот что у меня получилось:

Файл:  MatrixScanScript.ps1

# Указываем URL страницы, с которой будем получать случайные ссылки
$randomurl = "https://upread.ru/random_site.php"

# Создаем хэш-таблицу для хранения уникальных URL, чтобы не проверять одни и те же адреса в рамках одной сессии.
$uniqueUrls = @{}

# Путь к файлу zap.bat. Замените путь, если установили ZAP в другую папку
$zapPath = "C:\Program Files\ZAP\Zed Attack Proxy\"

# Переходим в папку ZAP
Set-Location $zapPath

# Путь к папке ZAPSCAN на рабочем столе, куда будут сохраняться отчёты
$outputDir = "$env:USERPROFILE\Desktop\ZAPSCAN"

# Проверяем, существует ли папка ZAPSCAN, если нет - создаем её
if (-not (Test-Path $outputDir)) {
    New-Item -ItemType Directory -Path $outputDir | Out-Null
}

# Бесконечный Цикл, который можно разорвать только принудительно 
while ($true) {
    try {
        # Выполняем запрос к странице и получаем HTML-контент
        $response = Invoke-WebRequest -Uri $randomurl -ErrorAction Stop
        #Получаем весь HTML-контент страницы
        $htmlContent = $response.Content

        # Используем регулярное выражение для поиска URL в HTML-контенте
        # Ищем ссылки, заканчивающиеся на /favicon.ico, и захватываем основную часть URL (этот способ подобран экспериментально)
        $urlPattern = '(https?://[^"\s]+)/favicon\.ico'
        $match = [regex]::Match($htmlContent, $urlPattern)

        # Если URL найден
        if ($match.Success) {
            $baseUrl = $match.Groups[1].Value  # Извлекаем основную часть URL (без /favicon.ico)

            # Проверяем, был ли этот URL уже сохранён
            if (-not $uniqueUrls.ContainsKey($baseUrl)) {
                $uniqueUrls[$baseUrl] = $true  # Добавляем URL в хэш-таблицу
                
                # Формируем имя файла отчёта в формате сегодняшняядата_url.txt
                $date = Get-Date -Format "yyyyMMdd_HHmmss"
                $outputFile = "$outputDir\$($date)_$($baseurl -replace '[^\w]', '_').txt"

                # Выполняем команду zapit для нашего сайта и сохраняем результат в файл
                .\zap.bat -zapit $baseurl -cmd | Out-File -FilePath $outputFile
            } 
        } 
    } catch {
        # На всякий случай отлавливаем ошибки в консоли, но ошибок быть не должно
        Write-Output "Ошибка при запросе к $randomurl"
    }
}

Скрипт автоматически запускается и работает всю ночь

Тут я не буду вам снова приводить множество шагов и скриншотов того, как это сделать с помощью Планировщика задач (Task Scheduler) Windows. Всё достаточно подробно описал в предыдущей части. Уверен, вы справитесь и настроите «Старт-Стоп» скрипта так, как вам удобно. Если возникнут сложности, напишите в комментариях, обязательно помогу и подскажу.

Итог работы скрипта

Итак, проснувшись утром, вы получите примерно такую картину:

Да, да, я тестировал не утром, а вечером )
Да, да, я тестировал не утром, а вечером)

Как видим, всё работает. Результаты сканирования каждого сайта сохраняются в отдельный файл. Также видна производительность работы: 1–2 сайта в минуту, что, имхо, очень не плохо.

Теперь давайте посмотрим ещё раз внутрь отчётов:

Пентест в стиле «Матрица»

В отчёте нам важны 2 момента:

1) В предыдущей части, когда мы ставили и настраивали ZAP, мы установили плагин «Technology Detection», который прекрасно работает и очень часто из-за ошибок конфигурации или настроек сайта выдаёт информацию не только об используемой технологии, но и о её версии. Ну, а зная используемую версию, всегда можно посмотреть известные уязвимости;

2) Предупреждения (alerts), особенно уровней «High» и «Medium». Тут не буду долго расписывать, но уровень «High» — это, как правило, очень критичные уязвимости на сайте.

Понимая эти 2 момента, мы конечно можем начать каждый отчёт просматривать вручную, но мы же хакеры и нам лень тратить столько времени впустую, поэтому напишем отдельный скрипт-анализатор.

Анализ полученных отчётов

Анализатор — это отдельный Powershell-скрипт, который в указанной папке просмотрит каждый txt-файл и если в файле содержится слово «High», то к названию файла в начале добавляется буква «H», если содержит, например «PHP (7.3.33)», то к началу названия файла добавляется знак »+». Таких параметров может быть ещё несколько, т.е. должна быть возможность их легко добавлять в скрипт.

Вот, что у меня получилось:

Файл:  ScanAnalysis.ps1

# Укажите путь к папке с файлами
$folderPath = "C:\Users\chumi\Desktop\ZAPSCAN"

# Получаем все txt файлы в указанной папке
$files = Get-ChildItem -Path $folderPath -Filter *.txt

# Перебираем каждый файл
foreach ($file in $files) {
    $content = Get-Content -Path $file.FullName
    $newName = $file.Name

    # Проверяем наличие слова "High" в файле
    if ($content -match '\bHigh\b') {
        $newName = "H" + $newName
    }

    # Проверяем наличие строки "PHP (VER)" в файле
    if ($content -match "PHP \(7\.3\.33\)") {
        $newName = "+" + $newName
    }

    # Добавьте другие условия по аналогии
    # if ($content -match "AnotherPattern") {
    #     $newName = "AnotherPrefix" + $newName
    # }

    # Если имя файла изменилось, переименовываем файл
    if ($newName -ne $file.Name) {
        $newPath = Join-Path -Path $folderPath -ChildPath $newName
        Rename-Item -Path $file.FullName -NewName $newPath
    }
}

Как видим, всё достаточно просто и эффективно. Скрипт отрабатывает очень быстро, а нам остаётся посмотреть только те файлы, которые переименовались.

Пентест в стиле «Матрица»

В моих отчётах нашлось 4 сайта, которые построены с использованием PHP версии 7.3.33. Гуглим эту версию и видим:

Пентест в стиле «Матрица»

В данной версии PHP есть 2 уязвимости с очень высоким рисковым рейтингом.

Итоги и планы на будущее

Вдохновившись фильмом Матрица, мы с вами на 100% реализовали нашу идею и получили скрипты автоматизации пентеста, которые помогают существенно повысить эффективность первичной разведки. Надеюсь, я смог вам доказать, что любую рутинную работу в windows можно и нужно автоматизировать, чтобы оставалось больше времени на образование и творчество.

Что можно улучшить:

1) Ну конечно же надо улучшать функцию получения случайной URL. Тут вариантов реализации много. Предлагайте свои варианты;

2) Сейчас скрипт проверяет уникальность URL, которую нужно сканировать, только в рамках одной сессии. Можно этот механизм улучшить, чтобы уникальность проверялась в рамках настраиваемого периода, например, месяца;

3) Можно очень много чего улучшить в скрипте анализаторе, как вариант, пропускать отчёты через модель искусственного интеллекта.

Мне очень важны ваша обратная связь и реакции по этой статье и если вам она понравится, то чуть позже сделаю 4 часть, где мы подключим и будем локально использовать модель искусственного интеллекта в первичной разведке и анализе.

Поэтому, поставьте мне «лайк» за старания, напишите ваши мысли в комменты и подписывайтесь на мой Телеграм!

© Habrahabr.ru