The IPBan config file contains 2 interesting items that can trigger actions when IP addresses are banned or unbanned: ProcessToRunOnBan
and ProcessToRunOnUnban
.
Here’s the default config entry for ProcessToRunOnBan
:
<add key="ProcessToRunOnBan" value=""/>
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:
<add key="ProcessToRunOnBan" value="%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe C:\add-bannedip.ps1|###IPADDRESS###"/>
<add key="ProcessToRunOnUnban" value="%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe C:\remove-unbannedip.ps1|###IPADDRESS###"/>
The PowerShell (.ps1) scripts were really simple. The first adds banned IPs to a text file within the web root:
# Add an IP address to the list of banned IPs
param ($BannedIP)
$BannedPath = 'C:\inetpub\wwwroot\banned.txt'
Add-Content -Path $BannedPath -Value $BannedIP
The next removes unbanned IPs from the same text file:
# Remove an IP address from the list of banned IPs
param ($UnbannedIP)
$BannedPath = 'C:\inetpub\wwwroot\banned.txt'
Set-Content -Path $BannedPath (Get-Content $BannedPath | Select-String -NotMatch $UnbannedIP)
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.
However, I encountered an error when the next IP address was banned:
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.
at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo )
at System.Diagnostics.Process.StartCore(ProcessStartInfo )
at System.Diagnostics.Process.Start()
at System.Diagnostics.Process.Start(ProcessStartInfo )
at DigitalRuby.IPBanCore.IPBanService.<>c__DisplayClass191_0.<ExecuteExternalProcessForIPAddresses>b__0() in C:\Users\Jeff\Documents\GitHub\DigitalRuby\IPBan\IPBanCore\Core\IPBan\IPBanService_Private.cs:line 591
It apparently failed to expand %SystemRoot%
, so I replaced it with C:\Windows
.
As mentioned in my previous post on IPBan (IPBan: fail2ban for Windows), 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 (logfile.txt
):
2022-01-03 01:36:43.3348|INFO|DigitalRuby.IPBanCore.Logger|Config file changed
It looks like IPBan automatically checks the GetUrlConfig
value for updates. I confirmed that the file at C:\Program Files\IPBan\ipban.config
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.
Unfortunately, my change still didn’t work. I encountered the following error:
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.
at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo )
at System.Diagnostics.Process.Start(ProcessStartInfo )
at DigitalRuby.IPBanCore.IPBanService.<>c__DisplayClass191_0.<ExecuteExternalProcessForIPAddresses>b__0() in C:\Users\Jeff\Documents\GitHub\DigitalRuby\IPBan\IPBanCore\Core\IPBan\IPBanService_Private.cs:line 591
I decided to take a closer look at line 591:
ProcessStartInfo psi = new()
{
FileName = programFullPath,
WorkingDirectory = Path.GetDirectoryName(programFullPath),
Arguments = replacedArgs
};
using Process p = Process.Start(psi);
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:
<add key="ProcessToRunOnBan" value="C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe|C:\add-bannedip.ps1 ###IPADDRESS###"/>
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.
Another way to aggregate the data would be to include an
Invoke-WebRequest
command in the PowerShell script, something like:Lots of details to be considered there, like limiting access to the URI or requiring an access token so that it can’t be polluted by bad actors.