{"id":458,"date":"2022-11-01T20:47:04","date_gmt":"2022-11-01T20:47:04","guid":{"rendered":"https:\/\/baldsolutions.com\/?p=458"},"modified":"2022-11-01T21:37:40","modified_gmt":"2022-11-01T21:37:40","slug":"moving-target-defence-moving-ports-part-2","status":"publish","type":"post","link":"https:\/\/baldsolutions.com\/index.php\/2022\/11\/01\/moving-target-defence-moving-ports-part-2\/","title":{"rendered":"Moving Target Defence &#8211; Moving Ports, part 2"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>This is the part 2 of the MTD serie and it presents what happens behind the scenes in the PoC introduced in the <a href=\"https:\/\/baldsolutions.com\/index.php\/2022\/09\/25\/moving-target-defence-moving-ports\/\" target=\"_blank\" rel=\"noopener\" title=\"part1\">part 1<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to use nftables from python?<\/h2>\n\n\n\n<p>The title of this section is the same as this <a href=\"https:\/\/ral-arturo.org\/2020\/11\/22\/python-nftables-tutorial.html\" target=\"_blank\" rel=\"noopener\" title=\"post's title\">post&#8217;s title<\/a>. The post describes the key point in terms of the PoC implementation &#8211; the ability to apply nftables rules using pure python. As you can read the python3-nftables package is all you need to implement your own solution.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">PoC implementation<\/h2>\n\n\n\n<p>The core configuration of the PoC is based on the files in this <a href=\"https:\/\/github.com\/tglowka\/baldsolutions\/tree\/master\/mtd-moving-ports\/src\/configs\/setup\" target=\"_blank\" rel=\"noopener\" title=\"directory\">directory<\/a>. Actually, only three out of four are important, we don&#8217;t care about the <em>configuration_schema.json <\/em> file &#8211; this one only validates the <em>configuration.json<\/em> file. So, let&#8217;s describe the remaining files. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">configuration.json<\/h2>\n\n\n\n<p>The first file is the <em>configuration.json<\/em>. This is the custom file designed by myself and it has all the necessary configuration the PoC reads during the startup. There are three JSON objects:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>redis_connection_configuration,<\/li><li>redis_subscriber_configuration,<\/li><li>nftables_service_configuration.<\/li><\/ul>\n\n\n\n<p><em>redis_connection_configuration<\/em> and <em>redis_subscriber_configuration <\/em>are related only to the Redis communication whereas <em>nftables_service_configuration<\/em> consists of the configuration closely related to the nftables rules the PoC applies in the runtime &#8211; so let&#8217;s focus on this one. There are following objects:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>nft_startup_commands_path,<\/li><li>nft_address_rules_path,<\/li><li>max_port_number,<\/li><li>tcp_ports,<\/li><li>watched_addresses.<\/li><\/ul>\n\n\n\n<p><em>nft_startup_commands_path<\/em> and <em>nft_address_rules_path<\/em> point to the JSON files that consist of nftables commands &#8211; we will discuss these two files later on but for now it is worth to mention that the files&#8217; content is based on the JSON schema that is well documented <a href=\"https:\/\/manpages.debian.org\/unstable\/libnftables1\/libnftables-json.5.en.html\" target=\"_blank\" rel=\"noopener\" title=\"here\">here<\/a> (it is also mentioned in the aforementioned <a href=\"https:\/\/ral-arturo.org\/2020\/11\/22\/python-nftables-tutorial.html\" target=\"_blank\" rel=\"noopener\" title=\"post\">post<\/a>).<\/p>\n\n\n\n<p><em>max_port_number<\/em>  is the maximum port number that the program can choose when choosing redirection ports.<\/p>\n\n\n\n<p><em>tcp_ports<\/em> is a list of port numbers that are in use on the host machine.<\/p>\n\n\n\n<p><em>watched_addresses<\/em> is a list of objects in which each of them describes watched address <br>i.e. an IP address (<em>ip<\/em>  field) and a list of ports (<em>tcp_ignore<\/em>  field) that we want to exclude from the whole redirection process.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">nft_startup_commands.json<\/h2>\n\n\n\n<p>In this section (and in the next one) I won&#8217;t describe in details the file content because it&#8217;s not the point. The <em>nft_startup_commands.json<\/em> file was also created by myself but its content is  based on the previously mentioned <a href=\"https:\/\/manpages.debian.org\/unstable\/libnftables1\/libnftables-json.5.en.html\" target=\"_blank\" rel=\"noopener\" title=\"schema\">schema<\/a>. The file contains six nftables commands that do the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>removes all tables, chains and generated rules (first command &#8211; <em>flush<\/em>),<\/li><li>creates the <em>nat<\/em> table of the <em>ip<\/em>  family and creates the <em>prerouting<\/em> chain within the table (second and third commands &#8211; <em>add table<\/em> and <em>add chain<\/em>).<\/li><li>creates the <em>raw <\/em>table of the <em>ip<\/em> family and creates the <em>prerouting<\/em> and <em>output<\/em> chains within the table (fourth, fifth and sixth commands &#8211; <em>add table<\/em>, <em>add chain<\/em> and <em>add chain<\/em>).<\/li><\/ul>\n\n\n\n<p><span style=\"font-size: 1em;\">T<\/span>he commands don&#8217;t rely on the <em>configuration.json<\/em>  file, i.e. they are always the same. The main purpose of them is to remove all nftables-related rules and structures (tables and chains) created so far and prepare empty chains for the newly generated rules (described in the next section).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">nft_address_rules.json<\/h2>\n\n\n\n<p>The <em>nft_address_rules.json<\/em> file contains nftables commands that create redirection rules. The <em><em>nft_address_rules.json<\/em><\/em> file was also created by myself and its content is also based on the previously mentioned <a href=\"https:\/\/manpages.debian.org\/unstable\/libnftables1\/libnftables-json.5.en.html\" target=\"_blank\" rel=\"noreferrer noopener\">schema<\/a>. The file content is not 100% valid because it contains <br>4 custom tokens that are replaced in the runtime:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>{{SOURCE_ADDRESS}},<\/li><li>{{DESTINATION_PORT}},<\/li><li>{{REDIRECTED_PORT}},<\/li><li>{{PROTOCOL}}.<\/li><\/ul>\n\n\n\n<p>For each in the <em>watched_addresses<\/em> list from the <em>configuration.json<\/em>  file and for each in the <em>tcp_ports<\/em> list excluding <em>tcp_ignore<\/em> list the program generates rules according to the <em>nft_address_rules.json<\/em>  file. In other words, the <em>nft_address_rules.json<\/em> file is a  template for <br>a batch of rules for a particular pair of a watched IP address and a port (not ignored one).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example<\/h2>\n\n\n\n<p>The foregoing description might be a little involved but let me try to simplify it by an example. As the code on the GitHub repository might change in the future let&#8217;s assume that the following example uses the <em>configuration.json<\/em>, <em>nft_startup_commands.json<\/em> and <em>nft_address_rules.json <\/em> files from this <a href=\"https:\/\/github.com\/tglowka\/baldsolutions\/tree\/34d62088aca245bf8b085144615c0fc5d1715d31\/mtd-moving-ports\/src\/configs\/setup\" target=\"_blank\" rel=\"noopener\" title=\"commit\">commit<\/a>.<\/p>\n\n\n\n<p>Let&#8217;s focus for now on the <a href=\"https:\/\/github.com\/tglowka\/baldsolutions\/tree\/34d62088aca245bf8b085144615c0fc5d1715d31\/mtd-moving-ports#3-architecture\" target=\"_blank\" rel=\"noopener\" title=\"README file section\">README file section<\/a>. The <em>nftables<\/em> container is the one that has the PoC up and running. Now let&#8217;s move to this <a href=\"https:\/\/github.com\/tglowka\/baldsolutions\/tree\/34d62088aca245bf8b085144615c0fc5d1715d31\/mtd-moving-ports#43-nftables\" target=\"_blank\" rel=\"noopener\" title=\"README section\">README section<\/a> and to the following part &#8220;Once you send the message, you should see that the\u00a0<code>nftables<\/code>\u00a0container received the message (first terminal). Receiving the message means that the nftables rules has been applied.&#8221; What does it mean &#8220;the nftables rules has been applied&#8221;? Let me break it down by describing the whole rules application process in the following steps:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>The PoC is listening on the <em>test_channel_1<\/em> on Redis, IP address 10.0.0.5, port 6379 (<em>configuraion.json file<\/em>).<\/li><li>The message is sent to the <em>test_channel_1<\/em>.<\/li><li>The PoC is notified about the message.<\/li><li>The PoC starts to process the message.<ul><li>The PoC starts to generate nftables commands:<ul><li>The PoC starts to prepare the nftables commands (there is no commands at this time)  by appending the ones from <em>nft_startup_commands.json<\/em> file.<\/li><\/ul><ul><li>The PoC  continues to prepare the nftables commands by adding the nftables rules commands:<ul><li>For each in <em>watched_addresses <\/em> and for each in <em>tcp_ports<\/em> excluding <em>tcp_ignore<\/em>  a batch of rules based on the <em>nft_address_rules.json<\/em> is created. In this example that would be 3 batches of rules (each unique pair of an IP and a port has its own batch of rules):<ul><li>first batch of rules &#8211; IP 10.0.0.3, port 3 &#8211; the {{SOURCE_ADDRESS}} token is replaced by &#8220;10.0.0.3&#8221;, {{DESTINATION_PORT}} by &#8220;3&#8221;, {{REDIRECTED_PORT}} by <br>a random number from the range [1..20] (20 is the <em>max_port_number<\/em>) excluding  [1, 2, 3, 4, 5] (<em>tcp_ports<\/em>) and {{PROTOCOL}} by &#8220;tcp&#8221;.<\/li><li>second batch of rules &#8211; IP 10.0.0.3, port 4 &#8211; the {{SOURCE_ADDRESS}} token is replaced by &#8220;10.0.0.3&#8221;, {{DESTINATION_PORT}} by &#8220;4&#8221;, {{REDIRECTED_PORT}} by <br>a random number from the range [1..20] (20 is the <em>max_port_number<\/em>) excluding  [1, 2, 3, 4, 5] (<em>tcp_ports<\/em>) and excluding [NumberChosenForPort3] and {{PROTOCOL}} by &#8220;tcp&#8221;.<\/li><li>third batch of rules &#8211; IP 10.0.0.3, port 5 &#8211;  the {{SOURCE_ADDRESS}} token is replaced by &#8220;10.0.0.3&#8221;, {{DESTINATION_PORT}} by 3, {{REDIRECTED_PORT}} by a random number from the range [1..20] (20 is the <em>max_port_number<\/em>) excluding  [1, 2, 3, 4, 5] (<em>tcp_ports<\/em>) and excluding [NumberChosenForPort3, NumberChosenForPort4] and {{PROTOCOL}} by &#8220;tcp&#8221;.<\/li><\/ul><\/li><\/ul><\/li><li><span style=\"font-size: 1em;\">The PoC finishes the nftables commands preparation, appends them to the  commands added from the <em>nft_startup_commands.json<\/em><\/span> <span style=\"font-size: 1em;\">and is ready to validate and apply the commands.<\/span><\/li><li>The PoC validates the prepared commands.<\/li><\/ul><ul><li>The PoC applies the nftables commands and validates the output.<\/li><li>If the rules application succeed, then the previously applied rules are removed and the network traffic is redirected according to the newly applied batches of rules. <\/li><\/ul><\/li><\/ul><\/li><li>The PoC finishes the message processing.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>I hope the explanation helps at least a little in understanding the presented PoC. There is one more thing that might help you to understand the concept. If you run the PoC according to the <a href=\"https:\/\/github.com\/tglowka\/baldsolutions\/tree\/master\/mtd-moving-ports#4-test-the-solution\" target=\"_blank\" rel=\"noopener\" title=\"README\">README<\/a> you can list all applied nftables commands by the PoC on the host machine (i.e. <em>nftables<\/em> container). All you have to do is to run the following command inside the <em>nftables<\/em> container: <code>nft list ruleset<\/code>.<\/p>\n\n\n\n<p>Have a nice day, bye!<\/p>\n\n\n\n<p>  <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction This is the part 2 of the MTD serie and it presents what happens behind the scenes in the PoC introduced in the part&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/baldsolutions.com\/index.php\/2022\/11\/01\/moving-target-defence-moving-ports-part-2\/\">Continue reading<span class=\"screen-reader-text\">Moving Target Defence &#8211; Moving Ports, part 2<\/span><\/a><\/div>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[6,7,5],"tags":[],"class_list":["post-458","post","type-post","status-publish","format-standard","hentry","category-cybersecurity","category-mtd","category-network","entry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/posts\/458","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/comments?post=458"}],"version-history":[{"count":54,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/posts\/458\/revisions"}],"predecessor-version":[{"id":522,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/posts\/458\/revisions\/522"}],"wp:attachment":[{"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/media?parent=458"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/categories?post=458"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/tags?post=458"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}