Skip to content

Commit 985fab2

Browse files
committed
suricata package addition
1 parent 7f5911d commit 985fab2

File tree

6 files changed

+157
-3
lines changed

6 files changed

+157
-3
lines changed

packages/common.vm/common.vm.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
33
<metadata>
44
<id>common.vm</id>
5-
<version>0.0.0.20250509</version>
5+
<version>0.0.0.20250517</version>
66
<description>Common libraries for VM-packages</description>
77
<authors>Mandiant</authors>
88
</metadata>

packages/common.vm/tools/vm.common/vm.common.psm1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ function VM-Write-Log {
8181
[CmdletBinding()]
8282
Param(
8383
[Parameter(Mandatory=$true, Position=0)]
84-
[ValidateSet("INFO","WARN","ERROR")]
84+
[ValidateSet("INFO","WARN","ERROR","FATAL")]
8585
[String] $level,
8686
[Parameter(Mandatory=$true, Position=1)]
8787
[string] $message
@@ -1834,7 +1834,7 @@ function VM-Get-MSIInstallerPathByProductName {
18341834

18351835
try {
18361836
# Get a list of all installed MSI products
1837-
$installedProducts = Get-CimInstance -Class Win32_Product | Where-Object { $_.Name -like $ProductName }
1837+
$installedProducts = Get-CimInstance -Class Win32_Product | Where-Object { $_.Name -match $ProductName }
18381838

18391839
if (-not $installedProducts) {
18401840
VM-Write-Log "WARN" "No product found with name like '$ProductName'"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
3+
<metadata>
4+
<id>suricata.vm</id>
5+
<version>7.0.10</version>
6+
<authors>Open Information Security Foundation</authors>
7+
<description>Suricata is a network IDS, IPS and NSM engine developed by the OISF and the Suricata community.</description>
8+
<dependencies>
9+
<dependency id="common.vm" version="0.0.0.20250206" />
10+
<dependency id="npcap.vm" version="1.80.20250219" />
11+
</dependencies>
12+
<tags>Networking</tags>
13+
</metadata>
14+
</package>
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
$ErrorActionPreference = 'Stop'
2+
Import-Module vm.common -Force -DisableNameChecking
3+
4+
try{
5+
$toolName = 'suricata'
6+
$category = VM-Get-Category($MyInvocation.MyCommand.Definition)
7+
$toolDir = Join-Path ${Env:ProgramFiles} $toolName
8+
$executablePath = Join-Path $toolDir "$toolName.exe"
9+
$exeUrl = "https://www.openinfosecfoundation.org/download/windows/Suricata-7.0.10-1-64bit.msi"
10+
$sha256 = "b32a6ca8a793a603a23de307c83831c874099f50bbcd2710ee8325d69a49fb44"
11+
12+
$packageArgs = @{
13+
toolName = $toolName
14+
category = $category
15+
filetype = "MSI"
16+
silentArgs = "/qn /norestart"
17+
executablePath = $executablePath
18+
url = $exeUrl
19+
sha256 = $sha256
20+
consoleApp = $true
21+
}
22+
23+
VM-Install-With-Installer @packageArgs
24+
25+
# Delete default desktop shortcut
26+
$desktopShortcutPath = "${Env:HomeDrive}\Users\*\Desktop\$toolName*.lnk"
27+
Remove-Item -Path $desktopShortcutPath -ErrorAction SilentlyContinue
28+
29+
# Rules configuration and download
30+
$rulesXmlPath = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)/rules.xml"
31+
$rulesXml = [xml](Get-Content $rulesXmlPath)
32+
$rulesDir = Join-Path $toolDir "rules" -Resolve
33+
$rules = $rulesXml.rules.rule
34+
35+
# Tempdir for rules been added
36+
# Rules are added to tempdir before been added to default rule folder as other default rules exist in default folder
37+
# Rules filenames are needed for adding to config files
38+
$tempToolDir = Join-Path ${Env:TEMP} "$toolName.vm"
39+
$tempRuleDir = Join-Path $tempToolDir "rules"
40+
41+
foreach ($rule in $rules) {
42+
VM-Write-Log "INFO" "Attempting to install rule: $($rule.name)"
43+
$filePath = Join-Path $tempToolDir ([System.IO.Path]::GetFileName($rule.url))
44+
45+
# Create rule specific temp folder
46+
$tempRuleSpecificFolder = Join-Path $tempRuleDir $rule.name
47+
New-Item $tempRuleSpecificFolder -ItemType Directory -Force
48+
try{
49+
Invoke-WebRequest -Uri $rule.url -OutFile $filePath -ErrorAction Stop
50+
# If the rule URL is a ZIP archive (collection of multiple rule files)
51+
if ($filePath -like '*.zip') {
52+
VM-Write-Log "INFO" "ZIP file detected."
53+
Get-ChocolateyUnzip -FileFullPath $filePath -Destination $tempRuleSpecificFolder | Out-Null
54+
55+
# If the rule URL is one rules file
56+
} elseif ($filePath -like '*.rules') {
57+
VM-Write-Log "INFO" "Rules file detected. Moving to $tempRuleSpecificFolder..."
58+
Move-Item -Path $filePath -Destination $tempRuleSpecificFolder
59+
60+
# Any other types of url resource is unsupported
61+
} else {
62+
throw "Unsupported file type: '$filePath'. Only .zip and .rule are allowed."
63+
}
64+
} catch {
65+
VM-Write-Log "WARN" "Failed rule: $filePath. Cause: $($_.Exception.Message)"
66+
}
67+
}
68+
69+
$allRuleFiles = Get-ChildItem -Path $tempRuleDir -Recurse -File -Filter *.rules
70+
71+
$rulesConfigPath = Join-Path $toolDir "suricata.yaml" -Resolve
72+
$rulesConfigLines = Get-Content -Path $rulesConfigPath
73+
74+
# Index of the location in the yaml where `rule-files:` is specified
75+
# Also collect all rules references in the config file
76+
$ruleFilesIndex = $null
77+
$rulesList = @()
78+
for ($i = 0; $i -lt $rulesConfigLines.Count; $i++) {
79+
$line = $rulesConfigLines[$i].Trim()
80+
81+
# Set ruleFilesIndex when `rule-files:` found
82+
if ($line -match '^rule-files:$') {
83+
$ruleFilesIndex = $i
84+
continue
85+
}
86+
87+
# Only when `rule-files` found, collect the rules references
88+
if ($null -ne $ruleFilesIndex){
89+
90+
# Break rules reference search if the line does not start with '- .*'
91+
if ($line -notmatch "- .*"){
92+
break
93+
}
94+
else{
95+
if ($line -match '\.rules$'){
96+
$cleanLine = $line.TrimStart('- ')
97+
$rulesList += $cleanLine
98+
}
99+
}
100+
}
101+
}
102+
103+
# The config file must have `rule-files:`, throw an error if not found
104+
if ($null -eq $ruleFilesIndex) {
105+
throw "Line with 'rule-files:' string not found in the config file."
106+
}
107+
108+
# Move all rule files in temp rule folder to the suricata rule folder
109+
# Add rules to `suricata.yaml`
110+
VM-Write-Log "INFO" "Moving rule-files to $rulesDir..."
111+
foreach ($ruleFile in $allRuleFiles){
112+
Move-Item -Path $ruleFile.FullName -Destination $rulesDir -Force
113+
if (-not ($rulesList -contains $ruleFile.Name)){
114+
$newRuleLine = " - $($ruleFile.Name)"
115+
# Add rule to config file
116+
$rulesConfigLines = $rulesConfigLines[0..$ruleFilesIndex] + $newRuleLine + $rulesConfigLines[($ruleFilesIndex + 1)..($rulesConfigLines.Length - 1)]
117+
VM-Write-Log "INFO" "[+] Rule-file $($ruleFile.Name) added to $rulesDir. Added rule-file reference to config file."
118+
}
119+
else{
120+
VM-Write-Log "INFO" "[+] Rule-file $($ruleFile.Name) added to $rulesDir. Rule-file reference already exist in config file."
121+
}
122+
}
123+
124+
# Save the updated content back to the file
125+
$rulesConfigLines | Set-Content -Path $rulesConfigPath
126+
}
127+
catch{
128+
VM-Write-Log-Exception $_
129+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
$ErrorActionPreference = 'Continue'
2+
Import-Module vm.common -Force -DisableNameChecking
3+
4+
$toolName = 'suricata'
5+
$category = VM-Get-Category($MyInvocation.MyCommand.Definition)
6+
7+
VM-Uninstall-With-Uninstaller $toolName $category "MSI" "/qn /norestart"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<rules>
3+
<rule name="emerging-all" url="https://rules.emergingthreats.net/open/suricata-7.0.3/emerging.rules.zip" innerFolder="rules"/>
4+
</rules>

0 commit comments

Comments
 (0)