Представлять Nmap читателю ][ сродни тому, что объяснять физику-ядерщику, что такое заряженная частица. Nmap знают все, и скорее всего даже хотя бы разок им пользовались. Но вот парадокс: ту изумительную по расширению архитектуру, позволяющую заточить сканер под себя, все упорно обходят стороной. И совершенно напрасно.

Если ты следишь за обновлениями легендарного сканера, которые, кстати говоря, в последнее время выходят особенно часто, то должен был обратить внимание на две цифры, которые фигурируют в каждой записи changelog’а. Первая означает количество обновленных сигнатур для определения сервисов и операционных систем. А вторая — количество новых NSE-скриптов для реализации более тонких проверок и интеллектуального сканирования. Обычно такие скрипты разрабатываются для какойнибудь серьезной уязвимости и используют части оказавшихся в паблике сплойтов. Но то, что оказалось у всех — это уже не так интересно. Другое дело — сделать что-то для себя. Скажем, зная о том, как устроен какой-то свежий троян, добавить в сканер определенные проверки и таким образом, быстро прочесав сеть, порутать сразу множество машин. Как тебе?

 

Fingerprinting своим руками

Конечно, можно написать с нуля программусканер, которая будет отправлять некий запрос, парсить результат и, в конечном счете, возможно, детектировать зараженные машины. И реализовать некое подобие многопоточности тоже несложно. Но разве все это может сравниться с теми механизмами, которые столько времени оттачивались в Nmap? Я так не думаю. Одна из ключевых особенностей сканера — широкие возможнос ти fingerprinting’а, то есть как раз определения версии ОС и работающих сервисов по так называемым отпечаткам пальцев (в терминах Nmap они называются probe). Сервисом может быть обычный WWWдемон, а может — трой. При этом абсолютно необязательно мириться с той базой, которая по умолчанию поставляется со сканером.

Посмотрим, как можно обновить ее самому. В качестве примера возьмем троян, который распространялся в Европе с софтом для зарядок от компании Energizer (мы рассказали о нем в Meganews прошлого номера). На официальном сайте программа уже обновлена, но зараженный вариант по-прежнему доступен в снимках сайтов, сохраненных архиватором интернета Wayback Machine (web.archive.org). Заниматься глубоким реверсингом мы не будем. Хотя расковырять трой достаточно просто (автор не сильно заморачивался, чтобы хоть как-то закриптовать малварь), это уже сделали за нас. На сайте www.symantec.com/connect/blogs/trojan-found-usb-batterycharger-software приведено подробное описание вируса, из которого нам интересны несколько фактов:

  • троян слушает 7777 порт;
  • любые данные, которые троян принимает на этот порт, XOR-ятся со значением 0xE5 перед тем, как обрабатываются далее;
  • команды (запуск процесса, удаление файла, выполнения команды и т.д.) передаются в виде CLSID (уникальный идентификатор вида {XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXXX});
  • перед командой передаются 4 управляющих байта, в которых указывается длина управляющего сообщения.

Одна из таких команд — "{E2AC5089-382043fe-8A4D-A7028FAD8C28}" — проверяет, активен троян в системе или нет. Если вирус принимает и понимает ее, то в ответ он отправляет текст «YES», который так же, как и сама команда, XOR’ится символом 0xE5. Похоже, это как раз то, что поможет нам выявить наличие трояна на удаленной системе. Итак, мы знаем, что отправлять (команду для проверки активности), куда отправлять (порт 7777) и что должны получить («YES»); осталось реализовать проверку.

 

Все Ок? Yes!

Для начала попробуем отправить пакет с командой на порт 7777 вручную. Для этого нам понадобится утилита netcat (с www.securityfocus.com/tools/13 можно скачать ее портированную версию под Windows).

Поскольку троян ожидает данные в закриптованном с помощью XOR’а виде, то придется выполнить такое шифрование. Напишем для этого предельно простую утилиту на Си, хотя то же самое за минуту можно сделать и на любом другом языке.

#include <stdio.h>
int main(int argc, char *argv[])
{
int c;
while((c = getchar()) != EOF)
printf("%c", c ^ 0xE5);
return 0;
}

Все просто: тулза читает символы из стандартного потока вывода, далее для каждого символа осуществляет операцию "XOR 0xE5" и результат, то есть закриптованный текст, отправляет в поток вывода:

$ gcc -o test test.c
$ echo "this is a test" | ./test |
hexdump -C
00000000 91 8d 8c 96 c5 8c
96 c5 84 c5 91 80 96 91 ef
|....A..A.A....i|

Все хорошо, кроме одного момента — в конце у нас нарисовался лишний символ — 0xEF, который означает перевод строки. С другой стороны, не хватает терминального символа завершения строки. Поэтому запускаем команду echo с ключом "-n", чтобы избавиться от перевода строки, и ключом "-e", чтобы та распознала escape-символ "\x00", который мы добавим в конце сообщения:

$ echo -ne "this is a test\x00" |
./test | hexdump -C
00000000 91 8d 8c 96 c5 8c
96 c5 84 c5 91 80 96 91 e5
|....A..A.A....a|

Вот теперь все правильно. Осталось подставить нашу команду "{E2AC5089-3820-43fe8A4D-A7028FAD8C28}", указав перед ней ее размер (38 символов самой команды + 1 терминальный символ = 39 байт, что в шестнадцатеричном представлении дает 27):

echo -ne "\x27\x00\x00\x00{E2AC5089-382043fe-8A4D-A7028FAD8C28}\x00"

По идее, этот пакет должен вызвать ответ трояна. Для этого отсылаем вывод команд с помощью netcat’а на 7777 порт зараженной машины:

$ echo -ne "\x27\x00\x00\x00{E2AC5089-382043fe-8A4D-A7028FAD8C28}\x00" |
./test | # шифруем команду
ncat 192.168.1.123 7777 | # отправляем ее
./test # получаем результат

ответ:

Yes

Да! Троя разговаривает с нами и говорит «YES» — значит, все работает! Как видишь, fingerprinting удаленных сервисов — это далеко не всегда очень сложно.

 

Создаем Probe для Nmap

Теперь самое время перейти к тому, ради чего мы все это и затевали, а именно — созданию слепка для базы Nmap’а. Первое, что нам понадобится — это найти файл nmap-service-probes. Обычно он располагается в c:\program files\nmap (/usr/share/nmap или /usr/local/share/ nmap в случае с никсами). Это самый обычный текстовый конфиг, в котором последовательно перечислены все probe’ы в специальном формате. Если выполнить последнюю команду, но не отправлять ее в netcat, то на экране появится зашифрованная команда, которую и нужно вставить в отпечаток:

# Наш слепок для определения Energizer
trojan
Probe TCP Energizer q|\xC2\xE5\xE5\xE5\x9E\
xA0\xD7\xA4\xA6\xD0\xD5\xDD\xDC\xC8\xD6\xDD\
xD7\xD5\xC8\xD1\xD6\x83\x80\xC8\xDD\xA4\xD1\
xA1\xC8\xA4\xD2\xD5\xD7\xDD\xA3\xA4\xA1\xDD\
xA6\xD7\xDD\x98\xE5|
rarity 8
ports 7777
match energizer m|^\xbc\xa0\xb6$| p/
Energizer backdoor/ o/Windows/
i/**BACKDOOR**/

Вот и все: fingerprinting база обзавелась новым слепком. Обозначение нового элемента fingerprinting-базы начинается с ключевого слова Probe, последовательность байтов обособляется "q|" в начале и символом "|" в конце. Параметр rarity указывает вероятность срабатывания проверки. Ports задает порты, на которые отправляется проверяющая последовательность. С помощью команды match и регулярного выражения в Perl-стиле определяется отчет сервера, на который должен реагировать Nmap. В результате Nmap будет отсылать пакет на порт 7777 аналогично тому, что мы только что сделали с помощью Netcat’а. Если в ответ придет закодированное слово «YES», то сканер определит присутствие троя в системе. Проверим это в действии:

$ nmap -sV -p7777 192.168.1.2
Starting Nmap 5.30BETA1 ( http://nmap.org )
Nmap scan report for 192.168.1.2
Host is up (0.00024s latency).
PORT STATE SERVICE VERSION
7777/tcp open energizer Energizer
backdoor (**BACKDOOR**)
Service Info: OS: Windows

Таким образом, потратив совсем немного времени, мы научили Nmap находить зараженные машины в сети. Важно, что такая проверка никак не выбивается из привычного образа использования Nmap. Для сканируемых хостов будет выполняться еще одна проверка, вот и все. Ты по-прежнему сможешь использовать все остальные возможности Nmap, в том числе и автоматизированные скрипты.

 

NSE — что это?

Стоп, что еще за автоматизированные скрипты? Я говорю о скриптовом движке Nmap Scripting Engine (NSE), который появился еще в 4.21 версии сканера, причем разработчики корпели над ним более 6 месяцев. По сути, в Nmap сейчас больше обновляется не само ядро сканера, а количество поддерживаемых NSE-сценариев.

Например, в последней доступной бете (5.30BETA1) появились 37 новых скриптов: сценарий http-vmware-pathvuln, позволяющий уводить гостевые машины из уязвимых продуктов VMware; mysql-empty-password, который пытается найти базы с пустыми паролями для админа и анонимного пользователя, и т.д. Всего таких скриптов в Nmap 117, но это только в публичном доступе. На самом деле это отличный механизм на случай, когда к мощным возможностям сканирования необходимо добавить больше интеллектуальности или интерактивное общение с удаленным сервисом. В нашем примере, создавая правило для поиска хостов с трояном Energizer, мы смогли обойтись отправкой статического запроса и обработкой ответа. С другой стороны, можно было разобраться со всеми остальными командами троя и, написав несложный скрипт, выполнить последовательность команд, чтобы вытащить полезную информацию с зараженных систем.

Короче говоря, NSE позволяет не только использовать всю мощь Nmap, но и автоматизировать многие действия.

Для написания скриптов используется язык программирования Lua (www.lua.ru). Конечно, было бы вдвойне здорово, если бы в основе NSE был Python (который к тому же использовался для создания отдельных частей сканера), но тут, как говорится, разработчикам виднее. С другой стороны, для Lua, как и для Python, есть много библиотек для взаимодействия с различными сетевыми сервисами и протоколами (подробнее во врезке); они идут вместе с Nmap.

 

Пишем скрипт для Nmap

Для создания NSE-сценариев используется четкий и очень простой синтаксис. В общем виде структура любого скрипта состоит из нескольких элементов.

  • description — описание сценария;
  • categories — его принадлежность к категориям;
  • author — автор скрипта;
  • license — описание лицензии;
  • dependencies — указание зависимостей;
  • port/host rules — правила выполнения скрипта;
  • action — ядро скрипта, реализующее непосредственно логику его работы.

Скриптовый движок Nmap детально описан на nmap.org/book/nse.html, поэтому не буду чрезмерно перегружать тебя теорией. Лучше сразу попробуем собрать простенький сценарий на практике. В прошлом номере у нас был материал «Брутим дедики по-новому», в котором мы делились новыми техниками в брутфорсе RDP-серверов. Предлагаю в дополнение к имеющимся разработкам добавить быстрое сканирование и поиск RPD-серверов с помощью Nmap. Задачей займется самописный NSE-скрипт, который будет экспортировать файл с найденными хостами для дальнейшей работы брутфорса. По сути это всего десяток строк кода на Lua:

description = [[ RDP Servers seachtool ]]
author = "X Group"
license = "Same as Nmap--See http://nmap.
org/book/man-legal.html"
categories = {"discovery"}
require "shortport"
portrule = shortport.port_or_service(3389,
"ms-term-serv")
action = function(host, port)
file = io.open ("ip_with_rdp.
txt","a+")
file:write(host.ip.."\n")
file:flash()
file:close()
end

Кратко пройдемся по исходнику скрипта. В качестве категории NSE-сценария используется значение "discovery", подразумевающее, что скрипт будет осуществлять исследование сети — по большом счету это ни на что не влияет. Далее с помощью require мы подключили NSE-библиотеку для работы с портами. Важная часть любого сценария — условие его выполнения. В скрипте используется либо правило для портов (portrule), в которых перечисляются порты, с которыми будут осуществляться действия, либо правило для хостов (hostrule). В общем смысле правило — это функция, возвращающая true или false. От этого зависит, будет выполняться основная часть скрипта, заданная в action, или нет. В нашем случае мы используем portrule и с помощью функции port_or_service определяе м, что хотим иметь дело с сервисом на порту 3389 или сервисом, распознанным как ms-term-serv. Непосредственно сердце сценариев, в котором определяются действия, у нас очень простое. Если Nmap распознал терминальный RDP-сервис или просто открытый 3389 порт, мы просто записываем его IP-адрес в файл.

Текст скрипта сохраняем в файл (например, rpdlist.nse) и размещаем в папке scripts. Кстати говоря, для удобства разработки скриптов лучше сохранять их с расширением lua, тогда текстовые редакторы, в том числе Notepad++, будут подсвечивать синтаксис. Чтобы запустить скрипт, используется ключ "—script" или его синоним "-sC":

nmap -iR 0 -n -PS 3389 -p T:3389
--script=rpdlist.nse

Вот так просто мы создали многопоточный RPD -сканнер. Если подключить модули для работы с MSRPC, то можно попробовать выцепить список пользователя с удаленного компьютера и также экспортировать его в список. В этом случае, брутфорс будет осуществляться по известным именам пользователей. Настоятельно рекомендую тебе прочитать руководство по NSE nmap.org/book/nse.html, так как в умелых руках это позволит превратить в Nmap в универсальный и чрезвычайно эффективный инструмент.

 

Info

  • Если после установки Nmap, ты задаешься вопросом: «А на чем бы, собственно попробовать сканнер?». Смело используй scanme. nmap.org. Этот хост создатели специально разработали для проверки функциональности сканера.
  • Для того, чтобы выполнить обновления скриптов, запусти nmap с ключом "—script-updatedb": nmap —scriptupdatedb
  • После установки Nmap’а помимо самого сканера ты получае шь ряд интересных утилит.

В недавней версии появилась тулза ncat, которая является улучшенной версией старого доброго nc.

Среди прочих ее достоинств — работа не только с TCP, но и с UDP, а также встроенная возможность проксирования через HTTP/CONNECT и SOCKS. Помимо этого ты получаешь утилиту для удобного сравнения результатов сканирования — ndiff. А с помощью проги nping ты сможешь конструировать запросы, анализировать ответы и измерять время отклика удаленной системы.

 

Готовые библиотеки NSE

Чтобы сделать программирование скриптов на Lua еще более эффективным, в Nmap встроено много дополнительных библиотек, специально заточенных под выполнение различных сетевых проверок. Все они находятся в папке %nmap%/nselib. Чтобы ты не изобретал велосипед, придумывая, например, как выполнить запрос к DNS, привожу список наиболее часто используемых библиотек:

  • backdoor — простейшая реализация бэкдора в системе;
  • bin — работа с двоичными данными;
  • datafiles — библиотека для работы со встроенными файла Nmap (например, nmapprotocols — описанием и номерами портов различных протоколов);
  • default — наиболее часто используемые сетевые сценарии;
  • dns — работа с DNS;
  • http — работа с HTTP;
  • msrpc — библиотека для работы с вызовами MSRPC;
  • mysql — некоторые операции с MySQL;
  • netbios — работа с NetBIOS-трафиком;
  • nmap — взаимодействие с ядром сканера;
  • packer — манипулирование с пакетами в RAW-виде;
  • proxy — работа с прокси;
  • shortport — работа с портами;
  • smb — работа с SMB-протоколом;
  • sss1/ssh2 — работа с SSH.

Любые библиотеки подключаются с помощью команды require.

Оставить мнение

Check Also

Ручная распаковка. Вскрываем кастомный пакер на примере вымогателя GlobeImposter 2.0

При реверсе вирусов зачастую обнаруживается, что малварь накрыта какой-нибудь «навесной» з…