Скрипт блокировки ip-адресов, с которых пытаются подобрать пользователей роутера

Здесь выкладываем скрипты
Правила форума
Уважаемые Пользователи форума, обратите внимание!
Ни при каких обстоятельствах, Администрация форума, не несёт ответственности за какой-либо, прямой или косвенный, ущерб причиненный в результате использования материалов, взятых на этом Сайте или на любом другом сайте, на который имеется гиперссылка с данного Сайта. Возникновение неисправностей, потерю программ или данных в Ваших устройствах, даже если Администрация будет явно поставлена в известность о возможности такого ущерба.
Просим Вас быть предельно осторожными и внимательными, в использовании материалов раздела. Учитывать не только Ваши пожелания, но и границы возможностей вашего оборудования.
Ответить
Аватара пользователя
drpioneer
Сообщения: 142
Зарегистрирован: 30 май 2013, 10:20

Приветствую всех!

В условиях самоизоляции появилась возможность уделить больше внимания своему сетевому хозяйству.
Листая журналы своих Mikrotik-ов обратил внимание на периодические настырные попытки залогиниться на роутеры, подобные таким:

"Mmm/dd/yyyy hh:mm:ss disk system, error, critical login failure for user system from 117.248.147.203 via api"

Захотелось автоматизировать процесс нейтрализации всех желающих поживиться чужими девайсами :)
В качестве прототипа, откуда была подчерпнута идея, использовал этот код vqd:

viewtopic.php?p=22598&sid=f919b93b418a1 ... eed#p22598

На выходе у меня получился такой скрипт, который запускаем по расписанию с нужной периодичностью:

Код: Выделить всё


# Script for blocking dangerous addresses that tried to connect to the router
# https://forummikrotik.ru/viewtopic.php?p=70410#p70410
# tested on ROS 6.46.5
# updated 2020/05/10

foreach dangerString in=[ /log find message~"login failure for user"; ] do={
    do {
        :local stringTemp ([ /log get $dangerString message ]);
        :local dangerUser ([ :pick $stringTemp 23 ([ :find $stringTemp "from" ] - 1) ]);
        :local dangerIP ([ :pick $stringTemp ([ :find $stringTemp "from" ] + 5) ([ :find $stringTemp "via" ] - 1) ]);
        foreach routerUser in=[ /user find disabled=no ] do={
            do {
                if ( $routerUser != $dangerUser ) do={
                    if ([ /ip firewall address-list find list="BlockDangerAddress" address=$dangerIP ] = "" ) do={ 
                        /ip firewall address-list add address=$dangerIP list="BlockDangerAddress" timeout=14d;
                        :log warning (">>> Added in black list user: ".$dangerUser." from IP ".$dangerIP);
                    } 
                }
            } on-error={ :log warning ">>> Script error. Not found active router user."; } 
        }
    } on-error={ :log warning ">>> Script error. Not found string 'login failure for user'  in log."; }
}

Как это работает:
1. В журнале выискиваются все строки, указывающие на неудачную попытку залогиниться на роутер
2. Из каждой найденной строки вычленяется login и ip-адрес, с которого пытались залогиниться
3. Полученный login проверяется на предмет отсутствия в списке имен активных пользователей Mikrotik-а (такого user-а не существует),
4. Полученный ip-адрес проверяется на наличие в черном списке. Если его там нет, тогда добавляется в черный список.

Ну и чтоб взлетело, добавим в Firewall/Filter Rules правило, которое будет глушить все попытки достучаться до нашего роутера с выявленных IP-адресов:

Код: Выделить всё

/ip firewall filter add action=drop chain=input comment="Dropping dangerous adresses" src-address-list=BlockDangerAddress
Представляю результат работы скрипта за два дня:

Код: Выделить всё

 5 D BlockDangerAddress    37.99.71.78           may/10/2020 03:31:29
 6 D BlockDangerAddress    71.81.84.58           may/10/2020 03:31:29
 7 D BlockDangerAddress    123.18.131.24         may/10/2020 03:31:29
 8 D BlockDangerAddress    113.160.215.178       may/10/2020 03:31:29
 9 D BlockDangerAddress    36.90.208.193         may/10/2020 03:31:30
10 D BlockDangerAddress    183.80.166.84         may/10/2020 03:31:30
11 D BlockDangerAddress    202.172.17.65         may/10/2020 03:31:30
12 D BlockDangerAddress    159.192.143.234       may/10/2020 03:31:30
13 D BlockDangerAddress    14.231.35.181         may/10/2020 03:31:30
14 D BlockDangerAddress    103.72.219.134        may/10/2020 03:31:30
15 D BlockDangerAddress    182.185.22.138        may/10/2020 03:31:30
16 D BlockDangerAddress    118.69.226.85         may/10/2020 03:31:30
17 D BlockDangerAddress    14.184.0.182          may/10/2020 03:31:30
18 D BlockDangerAddress    36.73.74.59           may/10/2020 03:31:30
19 D BlockDangerAddress    1.1.200.240           may/10/2020 03:31:30
20 D BlockDangerAddress    39.33.144.52          may/10/2020 03:31:30
21 D BlockDangerAddress    36.88.129.253         may/10/2020 03:31:30
22 D BlockDangerAddress    14.231.205.10         may/10/2020 03:31:30
23 D BlockDangerAddress    41.174.72.239         may/10/2020 03:31:30
24 D BlockDangerAddress    186.250.118.50        may/10/2020 05:59:31
25 D BlockDangerAddress    118.175.138.196       may/10/2020 07:07:31
26 D BlockDangerAddress    42.119.82.204         may/10/2020 08:40:31
27 D BlockDangerAddress    117.248.147.203       may/10/2020 09:21:31
28 D BlockDangerAddress    14.177.80.228         may/10/2020 10:58:31
29 D BlockDangerAddress    122.164.165.220       may/10/2020 14:39:31
30 D BlockDangerAddress    14.249.102.84         may/10/2020 14:39:31
31 D BlockDangerAddress    194.156.250.105       may/10/2020 15:02:34
32 D BlockDangerAddress    170.245.227.210       may/10/2020 21:50:31
33 D BlockDangerAddress    125.166.78.251        may/11/2020 00:17:31
34 D BlockDangerAddress    113.188.242.28        may/11/2020 03:36:31
35 D BlockDangerAddress    119.76.132.235        may/11/2020 04:45:31
36 D BlockDangerAddress    36.66.43.79           may/11/2020 05:46:31
37 D BlockDangerAddress    113.161.179.245       may/11/2020 05:49:31
38 D BlockDangerAddress    14.253.28.77          may/11/2020 05:51:31
39 D BlockDangerAddress    116.108.44.225        may/11/2020 06:45:31
40 D BlockDangerAddress    115.75.48.53          may/11/2020 07:15:31
41 D BlockDangerAddress    183.88.152.51         may/11/2020 08:52:32
Конструктивные замечания и улучшения только приветствуются.

----------------------------
UPDATE of 2022: Скрипт развивается. Используйте актуальную версию скрипта. Её вы найдёте в конце этой ветки форума.
Последний раз редактировалось drpioneer 18 фев 2022, 13:48, всего редактировалось 3 раза.


Аватара пользователя
Virtue
Сообщения: 142
Зарегистрирован: 07 мар 2014, 10:17

интересный скрипт, но вот у меня например используется нестандартный порт на белом адресе и ко мне никто не ломится.. вообще тишина :-):


Аватара пользователя
podarok66
Модератор
Сообщения: 4355
Зарегистрирован: 11 фев 2012, 18:49
Откуда: МО

Virtue писал(а): 18 май 2020, 13:43 интересный скрипт, но вот у меня например используется нестандартный порт на белом адресе и ко мне никто не ломится.. вообще тишина :-):
Все за вас рады, но как это относится к теме написания скриптов? Хвастаться в ветку общения, пожалуйста.


Мануалы изучил и нигде не ошибся? Фаервол отключил? Очереди погасил? Витая пара проверена? ... Тогда Netinstal'ом железку прошей и настрой ее заново. Что, все равно не фурычит? Тогда к нам. Если не подскажем, хоть посочувствуем...
Аватара пользователя
Virtue
Сообщения: 142
Зарегистрирован: 07 мар 2014, 10:17

podarok66 писал(а): 18 май 2020, 13:49 Все за вас рады, но как это относится к теме написания скриптов? Хвастаться в ветку общения, пожалуйста.
просто странно что у автора столько много логин фэйлов всего за 2 дня, может он не поменял порт?


Аватара пользователя
podarok66
Модератор
Сообщения: 4355
Зарегистрирован: 11 фев 2012, 18:49
Откуда: МО

Virtue писал(а): 18 май 2020, 16:12 просто странно что у автора столько много логин фэйлов всего за 2 дня, может он не поменял порт?
И? Как это относится к работе скрипта? Вы можете представить ситуацию, когда менять порт нет возможности. Я могу, с таким сталкиваюсь сплошь и рядом... Ваши личные предпочтения не панацея. И на работоспособности скриптов никак не отражаются.
Специально для вас поясню. Данная ветка форума создана для обсуждения работы скриптов, а не альтернативных способов защиты. Если вам просто поболтать, посетите ветку Общение и там болтайте. Если у вас проблема, создайте в соответствующей ветке тему, мы тут вполне лояльны к новичкам. Но вот делать вбросы в темах с целью похвастаться или дать ненужные советы не стоит. Я очень ценю ветку скриптов, поэтому лишний флуд мне здесь ни к чему. Прекращайте.


Мануалы изучил и нигде не ошибся? Фаервол отключил? Очереди погасил? Витая пара проверена? ... Тогда Netinstal'ом железку прошей и настрой ее заново. Что, все равно не фурычит? Тогда к нам. Если не подскажем, хоть посочувствуем...
Аватара пользователя
drpioneer
Сообщения: 142
Зарегистрирован: 30 май 2013, 10:20

Полет моей мысли не остановить...
На основе этого скрипта получился новый, более суровый :men:

Код: Выделить всё


# Script for blocking dangerous addresses that tried to connect to the router
# https://forummikrotik.ru/viewtopic.php?t=4781&start=20
# tested on ROS 6.46.5
# updated 2020/05/22

# ----------- Stage 1 - search for a device login attempt ----------- 
foreach dangerString in=[ /log find message~"login failure for user"; ] do={
    do {
        foreach routerUser in=[ /user find disabled=no ] do={
            do { 
                :local stringTemp ([ /log get $dangerString message ]);
                :local dangerUser ([ :pick $stringTemp ([ :find $stringTemp "user" ] + 5) ([ :find $stringTemp "from" ] - 1) ]);
                :local dangerIP ([ :pick $stringTemp ([ :find $stringTemp "from" ] + 5) ([ :find $stringTemp "via" ] - 1) ]);
                if (($routerUser != $dangerUser) && ($dangerIP != "0.0.0.0")) do={
                    if ([ /ip firewall address-list find list="BlockDangerAddress" address=$dangerIP ] = "" ) do={ 
                        /ip firewall address-list add address=$dangerIP list="BlockDangerAddress" timeout=14d;
                        :log warning (">>> Added in black list router user: ".$dangerUser." from IP ".$dangerIP." (wrong router user)");
                    } 
                }
            } on-error={ :log warning ">>> Script error. Not found active router user."; } 
        }
    } on-error={ :log warning ">>> Script error. Not found string 'login failure for user' in log."; }
}

# ----------- Stage 2 - search for an attempt to enter through IPSec password ----------- 
foreach dangerString in=[ /log find message~"parsing packet failed, possible cause: wrong password"; ] do={
    do {
        :local stringTemp ([ /log get $dangerString message ]);
        :local dangerIP ([ :pick $stringTemp 0 ([ :find $stringTemp "parsing" ] - 1) ]);
        if ([ :len [ /log find message~"parsing packet failed, possible cause: wrong password" message~$dangerIP; ]] > 2) do={
            if ([ /ip firewall address-list find list="BlockDangerAddress" address=$dangerIP ] = "" ) do={ 
                /ip firewall address-list add address=$dangerIP list="BlockDangerAddress" timeout=14d;
                :log warning (">>> Added in black list IP ".$dangerIP." (wrong IPSec password)");
            }
        }
    } on-error={ :log warning ">>> Script error. Not found string 'parsing packet failed, possible cause: wrong password' in log."; }
}

# ----------- Stage 3 - search for an attempt to enter through IPSec proposal ----------- 
foreach dangerString1 in=[ /log find message~"failed to get valid proposal"; ] do={
    do {
        foreach dangerString2 in=[ /log find message~"failed to pre-process"; ] do={
            do {
                :local stringTemp1 ([ /log get $dangerString1 message ]);
                :local stringTemp2 ([ /log get $dangerString2 message ]);
                :local dangerIP1 ([ :pick $stringTemp1 0 ([ :find $stringTemp1 "failed" ] - 1) ]);
                :local dangerIP2 ([ :pick $stringTemp2 0 ([ :find $stringTemp2 "failed" ] - 1) ]);
                if ($dangerIP1 = $dangerIP2  && ($dangerIP2 != "0.0.0.0")) do={
                    if ([ /ip firewall address-list find list="BlockDangerAddress" address=$dangerIP2 ] = "" ) do={ 
                        /ip firewall address-list add address=$dangerIP2 list="BlockDangerAddress" timeout=14d;
                        :log warning (">>> Added in black list IP ".$dangerIP2." (wrong IPSec proposal)");
                    } 
                }
            } on-error={ :log warning ">>> Script error. Not found string 'failed to pre-process' in log."; } 
        }
    } on-error={ :log warning ">>> Script error. Not found string 'failed to get valid proposal' in log."; }
}

# ----------- Stage 4 - search for an attempt to enter through L2TP ----------- 
foreach dangerString in=[ /log find message~"user" message~"authentication failed"; ] do={
    do {
        :local stringTemp ([ /log get $dangerString message ]);
        :local dangerUser ([ :pick $stringTemp ([ :find $stringTemp "user" ] + 5) ([ :find $stringTemp "authentication" ] - 1) ]);
        :local dangerIP ([ :pick $stringTemp ([ :find $stringTemp "<" ] + 1) ([ :find $stringTemp ">" ]) ]);
        if ([ :len [ /log find message~"authentication failed" message~$dangerIP; ]] > 2 ) do={
            if ([ /ip firewall address-list find list="BlockDangerAddress" address=$dangerIP ] = "" ) do={ 
                /ip firewall address-list add address=$dangerIP list="BlockDangerAddress" timeout=14d;
                :log warning (">>> Added in black list L2TP user: ".$dangerUser." from IP ".$dangerIP." (wrong L2TP user)");
            }
        }
    } on-error={ :log warning ">>> Script error. Not found string 'user' & 'authentication failed' in log."; }
}

Теперь в черный список отправляются все граждане, пытающиеся:
  • залогиниться на роутер с несуществующим именем роутера (строка в логе: 'login failure for user XXXXXXX'),
  • 3 и более раз подобрать пароль IPSec (строка в логе: 'parsing packet failed, possible cause: wrong password'),
  • подключиться по IPSec c несовпадающим proposal (2 строки в логе: 'failed to get valid proposal' и 'failed to pre-process').
  • 3 и более раз подобрать пароль L2TP (строка в логе: 'user XXXXXXX authentication failed'),
Что-то подобное уже пытались изобразить вот здесь: https://github.com/Onoro/Mikrotik
А вот тут искали, как бороться с одной из этих напастей: viewtopic.php?t=7113

Замечания и улучшения только приветствуются.


Аватара пользователя
podarok66
Модератор
Сообщения: 4355
Зарегистрирован: 11 фев 2012, 18:49
Откуда: МО

Ну тогда уж до кучи стоит прикрутить неудачные авторизации по
* api
* api-ssl
* ssh
* winbox
* www
* www-ssl
* telnet
* ftp
* любой vpn по выбору юзера (ваще огонь!)
Тогда наши доблестные раздолбаи-параноики из числа спрашивающих как защититься от взлома от меня точно станут получать ссылку в эту тему. Клянусь!!! :-)
Вообще, без смеха, достаточно интересный вариант может вырисоваться


Мануалы изучил и нигде не ошибся? Фаервол отключил? Очереди погасил? Витая пара проверена? ... Тогда Netinstal'ом железку прошей и настрой ее заново. Что, все равно не фурычит? Тогда к нам. Если не подскажем, хоть посочувствуем...
Аватара пользователя
drpioneer
Сообщения: 142
Зарегистрирован: 30 май 2013, 10:20

Для этого нужны строки из log-файла, указывающие на невалидные попытки присоединиться к роутеру через:
* api
* api-ssl
* ssh
* winbox
* www
* www-ssl
* telnet
* ftp
* любой vpn по выбору юзера (ваще огонь!)
тогда будет с чем работать...

Более того, часть заявленных пунктов правильно обрабатывается скриптом (api, web, ssh, telnet, winbox) :-ok-:
Подозреваю, что все пункты, кроме последнего, также будут правильно обрабатываться.
По последнему пункту - не понял о чем речь?

В свете последних пожеланий выкладываю очередную версию скрипта с подправленным выводом информации в log-файл:

Код: Выделить всё


# Script for blocking dangerous addresses that tried to connect to the router
# https://forummikrotik.ru/viewtopic.php?t=4781&start=20
# tested on ROS 6.46.5
# updated 2020/05/24

# ----------- Stage 1 - search for a device login attempt ----------- 
foreach dangerString in=[ /log find message~"login failure for user"; ] do={
    do {
        foreach routerUser in=[ /user find disabled=no ] do={
            do { 
                :local stringTemp ([ /log get $dangerString message ]);
                :local dangerUser ([ :pick $stringTemp ([ :find $stringTemp "user" ] + 5) ([ :find $stringTemp "from" ] - 1) ]);
                :local dangerIP ([ :pick $stringTemp ([ :find $stringTemp "from" ] + 5) ([ :find $stringTemp "via" ] - 1) ]);
                :local dangerVia ([ :pick $stringTemp ([ :find $stringTemp "via" ]) ([ :find $stringTemp "via" ] + 20)]);
                if (($routerUser != $dangerUser) && ($dangerIP != "0.0.0.0")) do={
                    if ([ /ip firewall address-list find list="BlockDangerAddress" address=$dangerIP ] = "" ) do={ 
                        /ip firewall address-list add address=$dangerIP list="BlockDangerAddress" timeout=14d;
                        :log warning (">>> Added in black list IP ".$dangerIP." (wrong router user '".$dangerUser."' ".$dangerVia.")");
                    } 
                }
            } on-error={ :log warning ">>> Script error. Not found active router user."; } 
        }
    } on-error={ :log warning ">>> Script error. Not found string 'login failure for user' in log."; }
}

# ----------- Stage 2 - search for an attempt to enter through IPSec password ----------- 
foreach dangerString in=[ /log find message~"parsing packet failed, possible cause: wrong password"; ] do={
    do {
        :local stringTemp ([ /log get $dangerString message ]);
        :local dangerIP ([ :pick $stringTemp 0 ([ :find $stringTemp "parsing" ] - 1) ]);
        if ([ :len [ /log find message~"parsing packet failed, possible cause: wrong password" message~$dangerIP; ]] > 2) do={
            if ([ /ip firewall address-list find list="BlockDangerAddress" address=$dangerIP ] = "" ) do={ 
                /ip firewall address-list add address=$dangerIP list="BlockDangerAddress" timeout=14d;
                :log warning (">>> Added in black list IP ".$dangerIP." (wrong IPSec password)");
            }
        }
    } on-error={ :log warning ">>> Script error. Not found string 'parsing packet failed, possible cause: wrong password' in log."; }
}

# ----------- Stage 3 - search for an attempt to enter through IPSec proposal ----------- 
foreach dangerString1 in=[ /log find message~"failed to get valid proposal"; ] do={
    do {
        foreach dangerString2 in=[ /log find message~"failed to pre-process"; ] do={
            do {
                :local stringTemp1 ([ /log get $dangerString1 message ]);
                :local stringTemp2 ([ /log get $dangerString2 message ]);
                :local dangerIP1 ([ :pick $stringTemp1 0 ([ :find $stringTemp1 "failed" ] - 1) ]);
                :local dangerIP2 ([ :pick $stringTemp2 0 ([ :find $stringTemp2 "failed" ] - 1) ]);
                if ($dangerIP1 = $dangerIP2  && ($dangerIP2 != "0.0.0.0")) do={
                    if ([ /ip firewall address-list find list="BlockDangerAddress" address=$dangerIP2 ] = "" ) do={ 
                        /ip firewall address-list add address=$dangerIP2 list="BlockDangerAddress" timeout=14d;
                        :log warning (">>> Added in black list IP ".$dangerIP2." (wrong IPSec proposal)");
                    } 
                }
            } on-error={ :log warning ">>> Script error. Not found string 'failed to pre-process' in log."; } 
        }
    } on-error={ :log warning ">>> Script error. Not found string 'failed to get valid proposal' in log."; }
}

# ----------- Stage 4 - search for an attempt to enter through L2TP ----------- 
foreach dangerString in=[ /log find message~"user" message~"authentication failed"; ] do={
    do {
        :local stringTemp ([ /log get $dangerString message ]);
        :local dangerUser ([ :pick $stringTemp ([ :find $stringTemp "user" ] + 5) ([ :find $stringTemp "authentication" ] - 1) ]);
        :local dangerIP ([ :pick $stringTemp ([ :find $stringTemp "<" ] + 1) ([ :find $stringTemp ">" ]) ]);
        if ([ :len [ /log find message~"authentication failed" message~$dangerIP; ]] > 2 ) do={
            if ([ /ip firewall address-list find list="BlockDangerAddress" address=$dangerIP ] = "" ) do={ 
                /ip firewall address-list add address=$dangerIP list="BlockDangerAddress" timeout=14d;
                :log warning (">>> Added in black list IP ".$dangerIP." (wrong L2TP user '".$dangerUser."')");
            }
        }
    } on-error={ :log warning ">>> Script error. Not found string 'user' & 'authentication failed' in log."; }
}

Ну и как всегда: замечания и улучшения приветствуются.
Последний раз редактировалось drpioneer 24 май 2020, 19:56, всего редактировалось 1 раз.


Аватара пользователя
podarok66
Модератор
Сообщения: 4355
Зарегистрирован: 11 фев 2012, 18:49
Откуда: МО

В любом случае тема у меня в закладках.


Мануалы изучил и нигде не ошибся? Фаервол отключил? Очереди погасил? Витая пара проверена? ... Тогда Netinstal'ом железку прошей и настрой ее заново. Что, все равно не фурычит? Тогда к нам. Если не подскажем, хоть посочувствуем...
Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

Спасибо автору. Скрипт хорош как пример и весьма полезен многими строками кода.

По работе скрипта - проблема в том, что даже Ваш скрипт показывает, что залогиниться пытаются постоянно с новых адресов и адреса новых попыток никогда не повторяются. В таком случае какой смысл создания списка этих адресов (мы и так знаем откуда они :-) ) и блокировки их ? Вот в том то и дело ...

Так что логин посложнее и пароль посложнее и подлиннее (не менее 9 символов) как для user`ов самого Тика так и для VPN-клиентов. И всё. Никто Вас ломать не будет если Вы не банк.

А за скрипт действительно спасибо ! Мне всегда больше интересна реализация и варианты программирования. Возможности Lua всегда радуют и восхищают !


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
Ответить