📜 ⬆️ ⬇️

MikroTik + port knocking over ICMP

A very small post telling how to catch ICMP packets and filter them with logic.

We implement port knocking technology on RouterOS via the icmp protocol.

I ask under the cat.

Probably there is no point in telling what port knoking is, as there are quite a few descriptions about it on the Internet.
If it is quite briefly, the technology allows, in a certain order of port search, provided that the search is performed correctly, to perform various actions.
I will show you how you can implement this technology through ICMP protocol which ports do not support. And we will appeal by the size of the ICMP packet.

Add yourself to the white_list


We have a rule in the filter
[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 

Which says to allow incoming connections on port 22 (ssh), from all addresses that are contained in the white_list.
Add two rules
We set criteria, we need a simple check of the bonds of two approaches. Let there be the first knock on a package of 70, and the second 100, and also necessarily two packages.
Do not forget that the ICMP packet header is 28 bytes.
And so at us the following picture emerges: we should knock on ICMP twice with a packet size of 98 bytes and twice knock on a packet size of 128 bytes.
We catch the first packet with a size of 98 bytes.

 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 

A packet of 98 bytes using the ICMP protocol, we put the outgoing address in the ICMP_SSH_98_stage1 sheet

We catch the second packet with a size of 98 bytes.

 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 

The packet is 98 bytes in size by the ICMP protocol and the outgoing address is already contained in the ICMP_SSH_98_stage1 sheet, then we put the outgoing address in the ICMP_SSH_98_stage2 sheet

We caught two packets of 98 bytes or 70 bytes when sending.
We catch the third packet with a size of 128 bytes.

 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 

The packet is 128 bytes in size by the ICMP protocol and the outgoing address is already contained in the ICMP_SSH_98_stage2 sheet, then we put the outgoing address in the ICMP_SSH_128_stage1 sheet

We catch the fourth packet (last) with a size of 128 bytes.

 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 

The packet is 128 bytes in size by the ICMP protocol and the outgoing address is already contained in the ICMP_SSH_128_stage1 sheet, then we put the outgoing address in the white_list_ssh sheet for 1 hour.

')
I deliberately did the first example a bit wrong, so that you could see the sequence of actions.
In order for everything to work, you need to move the order of the rules in the reverse order. Look under the spoiler.

Fully filter table
 [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 



Actually everything is simple here.

Let's go further remove ourselves from the address sheets.


Many who set up MikroTik use Bruteforce brute force protection wiki.mikrotik.com/wiki/Bruteforce_login_prevention
It happens I chop off my hands. So now we will remove ourselves from the sheets we could get into.
And so we use the developments that we had from the last example; we will only change the final sheet to 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 

We also need the following script:
 :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; } } } } 

This script must be placed in the cron scheduler with an interval less than the time but which we add the address to the sheet plsdelme
What does the sprite do?
It searches for addresses in plsdelme sheets and compares values ​​with ~ blacklist sheets; if there is a match, it deletes this entry.

If you modify the script a little bit, then you can basically do anything.
Although for these purposes, the use of the API is more appropriate.

Source: https://habr.com/ru/post/186488/


All Articles