Одним из ключевых аспектов тестирования на проникновения является автоматизация шаблонных действий. Кто-то для этого пишет отдельные программы, однако сейчас существует множество продуктов, которые позволяют расширять свои функциональные возможности с помощью дополнительных модулей. Пример бесплатного сканера уязвимостей с поддержкой модулей - OpenVAS, но в этой статье речь пойдет о Nessus, который хоть и платный, но субъективно находит больше и генерирует меньше false positive срабатываний (хотя OpenVAS начался, как форк Nessus, но это было давно).
Большинство модулей для Nessus представляют собой обычные текстовые файлы с расширением .nasl. Часть модулей поставляются в виде бинарных файлов с расширением .nbin, но не будем об этом. Модули (или плагины) по умолчанию можно найти по следующим путям (https://community.tenable.com/s/article/Location-of-Plugin-Directory):
1 2 |
Windows: C:\ProgramData\Tenable\Nessus\nessus\plugins Linux: /opt/nessus/lib/nessus/plugins |
Модулей довольно много, более 100 тысяч, часть из них написаны давно (судя по коду) и почти не обновляются, хотя реализуют базовые моменты сканирования (например, поиск распространенных имен директорий). Модули зачастую никак не параметризуются, что приводит к необходимости вручную править код, чтобы, например, расширить встроенный в модуль словарь. Зато в таком разнообразии всегда можно найти пример кода, чтобы реализовать какую-то специфичную функцию в своем модуле.
В качестве примера мы напишем тривиальный модуль для поиска скрипта администрирования БД Adminer (https://github.com/vrana/adminer/). В Nessus есть похожий модуль для phpMyAdmin (https://phpmyadmin.net/). Модуль будет искать Adminer по всевозможным характерным путям, определять версию и в зависимости от нее выставлять степень критичности находки (до версии 4.6.3 возможно было читать файлы на сервере с помощью LOAD DATA LOCAL INFILE, подробнее можно прочитать тут).
Отмечу, что документация по доступному API своеобразная и обрывочная, одни и те же действия в стадартных модулях временами реализуются разными способами без видимой причины, именование некоторых функций также оставляет вопросы, что наводит на мысль о пласте legacy-кода, который Tenable (разработчик Nessus) никак не вычистит (возможно, не хотят старые модули переписывать).
Приступим. Модуль начинается с указания уникального внутреннего идентификатора для него, а также описания, даты релиза, степени критичности, CVE и т.п. Практически все является опциональным и служит лишь для удобного представления в веб-интерфейсе (а ведь модули можно запускать и без него через консоль). Рекомендую использовать подсветку синтаксиса для Ruby. Тут, естественно, используется не он, а NASL, но подсвечивает приемлемо.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# Adminer script discovery include("compat.inc"); if(description) { script_id(10797107); script_version("$Revision: 0.1 $"); script_cvs_date("$Date: 2019/04/10 13:37:00 $"); script_name(english: "Adminer Database Management Detection"); script_set_attribute(attribute: "synopsis", value: "Adminer Database Management script was detected on the remote host."); script_set_attribute(attribute: "description", value: "Adminer Database Management script was detected on the remote host."); script_set_attribute(attribute: "solution", value: "Restrict access to the script, if desired."); script_set_attribute(attribute: "risk_factor", value: "Low"); script_set_attribute(attribute:"plugin_publication_date", value: "2019/04/10"); script_set_attribute(attribute:"plugin_type", value: "remote"); script_end_attributes(); script_summary(english: "Reports if Adminer (https://www.adminer.org/) was discovered on the remote host."); script_category(ACT_GATHER_INFO); script_copyright(english: "This script is Copyright (C) Kaimi (https://kaimi.io)"); script_family(english: "CGI abuses"); script_dependencie("webmirror.nasl"); script_exclude_keys("Settings/disable_cgi_scanning"); script_require_keys("Settings/enable_web_app_tests"); script_require_ports("Services/www"); script_timeout(1800); exit(0); } |
Так как код в целом простой, буду описывать суть в абзацах после фрагментов кода. В вышеприведенном участке мы задали уникальный идентификатор, версию, дату, описание и прочие атрибуты модуля. Список атрибутов неполный, если есть необходимость добавить связанный CVE, CVSS и прочее - посмотрите примеры в стандартных модулях. В конце мы задаем категорию модуля - CGI abuses и несколько условий. Нам необходимо, чтобы до старта нашего модуля отработал модуль webmirror.nasl. Данный модуль занимается перебором стандартных путей и заполняет некоторые глобальные структуры, которые затем могут быть использованы другими модулями. Далее мы задаем условия, чтобы наш модуль не запускался если в политике сканирования явно отключено CGI scanning (https://www.tenable.com/blog/nessus-web-application-scanning-new-plugins-configuration), либо отключено тестирование веб-приложений. Далее нам необходимо, чтобы предварительно Nessus просканировал и идентифицировал порты с веб-серверами, и задаем таймаут работы нашего модуля.
Вот так будет выглядеть информация о модуле в веб-интерфейсе Nessus.
Для поиска возможных путей нам необходим список версий, а также возможные именования. Все это можно получить из официального репозитория Adminer - https://github.com/vrana/adminer/. Я составил полный список возможных именований с учетом доступных языков - https://github.com/kaimi-io/web-fuzz-wordlists/blob/master/adminer.txt. В нашем модуле мы будем использовать сокращенный вариант, который при необходимости можно дополнить, и будем частично генерировать этот список, вместо того, чтобы хардкодить содержимое. Но для начала допишем (скопируем из других модулей) еще несколько моментов:
1 2 3 4 5 6 7 8 |
include("audit.inc"); include("global_settings.inc"); include("misc_func.inc"); include("http.inc"); app = "Adminer"; port = get_http_port(default: 80); |
Мы подключаем некоторые модули, которые содержат используемые глобальные переменные и реализацию некоторых необходиммых функций. Далее получаем порт, где Nessus обнаружил веб-сервер. Переходим к draw the rest of the fucking owl основному коду:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
prefix_list = make_list("adminer-", "editor-", "adminer"); # Versions up to current for 4/10/2019 version_list = make_list("","4.7.1","4.7.0","4.6.3","4.6.2","4.6.1","4.6.0","4.5.0","4.4.0","4.3.1","4.3.0","4.2.5","4.2.4","4.2.3","4.2.2","4.2.1","4.2.0","4.1.0","4.0.3","4.0.2","4.0.1","4.0.0","3.7.1","3.7.0","3.6.4","3.6.3","3.6.2","3.6.1","3.6.0","3.5.1","3.5.0","3.4.0","3.3.4","3.3.3","3.3.1","3.3.0","3.2.2","3.2.1","3.2.0","3.1.0","3.0.1","3.0.0"); # More languages are available according to https://github.com/vrana/adminer suffix_list = make_list("-en.php", "-mysql-en.php", "-mysql.php", ".php", "/"); found_list = make_list(); found_list_ver = make_list(); found_ctr = 0; high_severity = 0; dirs = list_uniq(make_list(cgi_dirs(), "")); foreach dir (dirs) { path = dir + '/'; foreach prefix (prefix_list) { foreach version (version_list) { foreach suffix (suffix_list) { # path/ + adminer- + 4.1.0 + -en.php url = path + prefix + version + suffix; res = http_send_recv3( method : "GET", port : port, item : url ); if (isnull(res)) continue; match = pregmatch(pattern: '<span class="version">([0-9\\.]+)</span>', string: res[2], icase: TRUE); if (!empty_or_null(match)) { # LOAD DATA LOCAL INFILE disabled since 4.6.3 if (match[1] =~ "^(?:[1-4]\.[0-6]\.[0-2]|[1-3]\.[0-9]\.[0-9])$") high_severity = 1; found_list[found_ctr] = url; found_list_ver[found_ctr] = match[1]; found_ctr++; } } } } } if (found_ctr > 0) { report = NULL; if (report_verbosity > 0) { report += '\nThe following instance of Adminer was detected on the remote host: \n'; report += '\n'; for (i = 0; i < found_ctr; i++) { url = found_list[i]; version = found_list_ver[i]; report += 'Adminer Version\t: ' + version + '\n'; report += 'URL\t\t: ' + build_url(port: port, qs: url) + '\n'; report += '\n'; } if (high_severity) report += '\nDiscovered versions may be susceptible to LOAD DATA LOCAL INFILE attack\n'; } if (high_severity) security_hole(port: port, extra: report); else security_note(port: port, extra: report); } else { audit(AUDIT_WEB_APP_NOT_AFFECTED, app, build_url(port: port, qs:"/")); } |
Здоровенный фрагмент кода. В общем, исходя из репозитория, мы составили список версий, префиксов и суффиксов именования путей, по которым может быть расположен Adminer. Объявили несколько переменных (массивы для хранения пути, версии, общий счетчик числа обнаружений и флажок повышенной критичности). Далее мы начинаем процесс сканирования, используя при этом обнаруженные ранее пути. Формируем путь для проверки и делаем обычный GET-запрос. Обратите внимание на имя функции для его отправки и вспомните пассаж выше про legacy-код и качество API. Извлекаем обычным регулярным выражением версию и заносим в массивы, а также выставляем флажок, если обнаружена старая версия с возможностью чтения файлов на сервере. После проверки всех директорий генерируем текст для отчета, где указываем пути, обнаруженные версии и в зависимости от этого возвращаем, что ничего не нашлось (AUDIT_WEB_APP_NOT_AFFECTED), уязвимость низкого уровня (если версия >= 4.6.3), иначе высокого.
Вот так выглядят результаты работы модуля в веб-интерфейсе:
Как я упоминал, модуль также может быть запущен из командной строки следующим образом:
1 |
/opt/nessus/bin/nasl -t 192.168.1.1 ./adminer.nasl |
Подробнее можно почитать тут.
Наконец, после того, как модуль написан и перемещен в директорию с другими модулями, необходимо обновить БД плагинов (https://community.tenable.com/s/article/Rebuild-the-Plugin-Database):
1 2 3 4 |
/opt/nessus/sbin/nessuscli fix --set nasl_no_signature_check=yes service nessusd stop /opt/nessus/sbin/nessusd -R service nessusd start |
Первая команда отключает проверку подписи у используемых плагинов. Все готово, можно пользоваться. Для желающих почитать более структурированное описание процесса разработки модулей - можно полистать книгу Nessus Network Auditing, издание старое, но представление о процессе и доступном API дает.
Модуль из статьи: adminer_detect.nasl.zip
Kaimi, привет! Пишу в этой теме,т.к тема, соответствующая моему вопросу,закрыта. Можешь ли ты снять пароль с теста формата MTX,либо извлечь список вопросов за вознаграждение разумеется)?
Все экстракторы в статье пробовал,все нужные версии качал-не идёт. Возможно дело в моих кривых руках..
Если уже формат mtx, то надо не экстракторы пробовать, а брать софт из статьи про mtx, запускать редактор тестов, указывать процесс редактора и патчить память. Там это в одну кнопку вроде делается
Привет Друг! Я пытался преобразовать файл теста (mytestx) .exe в mtf по твоей инструкции но что-то не хочет редактор открывать его. Поможешь мне с одним файлом, буду очень благодарен! https://yadi.sk/d/wWGrSOGM_YJmsA
напиши пожалуйста ответ в вк. спасибо!