Привет, хабровчане. Делимся с вами авторской статьей, которую подготовил Александр Колесников.
Также в рамках профессионального курса «Network engineer» скоро состоится открытый вебинар по теме «NAT — не Firewall». Участники вебинара вместе с экспертом рассмотрят, что такое NAT и почему NAT != firewall, а также разберут различные виды конфигураций для разных ситуаций.
Сетевое взаимодействие — достаточно сложный процесс и порой, чтобы разобраться в том, как он работает, приходится пользоваться абстракциями и дополнительными инструментами, которые позволяют получить информацию об этом взаимодействии. Статья расскажет о том, как писать скрипты для инструмента nmap, и из чего они состоят.
Скриптовый язык и основные фичи
Официальный репозиторий хостится в системе svn, но мы для удобства будем использовать зеркало на github. Даже если не вникать в код проекта, легко можно увидеть, что проект пользуется языком Lua. Это язык программирования, который, как заверяют авторы, очень гибко может работать со структурами данных. Также он поддерживает большое количество парадигм программирования. С основными конструкциями синтаксиса можно познакомиться здесь.
Инструмент nmap использует язык Lua из-за его простоты и легковесности. Изначально этот язык был добавлен для того, чтобы можно было быстро и легко наращивать функционал nmap. Сетевых протоколов существует большое количество, поэтому стандартного взаимодействия по протоколам IP, UDP, TCP и ICMP может быть недостаточно.
Итак, nmap содержит интерпретатор Lua. Интерпретатор языка программирования интегрирован в nmap и взаимодействует с ним за счет фреймворка, который называется Nmap Scripting Engine. NSE умеет запускать скрипты параллельно и работать с интерфейсами ввода/вывода, а так же предоставляет систему обработки ошибок. Все скрипты, которые могут быть написаны для расширения работы nmap, поделены на отдельные задачи. Всего их 14, самые интересные по мнению автора можно найти ниже:
auth — скрипты, которые направлены на сбор аутентификационных данных;
discovery — скрипты, которые собирают информацию из корневых сущностей;
external — скрипты, которые могут использовать сторонние сервисы для предоставления информации;
vuln — скрипты, которые проверяют сервис на известную уязвимость, используются только для проверки;
intrusive — скрипты, которые могут нанести вред исследуемой системе.
В рамках нашей статьи будем создавать скрипт категории discovery.
Пишем скрипт
Каким бы простым не был язык программирования, но чтобы действительно быстро и эффективно писать на нем, нужно использовать IDE. Особенно если это язык программирования, в котором есть API, за счет которых он может связываться с внешним миром. Для написания скриптов NSE будем использовать Halcyon IDE. IDE требует установленной JRE, в запущенном виде выглядит так:
IDE позволяет изучать уже готовые скрипты, просматривать библиотеки, которые доступны для написания новых скриптов, а так же функционал по отладке и запуску скриптов в nmap.
Чтобы начать написание скрипта, нам необходимо понять, как именно скрипт вызывается и какие параметры он может использовать для разбора данных из сети. Базово скрипт может пользоваться той информацией, которую nmap получил по результатам сканирования хоста:
host — объект, который содержит большое количество информации о хосте (ip, OS version);
port — объект, который содержит информацию по порту (протокол, номер, версия).
Помимо перечисленных данных, из скрипта можно взаимодействовать с сетевой подсистемой так, как будто просто пишем приложения для работы по сети. То есть можно создать сокет и использовать его для передачи и получения информации. Помимо этого скрипты могут использовать дополнительные параметры, которые перечисляются для скрипта в командной строке.
Шаблон любого скрипта имеет следующий вид:
portrule = function( host, port )
return true
end
action = function(host, port)
end
portrule — правило, которое используется для определения, должен ли быть запущен скрипт. Позволяет проставить конкретный порт для сканирования. Также можно ограничить по значению хоста: для этого нужно изменить portrule на hostrule. Функция возвращает значение true или false в зависимости от того, совпадает порт или хост или нет.
action — main функция скрипта, срабатывает только в том случае, если rule часть возвратила true. Может возвращать строку или значение nil (пустое значение).
Протестируем скрипт вне IDE, запустим слушателя на порту 7878:
sudo nc -lvvp 7878
Проведем запуск сприпта:
sudo nmap -n --script=testScript.nse 127.0.0.1 -p 7878
Результат работы скрипта:
На снимке представлен пример запуска на любом порту, который отличается от того, что мы указывали в разделе portrule. И наоборот — тот самый порт, который должен быть обработан.
Результат
Скрипт, который может писать нотификации для заданного порта — достаточно простой пример, но именно он демонстрирует основные элементы скрипта для nmap. Читателю предлагается самостоятельно реализовать функционал для работы с http протоколом и получением информации о сервере.
Узнать подробнее о курсе «Network engineer».
Смотреть открытый вебинар по теме «NAT — не Firewall».