Содержание статьи
Ханипот на Amazon
Поднимаем ловушку для червей и сплоитов в облаке
В арсенале любой антивирусной компании есть большая сеть так называемых ханипотов — намеренно уязвимых машин, используемых для детектирования новых видов малвари. Мы тоже можем создать такую ловушку-приманку, попытавшись поймать приватный сплоит. Причем сделать ее абсолютно безопасно для себя, подняв ханипот в облаке.
Цель
В марте Microsoft выпустила патч и опубликовала бюллетень по безопасности MS12-020, предупреждающий о критических уязвимостях в протоколе удаленного рабочего стола, потенциально влекущих за собой возможность удаленного выполнения кода. В Сети тогда начали появляться как фейковые, так и настоящие PoC, вызывающие на удаленной машине BSoD, и особенно резвые товарищи уже начали портировать эти скрипты в модуль для Metasploit (сейчас он уже доступен). Это было интересное время, чтобы поднять свой ханипот и посмотреть на возможные атаки на RDP-сервис. И очень просто — достаточно открыть в файрволе порт 3389 и смотреть все, что на него приходит: если бы появился червь с боевой нагрузкой, то он вполне реально мог «отметиться» в наших логах. Но где взять сервер? У Amazon!
Бесплатный дедик
Арсенал облачных сервисов довольно большой, но наиболее популярны три из них: Amazon Elastic Compute Cloud (сокращенно EC2) — технология, с помощью которой ты можешь запустить в «облаке» любое количество компьютеров с нужным тебе конфигом и операционной системой; Amazon Elastic Block Store (или EBS) — технология виртуализации жесткого диска, с помощью которой можно создать виртуальный диск для своего виртуального сервера; Amazon Simple Storage Service (или S3) — технология, предназначенная для хранения файлов, этакий бесконечный контейнер для файлов, которые при желании становятся доступными через веб. Нас прежде всего интересует EC2, позволяющий создать виртуальный сервер. «Но за это же надо платить!» — возможно, резонно заметишь ты. Однако я не сказал о самом привлекательном. Amazon в рамках акции AWS Free Usage Tier предоставляет возможность «потрогать облака» бесплатно. Конечно, на бесплатную версию накладываются определенные ограничения: ежемесячно пользователям предоставляется 750 часов использования инстанса EC2, 10 Гб для EBS и 5 Гб для S3. Этих ресурсов вполне хватит, чтобы поднять свой собственный забугорный выделенный сервер. Мы, кстати, это уже использовали, когда поднимали на EC2 свой собственный VPN. Тогда же мы более подробно рассказывали о технологиях Amazon, поэтому рекомендую прочитать статью «Бесплатный VPN от Amazon» (][ #1 2011).
Зарегистрироваться и получить доступ к облачным сервисам можно по следующему адресу: aws.amazon.com. Нажимаем кнопку «Sign up now», на странице регистрации выбираем «I am a new user» и пошагово выполняем процедуру создания и верификации аккаунта. Единственно, что для успешной регистрации потребуется пластиковая карта (Visa или MasterCard). Если у тебя нет карты или ты по какой-то причине не хочешь ее задействовать, то можно без проблем приобрести виртуальную кредитную карту, например в терминалах QIWI. На последнем шаге регистрации необходимо будет указать свой номер телефона, после чего система совершит автоматический дозвон и приятным женским голосом попросит ввести четырехзначный пин-код, который будет отображен на экране компьютера. После этого можно перейти к созданию и настройке сервера.
Создаем и настраиваем сервер
Важное преимущество облачных сервисов перед обычным хостингом — возможность быстро, буквально в два клика поднять новый сервер (или к примеру три десятка — без разницы). Как это выглядит? Заходим на сайт под созданным аккаунтом и открываем «My Account / Console & AWS Management console». Там выбираем тип сервиса «Amazon EC2». Для создания сервера (в терминологии Amazon — instance’а) нажимаем на кнопку «Launch Instance». После чего запускаем мастер настройки сервера. Amazon предлагает на выбор различные варианты ОС для установки. Образ с операционной системой называется AMI (Amazon Machine Image), причем, помимо файлов самой системы, в него может быть включен нужный софт (к примеру, Apache, MySQL, Memcached и так далее), а также все необходимые файлы. Я для работы выбрал Ubuntu (имя образа — ami-baba68d3). На следующей вкладке важно установить тип инстанса — Micro Instance, использование которого бесплатно в рамках временного предложения Amazon. Если выбрать сервер помощнее, придется платить за каждый час его использования. Дальше, в принципе, все можно оставлять по дефолту, нас будут интересовать только третий и четвертый шаг. На третьем шаге необходимо будет создать пару открытый/приватный ключ для авторизации на нашем сервере, а на четвертом нужно настроить правила файрвола, чтобы была возможность подключиться к хосту по SSH. Для этого надо в выпадающем списке «Create a new rule» выбрать пункт «SSH» и нажать кнопку «Add Rule».
Настройка внешнего файрвола на Amazon
В результате мы получаем полноценный сервер с Ubuntu на борту. Самое время его запустить. Для этого в «AWS Management Console» выбираем пункт «Instances», видим только что созданный нами инстанс. Кликаем по нему правой кнопкой и в появившемся контекстном меню нажимаем на «Start». Как только в колонке «State» появится значение «Running», это будет свидетельствовать о том, что сервер удачно запустился. В нижней части консоли на вкладке «Description» можно посмотреть детальную информацию об инстансе. Параметр Public DNS определяет внешнее имя сервера (правда, при каждом запуске инстанса он будет меняться). Чтобы при каждом подключении не лезть и не смотреть новое имя сервера, идем в раздел «Elastic IPs» и задаем статический адрес. Нажимаем «Allocate New Address», в появившемся окне выбираем «EIP used in» равное EC2 и нажимаем «Yes, Allocate». Адрес выделен, теперь надо связать его с инстансом – кликаем на нем правой кнопкой мыши и нажимаем «Associate», в появившемся окне выбираем инстанс, для которого хотим установить этот адрес, и нажимаем «Yes, Associate». После чего для подключения к серверу будет использоваться статический адрес. Попробуем подключиться к серверу через SSH:
ssh -i antskey.pem ubuntu@23.21.97.235
Тут antskey.pem — пара ключей, которые были сгенерированы при создании инстанса, ubuntu — имя пользователя, а 23.21.97.235 — адрес инстанса. Если же ты хочешь подключиться из-под винды при помощи PuTTY, то сначала придется сконвертировать приватный ключ в ppk-формат при помощи утилиты PuTTYgen. Для успешного подключения необходимо указать PuTTY IP-адрес инстанса и приватный ключ, после чего можно открывать соединение с удаленным сервером.
Ханипот для MS12-20 RDP
Бесплатным дедиком мы обзавелись, осталось поднять на нем ханипот. Поскольку сервер у меня был на Linux’е, необходимо было поднять непосредственно сервис RDP:
sudo apt-get install xrdp
В случае успешной установки RDP сервер должен автоматически запуститься. Проверить это можно следующим образом:
netstat -an | grep 3389
tcp 0 0 0.0.0.0:3389 0.0.0.0:* LISTEN
Как видишь, сервер успешно стартанул на стандартном порту RDP (3389) и ждет подключений. Все это прекрасно, но Amazon’овский файрвол режет все подключения к нашему серверу, кроме тех, что мы разрешим. Поэтому необходимо опять зайти в «AWS Management Console», выбрать пункт «Security Groups», выбрать группу, в которой находится наш инстанс, и добавить правило, разрешающее подключаться по RDP к нашему серверу. Делается это опять же очень просто — достаточно выбрать в выпадающем списке RDP и кликнуть на «Add Rule». Теперь порт 3389 на нашей машине открыт для внешних подключений. Осталось только приказать tcpdump’у сохранять все пакеты, отправляемые на этот порт:
# sudo tcpdump tcp port 3389 -i eth0 -vvX >> /home/ubuntu/rdplog.txt &
Чтобы проверить, попробуем, к примеру, просканировать наш хост сканером nmap:
# nmap -T4 -A -v 23.21.97.235
Сканер сообщил, что обнаружил два открытых порта: 22 и 3389. Отлично, теперь зайдем на сервер, посмотрим, попало ли что-нибудь в лог. Как видим, tcpdump превосходно справился со своей работой, аккуратно сохранив все пакеты в лог-файл.
Лог, собранный tcpdump'ом
Остается перезапустить tcpdump и оставить сервер на ночь поработать, может быть, утром в логе обнаружится что-то интересное. Наутро ничего интересного не нашлось, и на следующее — тоже :). Очень скоро для Metasploit появился работающий сплоит, который клал на лопатки виндовую систему, но, естественно, никто не пытался использовать его для создания червя. Я опробовал его на своем хосте — и это была первая запись в логе снифера, сохранившая боевую нагрузку. Появится ли сплоит с боевым применением, позволяющий выполнить код, — вопрос открытый. Мой ханипот по-прежнему активен и ждет своего часа :).
Пытаемся проэксплуатировать уязвимость в протоколе RDP на нашем сервере
Тюним SSH для борьбы с брутфорсом
Разумеется, ханипот можно заточить под самые разные задачи. Не секрет, что немало людей по всему миру сканируют подсети и пытаются сбрутить пароли для подключения к дедикам. В том числе по протоколу SSH. Бороться с этим можно разными способами: разрешать подключение только с определенных адресов, блокировать атакующего с помощью файрвола после нескольких неудачных попыток залогиниться и так далее. У нас же абсолютно противоположная задача — мы предоставим атакующему фейковый SSH, который будет записывать в лог передаваемую им информацию (адрес атакующего, имя пользователя для подключения, пароль). Начнем мы с того, что перенесем нормальный SSH-сервер на другой порт. Пусть это будет порт 2222.
# sudo cp /etc/ssh/sshd_config /etc/ssh_sshd_config.bak2
# sudo nano /etc/ssh/sshd_config
Сначала делаем бэкап конфигурационного файла sshd_config, затем открываем его в редакторе nano. Ищем строку «Port 22» и меняем ее на «Port 2222». Теперь надо ребутнуть сервер. Сделать это можно из «AWS Management Console». Теперь если попробовать подключиться к SSH на 22-м порту, то получим сообщение об ошибке «Network error: Connection refused». Логично: SSH-сервер слушает совсем другой порт. Однако перед тем как подключиться к SSH-серверу на порту 2222, необходимо опять поднастроить файрвол Amazon’а. Создаем новое правило «Custom TCP rule», указываем «Port range» равным 2222, а «Source» оставляем по умолчанию равным 0.0.0.0/0. Добавляем правило и нажимаем «Apply Rule Changes». После чего легко коннектимся к серверу по SSH.
Зашкаливающее число попыток подобрать пароль к SSH
Теперь займемся созданием SSH-сервера, который будет сохранять информацию, передаваемую атакующим. Нам потребуются исходники OpenSSH, компилятор GCC, утилита make, библиотеки libssl-dev и zlib1g-dev.
# sudo apt-get update
# sudo apt-get install libssl-dev
# sudo apt-get install zlib1g-dev
# sudo apt-get install make
# sudo apt-get install gcc
# wget http://openbsd.org.ar/pub/OpenBSD/OpenSSH/portable/openssh-5.9p1.tar.gz
# tar xvzf openssh-5.9p1.tar.gz
# cd openssh-5.9p1
# ./configure
# make
Устанавливаем необходимые библиотеки, компилятор, скачиваем исходники OpenSSH, распаковываем и компилируем. Компиляция проходит успешно, теперь надо запустить полученный сервер. Но перед этим разберемся с конфигурационными файлами. Скопируем sshd_config в папку /usr/local/etc:
# sudo cp sshd_config /usr/local/etc
Открываем и правим:
# sudo nano /usr/local/etc/sshd_config
Параметр Port устанавливаем в значение 22, чтобы наш поддельный сервер использовал дефолтный порт; включаем возможность аутентификации по паролю — «PasswordAuthentication yes»; отключаем опцию UsePAM, закомментировав ее, так как мы собрали OpenSSH без поддержки PAM; сохраняем и выходим. Запускаем сервер, предварительно создав необходимую ему директорию /var/empty:
# sudo mkdir /var/empty
# sudo /home/ubuntu/openssh-5.9p1/sshd
Чтобы убедиться, что сервер успешно запущен, поищем его в списке процессов:
# ps aux | grep sshd
В списке процессов фигурируют два sshd: /usr/sbin/sshd, запущенный системой, и /home/ubuntu/openssh-5.9p1/sshd, запущенный нами вручную. Команда
# netstat -an | grep 22
покажет, что запущенные серверы слушают порты 22 и 2222. Теперь надо научить наш SSH-сервер сохранять данные, передаваемые атакующим. Убиваем запущенный нами сервер и идем в папку с сорцами. Нас интересует один файл, в котором происходит проверка введенного пароля, — это auth-passwd.c. Рекомендую, прежде чем проводить с ним какие-либо манипуляции, создать его резервную копию. Итак, открываем исходный файл для редактирования. Первое, что потребуется сделать, — это подключить еще один заголовочный файл: #include "canohost.h". После чего пролистываем код немного ниже и видим функцию auth_password. Она-то как раз нам и нужна. Слегка модифицируем ее. Сразу после строки «int result, ok = authctxt->valid;» вставим приведенный ниже код:
if (*password != '')
{
struct tm *timePtr;
time_t localTime;
char timeString[100];
localTime = time(NULL);
timePtr = localtime(&localTime);
strftime(timeString, 100, "%D %r", timePtr);
FILE *logFile;
logFile = fopen("/var/log/sshd_attempts","a+");
fprintf (logFile,"From: %s at: %s | user: %s, pass: %sn",
get_remote_ipaddr(), timeString, authctxt->user,
password);
fclose (logFile);
}
Как видно из листинга, если пароль не пуст, то мы сохраняем в файл /var/log/sshd_attempts адрес атакующего, имя пользователя, используемое для подключения, и пароль.
Патчим SSH для сохранения информации о злоумышленнике
Сохраняем измененный файл и заново собираем OpenSSH при помощи утилиты make. Ну что ж, теперь все готово, запускаем наш пропатченный сервер:
# sudo /home/ubuntu/openssh-5.9p1/sshd
Теперь пришло время поиграть в злоумышленников — попробуем подобрать пароль к собственному серверу. Запускаем еще один экземпляр PuTTY, вводим адрес сервера (23.21.97.235) и соединяемся. Нам предлагают ввести логин, пусть это будет root. А дальше надо угадать пароль для него :). Вручную подбирать пароль надоедает быстро, так что пойдем лучше проверим, что у нас появилось в логе. А в логе появились записи вида:
From: 72.241.54.74 at: 03/27/12 11:33:58 AM | user: root, pass: IT
Как видишь, все прекрасно работает. Единственно, если сейчас просканировать сервер, то сканер покажет три открытых порта — 22, 2222, 3389. Чтобы порт 2222 не вызывал лишних подозрений, его можно временно закрыть амазоновским файрволом.
INFO
Подробная информация о MS12-20: bit.ly/ADJcA6.
Противодействие сканированию портов
А теперь мы немножечко коснемся того, как затруднить жизнь атакующему. Каждая атака на начальном этапе включает в себя изучение цели. В большинстве случаев злоумышленников интересуют установленные сервисы, версия ОС, открытые порты. Всю эту информацию можно получить с помощью сканирования удаленной машины. Существуют инструменты, способные обнаружить сканирование портов и заблокировать атакующего, настроив соответствующим образом правила файрвола. Мы же пойдем от обратного и изобретем собственный велосипед для противодействия SYN-сканированию (опция -sS в nmap). Данный тип сканирования работает следующим образом: атакующий отправляет SYN-пакет на заданный порт, как если бы он хотел открыть соединение с удаленным хостом. Если удаленный хост отвечает SYN/ACK-пакетом, то это означает, что порт открыт. Если в ответ приходит RST(Reset)-пакет, то порт закрыт. Если же после нескольких передач от удаленного хоста так и не приходит ответа, то порт помечается как filtered. Многие инструменты для противодействия сканированию просто блокируют атакующего, мы же поступим хитрее — создадим иллюзию, что у нас открыт любой порт, какой бы он ни просканировал. Для этого нам понадобится, во-первых, настроить на своем хосте файрвол, чтобы он блокировал все исходящие RST-пакеты, указывающие, что этот порт закрыт, во-вторых, написать небольшой скриптик, который вместо RST-пакетов будет отсылать поддельные SYN/ACK-пакеты, говорящие о том, что порт открыт.
Итак, первым делом добавляем правило, блокирующее исходящие RST-пакеты:
# sudo iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP
Для дальнейших манипуляций нам понадобится установить Scapy:
# sudo apt-get install python-scapy
Scapy — это сетевая утилита, написанная на языке Python, которая позволяет посылать, просматривать и анализировать сетевые пакеты. В отличие от многих других утилит, утилита Scapy не ограничена только теми протоколами, пакеты которых она может генерировать. Фактически она позволяет создавать любые пакеты и комбинировать атаки различных типов. Запускаем:
# sudo scapy
и говорим, чтобы он отлавливал все сетевые пакеты, пока их количество не будет равно count:
>>> sniff(count=1)
Если нужно анализировать отловленные пакеты, то можно поступить следующим образом:
>>> p = sniff(count=100)
Как только Scapy перехватит 100 пакетов, можно будет их просмотреть/проанализировать. Например, следующая команда выводит краткую информацию по первым 20 пакетам:
>>> p[0:19].summary()
Детальную информацию о каждом пакете можно посмотреть так:
>>> p[2].dst // адрес назначения
>>> p[2][Ether] // Ethernet кадр
>>> p[2][IP] // заголовок IP-пакета и содержимое
В общем, если хочешь попробовать все возможности инструмента — почитай документацию на официальном сайте, мы же их подробно рассматривать не будем. Наша задача — написать простенький скриптик, использующий Scapy, который будет сообщать атакующему, что каждый просканированный порт является открытым. Приступим. Создаем файл для редактирования:
# nano antiscan.py
и пишем следующий код:
#!/usr/bin/env python
import sys
from scapy.all import *
def findSYN(p):
flags = p.sprintf("%TCP.flags%")
if flags == "S": # отвечаем только на SYN-пакеты
ip = p[IP] # полученный IP-пакет
tcp = p[TCP] # полученный TCP-сегмент
i = IP() # отправляемый IP-пакет
i.dst = ip.src
i.src = ip.dst
t = TCP() # отправляемый TCP-сегмент
t.flags = "SA"
t.dport = tcp.sport
t.sport = tcp.dport
t.seq = tcp.ack
new_ack = tcp.seq + 1
print "SYN/ACK sent to ",i.dst,":",t.dport
send(i/t)
sniff(prn=findSYN)
Принцип работы скрипта прост — разбираем полученный SYN-пакет и конструируем ответ, сообщающий, что данный порт открыт. Скрипт готов, делаем его исполняемым и запускаем:
# chmod +x antiscan.py # sudo /home/ubuntu/antiscan.py
Перед тем как перейти к сканированию нашего хоста, необходимо добавить три правила в Security-Group для нашего инстанса — All TCP, All UDP, All ICMP. Теперь можно запускать сканирование:
# nmap -T4 -A -v 23.21.97.235
После чего видим, что сканер обнаружил огромное число открытых портов. Значит, мы добились своей цели.
Злоумышленник видит, что все порты открыты
Заключение
Как видишь, поднять собственный ханипот не так уж сложно. Нужно лишь немного терпения и хороший сервер. В качестве площадки для экспериментов отлично себя зарекомендовал сервис Elastic Compute Cloud от Amazon. Во-первых, такой сервер очень быстро создается; во-вторых, на нем нет никаких важных данных и его не жалко; в-третьих, он пока бесплатен. Сама же тема создания ханипотов достаточно обширная, и я рекомендую продолжить эксперименты, вооружившись специализированной утилитой honeyd.
Удобное управление EC2
Веб-консоль для управления AWS хотя и предоставляет все необходимое, не всегда удобна. Для более комфортной работы лучше установить специальный плагин Elasticfox для Firefox. Настройка аддона сводится к указанию в настройках полученных во время регистрации AWS Access Key и AWS Secret Access Key. Помимо этого, сам Amazon предоставляет набор консольных утилит (s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip) для взаимодействия с EC2.