{"id":3586,"date":"2022-01-03T19:25:42","date_gmt":"2022-01-04T00:25:42","guid":{"rendered":"https:\/\/osric.com\/chris\/accidental-developer\/?p=3586"},"modified":"2022-01-04T09:42:33","modified_gmt":"2022-01-04T14:42:33","slug":"ipbans-processtorunonban-functionality","status":"publish","type":"post","link":"https:\/\/osric.com\/chris\/accidental-developer\/2022\/01\/ipbans-processtorunonban-functionality\/","title":{"rendered":"IPBan&#8217;s ProcessToRunOnBan functionality"},"content":{"rendered":"<p>The IPBan config file contains 2 interesting items that can trigger actions when IP addresses are banned or unbanned: <code>ProcessToRunOnBan<\/code> and <code>ProcessToRunOnUnban<\/code>.<\/p>\n<p>Here&#8217;s the default config entry for <code>ProcessToRunOnBan<\/code>:<\/p>\n<pre><code><!--\r\n      Run an external process when a ban occurs. Separate the process and any arguments with a pipe (|). ###IPADDRESS### will be replaced with the actual IP which was banned. The pipe is required.\r\n      Example: c:\\files\\on_ip_banned.exe|###IPADDRESS### -q\r\n    \r\n-->\r\n&lt;add key=\"ProcessToRunOnBan\" value=\"\"\/&gt;<\/code><\/pre>\n<p>I decided I wanted to make the list of banned IP addresses public by writing to a web-accessible file. I tried adding the following values:<\/p>\n<pre><code><!--\r\n      Run an external process when a ban occurs. Separate the process and any arguments with a pipe (|). ###IPADDRESS### will be replaced with the actual IP which was banned. The pipe is required.\r\n      Example: c:\\files\\on_ip_banned.exe|###IPADDRESS### -q\r\n    \r\n-->\r\n&lt;add key=\"ProcessToRunOnBan\" value=\"%SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe C:\\add-bannedip.ps1|###IPADDRESS###\"\/&gt;\r\n<!--\r\n      Run an external process when an unban occurs. Separate the process and any arguments with a pipe (|). ###IPADDRESS### will be replaced with the actual IP which was unbanned. The pipe is required.\r\n      Example: c:\\files\\on_ip_unbanned.exe|###IPADDRESS### -q\r\n    \r\n-->\r\n&lt;add key=\"ProcessToRunOnUnban\" value=\"%SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe C:\\remove-unbannedip.ps1|###IPADDRESS###\"\/&gt;<\/code><\/pre>\n<p>The PowerShell (.ps1) scripts were really simple. The first adds banned IPs to a text file within the web root:<\/p>\n<pre><code># Add an IP address to the list of banned IPs\r\nparam ($BannedIP)\r\n\r\n$BannedPath = 'C:\\inetpub\\wwwroot\\banned.txt'\r\nAdd-Content -Path $BannedPath -Value $BannedIP<\/code><\/pre>\n<p>The next removes unbanned IPs from the same text file:<\/p>\n<pre><code># Remove an IP address from the list of banned IPs\r\nparam ($UnbannedIP)\r\n\r\n$BannedPath = 'C:\\inetpub\\wwwroot\\banned.txt'\r\nSet-Content -Path $BannedPath (Get-Content $BannedPath | Select-String -NotMatch $UnbannedIP)<\/code><\/pre>\n<p>There are some flaws and a lack of error-checking in the above. The un-ban script could match IP addresses that are not identical, for example: 192.0.2.1 would match 192.0.2.10 and 192.0.2.100. Additionally, I would want to confirm that the parameter value was a valid IP address, but this was just a quick proof-of-concept.<\/p>\n<p>However, I encountered an error when the next IP address was banned:<\/p>\n<pre><code>2022-01-03 00:51:35.8763|ERROR|DigitalRuby.IPBanCore.Logger|Failed to execute process C:\\Program Files\\IPBan\\%SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe C:\\add-bannedip.ps1 192.0.2.14: System.ComponentModel.Win32Exception (2): An error occurred trying to start process 'C:\\Program Files\\IPBan\\%SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe C:\\add-bannedip.ps1' with working directory 'C:\\Program Files\\IPBan\\%SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe C:'. The system cannot find the file specified.\r\n   at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo )\r\n   at System.Diagnostics.Process.StartCore(ProcessStartInfo )\r\n   at System.Diagnostics.Process.Start()\r\n   at System.Diagnostics.Process.Start(ProcessStartInfo )\r\n   at DigitalRuby.IPBanCore.IPBanService.&lt;&gt;c__DisplayClass191_0.&lt;ExecuteExternalProcessForIPAddresses&gt;b__0() in C:\\Users\\Jeff\\Documents\\GitHub\\DigitalRuby\\IPBan\\IPBanCore\\Core\\IPBan\\IPBanService_Private.cs:line 591<\/code><\/pre>\n<p>It apparently failed to expand <code>%SystemRoot%<\/code>, so I replaced it with <code>C:\\Windows<\/code>.<\/p>\n<p>As mentioned in my previous post on IPBan (<a href=\"https:\/\/osric.com\/chris\/accidental-developer\/2021\/12\/ipban-fail2ban-for-windows\/\">IPBan: fail2ban for Windows<\/a>), I am using a remote config file hosted on an HTTPS server. Shortly after I made the change on the remote server, I noticed this in the logs (<code>logfile.txt<\/code>):<\/p>\n<pre><code>2022-01-03 01:36:43.3348|INFO|DigitalRuby.IPBanCore.Logger|Config file changed<\/code><\/pre>\n<p>It looks like IPBan automatically checks the <code>GetUrlConfig<\/code> value for updates. I confirmed that the file at <code>C:\\Program Files\\IPBan\\ipban.config<\/code> was updated at the same time. This is excellent, previously I thought I might need to restart the IPBan service any time the configuration changed.<\/p>\n<p>Unfortunately, my change still didn&#8217;t work. I encountered the following error:<\/p>\n<pre><code>2022-01-03 14:22:21.7154|ERROR|DigitalRuby.IPBanCore.Logger|Failed to execute process C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe C:\\add-bannedip.ps1 192.0.2.208: System.ComponentModel.Win32Exception (2): An error occurred trying to start process 'C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe C:\\add-bannedip.ps1' with working directory 'C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe C:'. The system cannot find the file specified.\r\n   at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo )\r\n   at System.Diagnostics.Process.Start(ProcessStartInfo )\r\n   at DigitalRuby.IPBanCore.IPBanService.&lt;&gt;c__DisplayClass191_0.&lt;ExecuteExternalProcessForIPAddresses&gt;b__0() in C:\\Users\\Jeff\\Documents\\GitHub\\DigitalRuby\\IPBan\\IPBanCore\\Core\\IPBan\\IPBanService_Private.cs:line 591<\/code><\/pre>\n<p>I decided to take a closer look at line 591:<\/p>\n<pre><code>    ProcessStartInfo psi = new()\r\n    {\r\n        FileName = programFullPath,\r\n        WorkingDirectory = Path.GetDirectoryName(programFullPath),\r\n        Arguments = replacedArgs\r\n    };\r\n    using Process p = Process.Start(psi);<\/code><\/pre>\n<p>It looked to me like it was taking the path for the PowerShell executable and the PowerShell script both as the full path. I changed the config to pass in the path to the PowerShell script as part of the arguments, which made sense:<\/p>\n<pre><code>&lt;add key=\"ProcessToRunOnBan\" value=\"C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe|C:\\add-bannedip.ps1 ###IPADDRESS###\"\/&gt;<\/code><\/pre>\n<p>That worked! The next time an IP address was banned, the .ps1 script was run and added the IP address to a web-accessible file.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The IPBan config file contains 2 interesting items that can trigger actions when IP addresses are banned or unbanned: ProcessToRunOnBan and ProcessToRunOnUnban. Here&#8217;s the default config entry for ProcessToRunOnBan: &lt;add key=&#8221;ProcessToRunOnBan&#8221; value=&#8221;&#8221;\/&gt; I decided I wanted to make the list of banned IP addresses public by writing to a web-accessible file. I tried adding the &hellip; <a href=\"https:\/\/osric.com\/chris\/accidental-developer\/2022\/01\/ipbans-processtorunonban-functionality\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">IPBan&#8217;s ProcessToRunOnBan functionality<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[393,48],"tags":[569],"class_list":["post-3586","post","type-post","status-publish","format-standard","hentry","category-powershell","category-security","tag-ipban"],"_links":{"self":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts\/3586","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/comments?post=3586"}],"version-history":[{"count":7,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts\/3586\/revisions"}],"predecessor-version":[{"id":3593,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/posts\/3586\/revisions\/3593"}],"wp:attachment":[{"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/media?parent=3586"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/categories?post=3586"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/osric.com\/chris\/accidental-developer\/wp-json\/wp\/v2\/tags?post=3586"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}