MikroTik + port knoking over ICMP

от автора

Совсем маленький пост рассказывающий, как отловить ICMP пакеты и отфильтровать их с логикой.

Реализуем технология port knoking на RouterOS через протокол icmp.

Прошу под кат.

Наверное нету смысла рассказывать, что такое port knoking, так как в интернете довольно-таки много описаний про него.
Если совсем кратко то технология позволяет при определённом порядке перебора портов, при условии что перебор выполнен верно, выполнять различные действия.
Я же вам покажу как можно реализовать данную технологию через протокол ICMP которые не поддерживает порты. И мы будем апеллировать размером пакетов и различными другими свойствами ICMP пакета.

Добавляем себя в white_list

У нас есть правило в фильтре

[admin@kirilka] /ip firewall filter> print  Flags: X - disabled, I - invalid, D - dynamic   0   chain=input action=accept protocol=tcp src-address-list=white_list_ssh in-interface=ether1 dst-port=22  

Которое говорит, что разрешать входящие соединение по 22 порту (ssh), со всех адресов которые содержаться в white_list.
Добавим два правила
Зададим критерия, нужна простая проверка уз двух подходов. Пусть будет первых стук пакет размером 70, а второй 100, а также обязательно по два пакета.
Не забываем, что заголовок пакета ICMP 28 байт.
И так у нас вырисовывается следующая картина мы должны два раза стукнуться по ICMP с размером пакета 98байт и два раза стукнуться с размером пакета 128 байт.

Ловим первый пакет с размером 98 байт.

chain=input action=add-src-to-address-list protocol=icmp address-list=ICMP_SSH_98_stage1 address-list-timeout=1m in-interface=ether2 packet-size=98 

Пакет размером 98 байт по протоколу ICMP заносим исходящий адрес в лист ICMP_SSH_98_stage1

Ловим второй пакет с размером 98 байт.

chain=input action=add-src-to-address-list protocol=icmp src-address-list=ICMP_SSH_98_stage1 address-list=ICMP_SSH_98_stage2 address-list-timeout=1m  in-interface=ether2 packet-size=98 

Пакет размером 98 байт по протоколу ICMP и исходящий адрес уже содержится в листе ICMP_SSH_98_stage1, то заносим исходящий адрес в лист ICMP_SSH_98_stage2

Мы поймали два пакета по 98 байт или 70 байт при отправлении.

Ловим третий пакет с размером 128 байт.

chain=input action=add-src-to-address-list protocol=icmp src-address-list=ICMP_SSH_98_stage2 address-list=ICMP_SSH_128_stage1 address-list-timeout=1m in-interface=ether1 packet-size=128 

Пакет размером 128 байт по протоколу ICMP и исходящий адрес уже содержится в листе ICMP_SSH_98_stage2, то заносим исходящий адрес в лист ICMP_SSH_128_stage1

Ловим четвёртый пакет(последний) с размером 128 байт.

chain=input action=add-src-to-address-list protocol=icmp src-address-list=ICMP_SSH_128_stage1 address-list=white_list_ssh address-list-timeout=1h in-interface=ether1 packet-size=128 

Пакет размером 128 байт по протоколу ICMP и исходящий адрес уже содержится в листе ICMP_SSH_128_stage1, то заносим исходящий адрес в лист white_list_ssh на 1 час.

Я специально сделал первый пример немного не правильно, чтобы вы смогли увидеть последовательность действий.
Для того чтобы всё заработало вам необходимо порядок правил переместить в обратном порядке. Смотри под спойлером.

Полностью таблица фильтров

[admin@kirilka] /ip firewall filter> print Flags: X - disabled, I - invalid, D - dynamic   0   chain=input action=accept protocol=tcp src-address-list=white_list_ssh in-interface=ether2 dst-port=22    1   chain=input action=add-src-to-address-list protocol=icmp src-address-list=ICMP_SSH_128_stage1 address-list=white_list_ssh address-list-timeout=1h in-interface=ether1 packet-size=128    2   chain=input action=add-src-to-address-list protocol=icmp src-address-list=ICMP_SSH_98_stage2 address-list=ICMP_SSH_128_stage1 address-list-timeout=1m  in-interface=ether1 packet-size=128    3   chain=input action=add-src-to-address-list protocol=icmp src-address-list=ICMP_SSH_98_stage1 address-list=ICMP_SSH_98_stage2 address-list-timeout=1m in-interface=ether1 packet-size=98    4   chain=input action=add-src-to-address-list protocol=icmp address-list=ICMP_SSH_98_stage1 address-list-timeout=1m in-interface=ether1 packet-size=98   


Собственно здесь всё просто.

Поехали дальше удаляем себя из адрес листов.

Многие кто настраивают MikroTik используют защиту от перебора паролей Bruteforce wiki.mikrotik.com/wiki/Bruteforce_login_prevention
Бывает сам отрубаю себе руки. Так что сейчас мы будем удалять себя из листов в которые мы могли попасть.
И так используем наработки которые у нас были из прошлого примера изменим только конечный лист на plsdelme

[admin@kirilka] /ip firewall filter> print Flags: X - disabled, I - invalid, D - dynamic   0   chain=input action=add-src-to-address-list protocol=icmp src-address-list=ICMP_SSH_128_stage1 address-list=plsdelme address-list-timeout=1m  in-interface=ether1 packet-size=128    1   chain=input action=add-src-to-address-list protocol=icmp src-address-list=ICMP_SSH_98_stage2 address-list=ICMP_SSH_128_stage1 address-list-timeout=1m  in-interface=ether1 packet-size=128    2   chain=input action=add-src-to-address-list protocol=icmp src-address-list=ICMP_SSH_98_stage1 address-list=ICMP_SSH_98_stage2 address-list-timeout=1m in-interface=ether1 packet-size=98    3   chain=input action=add-src-to-address-list protocol=icmp address-list=ICMP_SSH_98_stage1 address-list-timeout=1m in-interface=ether1 packet-size=98   

Так же нам понадобиться скрипт следующего содержания:

:local wlist "plsdelme"; :local tmp ""; :local tmp1 "";   :if ( [/ip firewall address-list find ] != "") do={   :foreach i in [/ip firewall address-list find list=$wlist] do={     :set tmp [/ip firewall address-list get $i address]; 		:foreach x in [/ip firewall address-list find list~"blacklist"] do={ 			:set tmp1 [/ip firewall address-list get $x address]; 			:if ( $tmp1 = $tmp) do={ 				/ip firewall address-list remove $x; 			} 			} 		} } 

Данный скрипт необходимо поместить в cron scheduler c интервалом меньшим чем время но которое мы добавляем адрес в лист plsdelme
Что делает сприпт?
Он ищет адреса в листах plsdelme и сверяет значения с листами ~«blacklist», если есть совпадение то удаляет эту запись.

Если вы немного модифицируете скрипт, то можно делать в принципе всё что угодно.
Хотя для этих целей, больше подойдёт использование API.

ссылка на оригинал статьи http://habrahabr.ru/post/186488/


Комментарии

Один комментарий на ««MikroTik + port knoking over ICMP»»

  1. Аватар пользователя Андрей
    Андрей

    Очень интересно, самое галавное что у нас похоже происходит тоже самое после перехода на Автономную систему и на BGP маршрутизацию после статики.
    Вот что в логах сыплется:
    in:TTK1 out:TTK1, src-mac a8:d0:e5:50:f1:01, proto UDP, 95.83.101.240:29839->1.1.1.13:25565, len 48
    Nov/10/2013 15:31:42 firewall,info Null_mangle forward: in:TTK1 out:TTK1, src-mac a8:d0:e5:50:f1:01, proto TCP (SYN), 5.167.95.173:51156->1.1.1.13:16566, len 52
    Nov/10/2013 15:31:42 firewall,info Null_mangle forward: in:TTK1 out:TTK1, src-mac a8:d0:e5:50:f1:01, proto TCP (SYN), 188.114.33.7:58757->1.1.1.23:30082, len 52
    Nov/10/2013 15:31:42 firewall,info Null_mangle forward: in:TTK1 out:TTK1, src-mac a8:d0:e5:50:f1:01, proto UDP, 141.105.135.48:1024->1.1.1.24:49001, len 357
    Nov/10/2013 15:31:42 firewall,info Null_mangle forward: in:TTK1 out:TTK1, src-mac a8:d0:e5:50:f1:01, proto UDP,

    1.1.1.0 — наш пул адресов.
    Также неожиданно рвутся BGP сессии, ну и соответственно остальные радости. Как бы с джунепера перевести примеры фильтров на Микротике… Не поможете? Я буду крайне признателен.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *