Хакер - Господин Микротиков. Автоматизируем сбор и обработку данных с оборудования MikroTik

Хакер - Господин Микротиков. Автоматизируем сбор и обработку данных с оборудования MikroTik

hacker_frei

https://t.me/hacker_frei

NestorMahno

Содержание статьи

  • Первый этап оптимизации жизнедеятельности сисадмина
  • Второй этап оптимизации. Учим сервер делать работу за нас
  • Планировщик cron или полная автоматизация скрипта
  • Итоги

Пред­ставь, что у нас есть обо­рудо­вание MikroTik, для которо­го написа­ны пра­вила фай­рво­ла про­тив ска­ниро­вания пор­тов. Нам нуж­но вес­ти ежед­невный учет IP-адре­сов и отправ­лять пись­мо с отче­том для отде­ла безопас­ности. Сегод­ня мы в духе извес­тной ци­таты с «Баша» о прог­раммис­те, который авто­мати­зиро­вал все, что занима­ло у него боль­ше 90 секунд, напишем скрипт, что­бы он выпол­нял всю эту работу. По дороге поуп­ражня­емся в адми­нис­три­рова­нии сетей на осно­ве MikroTik.

Как ты пом­нишь, пер­вый этап любой кибера­таки — это раз­ведка. От нее‑то мы и будем защищать­ся. На неко­ем гра­нич­ном мар­шру­тиза­торе MikroTik у нас нас­тро­ены пра­вила Firewall про­тив стан­дар­тно­го ска­на пор­тов (нап­ример, все­ми ува­жаемым ска­нером Nmap).

Пра­вила Firewall про­тив ска­на пор­тов

Все пра­вила нас­тро­ены в таб­лице Raw для обра­бот­ки тра­фика до попада­ния в Connection Tracking и мень­шей наг­рузки на про­цес­сор. В пра­вилах задей­ство­вана цепоч­ка Prerouting, логика работы пра­вил осно­вана на фла­гах TCP (tcp-flags). Если нам с одно­го IP-адре­са пооче­ред­но на раз­ные пор­ты мар­шру­тиза­тора при­лета­ет нес­коль­ко пакетов TCP с фла­гами SYN (полу­откры­тые соеди­нения), то мож­но сде­лать вывод, что работа­ет ска­нер пор­тов. Добав­ляем IP-адрес в Address List и в кон­це дела­ем drop все­го лис­та. Эти сиг­натуры не пре­тен­дуют на уни­каль­ность. Так что, как говорит мой началь­ник, «совер­шенс­твуй и улуч­шай».

Эк­спорт пра­вил Firewall про­тив ска­на пор­тов

INFO

Де­таль­ный раз­бор этих пра­вил выходит за рам­ки статьи. Что­бы вник­нуть под­робнее, читай цикл ста­тей «Сте­на огня» и изу­чай, как работа­ют ска­неры пор­тов.

Спи­сок адре­сов с наз­вани­ем port scanners

ПЕРВЫЙ ЭТАП ОПТИМИЗАЦИИ ЖИЗНЕДЕЯТЕЛЬНОСТИ СИСАДМИНА

Итак, нам нуж­но вес­ти учет количес­тва IP-адре­сов, которые ска­ниру­ют сеть, и ежед­невно отправ­лять Address List в отдел безопас­ности пред­при­ятия для даль­нейше­го ана­лиза и пре­дот­вра­щения атак. Как извес­тно, сис­темный адми­нис­тра­тор сущес­тво ле­нивое занятое, и каж­дый день заходить на мар­шру­тиза­тор и ски­дывать файл с адре­сами для него нерен­табель­но. Начал я с того, что написал скрипт для RouterOS, который ежед­невно сох­ранял Address List в файл и отправ­лял пись­мо на элек­трон­ную поч­ту.

При­мер локаль­ного скрип­та на мар­шру­тиза­торе MikroTik RouterOS

:local sysname [/system identity get name];

:local sysdate [/system clock get date];

:local d [:pick $sysdate begin=4 end=6];

:local m [:pick $sysdate begin=0 end=3];

:local y [:pick $sysdate begin=7 end=11];

########SAVE_ADDRESS_LIST_TO_FILE#############

/ip firewall address-list print from=[ find where list=port_scanners] \

file="$sysname_$d$m$y_port_scanners_list.txt";

:delay 3s;

########SEND_ADDRESS_LIST_TO_MAIL############

/tool e-mail send to=tester025@protonmail.com from=tester075@protonmail.com \

subject=([/system identity get name] . " Port_scanners_address_list " . \

[/system clock get date]) body=("Port scanners address-list of $sysname\nTime and Date stamp: " . \

[/system clock get time] . " " . [/system clock get date] . "\n ") \

file="$sysname_$d$m$y_port_scanners_list.txt";

Скрипт брал основную информа­цию по обо­рудо­ванию, имя устрой­ства, дату, месяц и год, искал соот­ветс­тву­ющий Address List и сох­ранял файл.

Сох­ранен­ный файл

А затем отправ­лял сооб­щение с вло­жен­ным фай­лом на поч­ту.

При­мер получен­ного пись­ма

До­бав­ление это­го скрип­та в Scheduler нем­ного облегчи­ло жизнь, но нуж­но было заходить на поч­ту сох­ранять логи и еже­недель­но под­счи­тывать IP-адре­са.

Пла­ниров­щик и наш скрипт

ВТОРОЙ ЭТАП ОПТИМИЗАЦИИ. УЧИМ СЕРВЕР ДЕЛАТЬ РАБОТУ ЗА НАС

План дей­ствий будет сле­дующий.

  1. Мы напишем на Bash скрипт, который будет заходить на мар­шру­тиза­тор по SSH, сох­ранять файл из Address List и по SCP забирать файл себе.
  2. На­пишем еще один Bash-скрипт, который будет вес­ти еже­недель­ный под­счет IP-адре­сов и отправ­лять безопас­никам эту информа­цию по поч­те, прик­ладывая сам спи­сок.
  3. Вы­пол­ним вся­кие вспо­мога­тель­ные задачи: нас­трой­ку cron и поч­тового кли­ента на сер­вере, генера­цию клю­чей SSH и, конеч­но, нас­трой­ку телег­рам‑бота для получе­ния слу­жеб­ных сооб­щений и (при некото­рой доработ­ке) управле­ния работой скрип­та.

Из инс­тру­мен­тов нам понадо­бит­ся Unix-образная сис­тема (я тес­тировал на Ubuntu, Armbian и Manjaro), пря­мые руки и баноч­ка пива (опци­ональ­но). Прис­тупа­ем к работе!

Сна­чала соз­даем дирек­торию для хра­нения наших скрип­тов и слу­жеб­ных фай­лов:

mkdir /home/user/.scripts/cyber

И еще одну — для хра­нения спис­ка адре­сов, с которых про­исхо­дило ска­ниро­вание:

mkdir /home/user/.scripts/cyber/port_scanners

Так­же нуж­но на сер­вере сге­нери­ровать клю­чи SSH:

ssh-keygen

И вруч­ную най­ти пуб­личный ключ (id_rsa.pub) в катало­ге ~/.ssh. На мар­шру­тиза­торе соз­даем поль­зовате­ля (нап­ример, uServer) и кла­дем пуб­личный ключ SSH (id_rsa.pub) в дирек­торию Files. Далее откры­ваем вклад­ку System → Users → SSH Keys и выбира­ем пуб­личный ключ SSH (id_rsa.pub) для соз­данно­го поль­зовате­ля.

Соз­дание нового поль­зовате­ля

INFO

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

Для монито­рин­га работы скрип­тов мы будем исполь­зовать телег­рам‑бота. Его код я здесь при­водить не буду, но смас­терить его нес­ложно — ищи бота BotFather и дер­зай.

INFO

Под­робнее о том, как писать ботов для Telegram, читай в статье «Те­лег­рафиру­ет робот. Пишем бота для Telegram на Python».

Даль­ше соз­даем груп­пу или канал, даем ей соот­ветс­тву­ющее наз­вание (нап­ример, MikrotControl). Добав­ляем бота в груп­пу и даем ему пра­ва для пуб­ликации сооб­щений.

Даль­ше узна­ем chat id нашей груп­пы. Для это­го откры­ваем спе­циаль­ный URL:

https://api.telegram.org/bot<ваш_токен_телеграм_бота>/getUpdates

В отве­те нас инте­ресу­ет параметр message → chat → id, в нем хра­нит­ся уни­каль­ный иден­тифика­тор чата груп­пы с нашим ботом.

Вы­вод в фор­мате JSON:

"chat": {

"id": -1524684857943,

"title": "MikrotControl",

"type": "supergroup"

},

Те­перь отпра­вим тес­товое сооб­щение от бота в груп­пу или канал. Для это­го есть спе­циаль­ный URL:

https://api.telegram.org/bot<ваш_токен_телеграм_бота>/sendMessage?chat_id=<ідентифікатор_групи>&text=test123

В нашем слу­чае chat ID -1524684857943. Имен­но так, со зна­ком минус.

В груп­пе мы дол­жны получить сооб­щение от бота с тек­стом test123. Даль­ше нуж­но нас­тро­ить бота на сер­вере. Я возь­му за осно­ву готовый скрипт monit2telegram.

Ус­танав­лива­ем кли­ент Git:

sudo pacman -S git

Пе­рехо­дим в дирек­торию /usr/src:

cd /usr/src

Заг­ружа­ем необ­ходимые ресур­сы с GitHub и перехо­дим в заг­ружен­ную дирек­торию:

sudo git clone https://github.com/matriphe/monit2telegram.git

cd monit2telegram

За­тем необ­ходимо ско­пиро­вать файл кон­фигура­ции и скрип­ты в соот­ветс­тву­ющие дирек­тории фай­ловой сис­темы и дать скрип­там пра­ва на исполне­ние:

sudo cp telegramrc /etc/telegramrc

sudo cp sendtelegram.sh /usr/local/bin/sendtelegram

sudo chmod +x /usr/local/bin/sendtelegram

sudo cp monit2telegram.sh /usr/local/bin/monit2telegram

sudo chmod +x /usr/local/bin/monit2telegram

Ус­тановить необ­ходимые зависи­мос­ти (jq):

cd /usr/src

sudo wget https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64

sudo ln -s /usr/src/jq-linux64 /usr/bin/jq

В пер­воначаль­ном кон­фиге /etc/telegramrc нуж­но ука­зать уни­каль­ный TOKEN бота и CHATID нашей груп­пы:

TOKEN='...'

CHATID='...'

Про­верить, при­ходят ли сооб­щения, мож­но так:

sendtelegram -m "test message from server"

В нашей груп­пе мы дол­жны получить сооб­щение от бота с ука­зан­ным тек­стом.

Ну и наконец, пишем наш скрипт.

/home/user/.scripts/cyber/port_scanners.sh

#!/bin/bash

DIR_FILES="/home/user/.scripts/cyber/port_scanners";

# Переменные команд для работы в любых оболочках

CMD_WC=$(which wc)" -l";

CMD_SSH=$(which ssh);

CMD_SCP=$(which scp);

CMD_GREP=$(which grep);

CMD_NMAP=$(which nmap);

CMD_DATE=$(date +%d_%m_%Y);

CMD_SEND2TG=$(which sendtelegram)" -m";

# Переменные для доступа по SSH и работы скрипта

IDL_TIME="5s";

HOST="192.168.100.12";

USER="uServer";

PORT="4200";

IDENTITY="CRT001";

FILE_NAME=$(echo $IDENTITY"_"$CMD_DATE".txt");

SSH_OPT=" -o ConnectionAttempts=5 -o ConnectTimeout=5s \

-o PasswordAuthentication=no -o PreferredAuthentications=publickey \

-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \

-o GlobalKnownHostsFile=/dev/null -o CheckHostIP=no ";

# Переменные для телеграм-бота

DATE1="$(date "+%H:%M:%S")"

DATE2="$(date "+%d %B %Y")"

TEXT="

Port scanners file загружен на сервер *$HOSTNAME* в директорию *$DIR_FILES*

Время: $DATE1

Дата: $DATE2"

PAYLOAD="$TEXT&parse_mode=Markdown&disable_web_page_preview=true"

# Копирование файла с RouterOS на localhost

SCP_STR_FILE="$CMD_SCP -2 -4 -B $SSH_OPT -P $PORT $USER@$HOST:/$FILE_NAME $DIR_FILES";

# Сохранение address-list на RouterOS в файл

FILE_CRT="/ip firewall address-list print from=[ find where list=port_scanners] file=$FILE_NAME";

# Удаление файла из address-list на RouterOS

FILE_CLN="/file remove [find name=$FILE_NAME];/ip firewall address-list remove [find where list=port_scanners]";

# Подключение по протоколу SSH на RouterOS

SSH_STR="$CMD_SSH -p $PORT $USER@$HOST $SSH_OPT";

# Проверка доступности целевого хоста (маршрутизатор MikroTik) для написания условий

DEST_HOST=$($CMD_NMAP -p $PORT $HOST -Pn | $CMD_GREP -ic open);

# Если хост недоступен, отправляем сообщение в группу

if [ "$DEST_HOST" = 0 ]; then

$CMD_SEND2TG "cannot connect to $HOST"

fi;

# Если доступен, то сохраняем файл, копируем его в заданную директорию, удаляем с маршрутизатора и пишем об удачной отработке скрипта в группу

if [ "$DEST_HOST" = 1 ]; then

$SSH_STR $FILE_CRT

sleep $IDL_TIME && $SCP_STR_FILE

sleep $IDL_TIME && $SSH_STR $FILE_CLN

$CMD_SEND2TG "$PAYLOAD";

fi;

Ду­маю, логика скрип­та понят­на, поэто­му идем даль­ше.
Для генера­ции элек­трон­ного пись­ма нам необ­ходимо соз­дать файл old_date с датой отправ­ки пер­вого пись­ма для ИБ‑отде­ла:

echo 05.09.2021 > /home/user/.scripts/cyber/old_date

Так­же соз­даем допол­нитель­ный файл mail_body_text с тек­стом сооб­щения для нашего элек­трон­ного пись­ма:

echo Cybersecurity report with port scanners files > /home/user/.scripts/cyber/mail_body_text

Для элек­трон­ной поч­ты уста­новим mutt:

yaourt mutt

Да­лее необ­ходимо соз­дать файл кон­фигура­ции home/user/.scripts/cyber/.muttrc:

sudo vi home/user/.scripts/cyber/.muttrc

Ос­новные нас­трой­ки фай­ла home/user/.scripts/cyber/.muttrc:

set from = "username@protonmail.com" set realname = "Nestor" \

set imap_user = "username@protonmail.com" set imap_pass = "security_password" \

set folder = "imaps://imap.protonmail.com:993" set spoolfile = "+INBOX" \

set postponed ="+[Protonmail]/Drafts" set header_cache =~/.mutt/cache/headers \

set message_cachedir =~/.mutt/cache/bodies set certificate_file =~/.mutt/certificates \

set smtp_url = "smtp://username@smtp.protonmail.com:587/" set smtp_pass = "security_password" \

set move = no set imap_keepalive = 900

Для про­вер­ки элек­трон­ной поч­ты исполь­зуем такую коман­ду:

mutt -s Subject -a /home/user/.scripts/cyber/Cybersecurity_report.txt -- recepient_name@protonmail.com < Test message body

Те­перь напишем скрипт для под­сче­та IP-адре­сов и отправ­ки элек­трон­ного пись­ма для синей коман­ды vim /home/user/.scripts/cyber/report_mail.sh. Все фун­кции скрип­та про­писа­ны в ком­мента­риях в нем.

#!/bin/bash

# Переменные команд для работы в любых оболочках

CMD_DATE=$(date +%d.%m.%Y);

CMD_WC=$(which wc)" -l";

CMD_RM=$(which rm)" -r";

CMD_CAT=$(which cat);

CMD_EXPR=$(which expr);

CMD_SEND2TG=$(which sendtelegram)" -m";

CMD_MUTT=$(which mutt)" -s Cybersecurity_logs -a";

# Переменные директорий

DIR_FILES="/home/user/.scripts/cyber/port_scanners";

DIR_REPORT="/home/user/.scripts/cyber";

# Переменные файлов

FILE_REPORT="Cybersecurity_report.txt";

FILE_OLD_DATE="old_date";

FILE_MAIL="mail_body_text";

# Переменные для телеграм-бота

DATE1="$(date "+%H:%M:%S")"

DATE2="$(date "+%d %B %Y")"

TEXT="$DATE2 : Доклад и $RESULT IP-адресов для отдела ИБ отправлен на электронную почту recepient_name@protonmail.com";

# Берем старую дату предыдущего доклада для генерации нового

OLD_DATE=$($CMD_CAT "$DIR_REPORT/$FILE_OLD_DATE");

# Подсчет IP-адресов из сохраненных за неделю файлов

IP_SUM=$($CMD_CAT "$DIR_FILES"/* | $CMD_WC);

RESULT=$($CMD_EXPR $IP_SUM - 35);

# Удаляем старый Cybersecurity_report.txt

$CMD_RM "$DIR_REPORT/$FILE_REPORT";

# Генерируем рапорт для синей команды

if ! [[ -r $DIR_REPORT/$FILE_REPORT ]];

then

echo "

Доклад на 10:00 с $OLD_DATE г. по $CMD_DATE г. зафиксировано $RESULT IP адресов, с которых производилось сканирование сети. Файлы с ІР-адресами во вложении к докладу.

Системный администратор Нестор Иванович Махно

$CMD_DATE года" > $DIR_REPORT/$FILE_REPORT;

# Замена переменной старой даты для последующего доклада

echo $CMD_DATE > "$DIR_REPORT/$FILE_OLD_DATE";

# Отправка электронного письма с вложениями

$CMD_MUTT "$DIR_REPORT/$FILE_REPORT" "$DIR_FILES"/* --recepient_name@protonmail.com < "$DIR_REPORT/$FILE_MAIL";

# Сообщение в группу «Телеграма» об удачной отправке

$CMD_SEND2TG "$TEXT";

# Удаление файлов с address-list port_scanners

#$CMD_RM "$DIR_FILES"/*;

else

# Сообщение в группу «Телеграма» о неудачной отработке скрипта

$CMD_SEND2TG "cyber.sh не отработал";

fi;

При­веду крат­кое пояс­нение час­ти скрип­та для под­сче­та IP-адре­сов из сох­ранен­ных фай­лов за неделю.

IP_SUM=$($CMD_CAT "$DIR_FILES"/* | $CMD_WC);

RESULT=$($CMD_EXPR $IP_SUM - 35);

Вот как выг­лядит экспорт спис­ка адре­сов.

Как мы видим, пер­вые пять строк не несут смыс­ловой наг­рузки.

С помощью ути­литы wc мы счи­таем все стро­ки в фай­лах из дирек­тории /home/user/.scripts/cyber/port_scanners, а так как док­лад у нас за целую неделю, то 35 слу­жеб­ных строк мы не учи­тыва­ем.

Ну и пос­мотрим, как работа­ет опо­веще­ние телег­рам‑бота в нашей груп­пе.

Опо­веще­ние телег­рам‑бота в груп­пе

ПЛАНИРОВЩИК CRON ИЛИ ПОЛНАЯ АВТОМАТИЗАЦИЯ СКРИПТА

Для нор­маль­ного запус­ка наших скрип­тов соз­дадим сим­воличес­кие ссыл­ки:

sudo ln -s /home/user/.script/cyber/port_scanners.sh /usr/bin/port_scanners.sh

sudo ln -s /home/user/.script/cyber/report_mail.sh /usr/bin/report_mail.sh

Даль­ше необ­ходимо открыть пла­ниров­щик cron:

crontab -e

И про­писать в нем сле­дующие стро­ки для запус­ка наших сим­воличес­ких ссы­лок на скрип­ты:

00 10 * * * /usr/bin/port_scanners.sh

30 12 * * 3 /usr/bin/report_mail.sh

Те­перь каж­дый день в 10:00 будет запус­кать­ся наш скрипт для сбо­ра адре­сов, а каж­дую сре­ду в 12:30 под­счи­тыва­ется чис­ло айпиш­ников, генери­рует­ся и отправ­ляет­ся элек­трон­ное пись­мо.

ИТОГИ

От­дел безопас­ности получа­ет необ­ходимые дан­ные, информа­ция не занима­ет память мар­шру­тиза­тора MikroTik, а всю работу выпол­няет наш сер­вер. Сис­темный адми­нис­тра­тор при этом кон­тро­лиру­ет выпол­нение в груп­пе или канале Telegram, а в сэконом­ленное вре­мя почиты­вает «Хакер»!

Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei

Report Page