Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 0 additions & 27 deletions pkg/hostrules/hostrules_interface.go

This file was deleted.

43 changes: 43 additions & 0 deletions pkg/hostrules/v1/consts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package hostrules

import (
_ "embed"
"encoding/json"
)

var (
writeFlags = []string{
"O_WRONLY",
"O_RDWR",
"O_TRUNC",
"O_CREAT",
"O_APPEND"}

allowedNamespaces = map[string]bool{
"ci": true, // CI/CD pipelines
"jenkins": true, // Jenkins workloads
"gitlab": true, // GitLab runners
"build": true, // Build environments
"docker-mgmt": true, // Docker management tools
}
)

//go:embed data/suspicious_tools.json
var suspiciousToolsJSON []byte

var suspiciousTools = func() map[string]toolInfo {
var result struct {
Tools []toolInfo `json:"tools"`
}

if err := json.Unmarshal(suspiciousToolsJSON, &result); err != nil {
panic(err)
}

toolMap := make(map[string]toolInfo)
for _, tool := range result.Tools {
toolMap[tool.Name] = tool
}

return toolMap
}()
189 changes: 189 additions & 0 deletions pkg/hostrules/v1/data/suspicious_tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
{
"tools": [
{
"name": "nmap",
"severity": 1,
"category": "network scanner"
},
{
"name": "masscan",
"severity": 1,
"category": "network scanner"
},
{
"name": "nikto",
"severity": 3,
"category": "web vulnerability scanner"
},
{
"name": "metasploit-framework",
"severity": 3,
"category": "exploitation framework"
},
{
"name": "msfconsole",
"severity": 3,
"category": "exploitation framework"
},
{
"name": "burpsuite",
"severity": 1,
"category": "web security tool"
},
{
"name": "sqlmap",
"severity": 3,
"category": "SQL injection tool"
},
{
"name": "wireshark",
"severity": 1,
"category": "network analyzer"
},
{
"name": "tcpdump",
"severity": 1,
"category": "packet analyzer"
},
{
"name": "tshark",
"severity": 1,
"category": "network analyzer"
},
{
"name": "netcat",
"severity": 2,
"category": "network utility"
},
{
"name": "nc",
"severity": 2,
"category": "network utility"
},
{
"name": "socat",
"severity": 2,
"category": "network utility"
},
{
"name": "john",
"severity": 3,
"category": "password cracker"
},
{
"name": "hashcat",
"severity": 3,
"category": "password cracker"
},
{
"name": "hydra",
"severity": 3,
"category": "brute-force tool"
},
{
"name": "medusa",
"severity": 3,
"category": "brute-force tool"
},
{
"name": "aircrack-ng",
"severity": 3,
"category": "wireless network cracker"
},
{
"name": "reaver",
"severity": 3,
"category": "wireless network cracker"
},
{
"name": "ettercap",
"severity": 3,
"category": "network sniffer & MITM tool"
},
{
"name": "bettercap",
"severity": 3,
"category": "network sniffer & MITM tool"
},
{
"name": "dnsrecon",
"severity": 3,
"category": "DNS reconnaissance tool"
},
{
"name": "dnscan",
"severity": 3,
"category": "DNS reconnaissance tool"
},
{
"name": "theHarvester",
"severity": 3,
"category": "information gathering tool"
},
{
"name": "scapy",
"severity": 2,
"category": "packet manipulation tool"
},
{
"name": "proxychains",
"severity": 2,
"category": "anonymous proxy tool"
},
{
"name": "tor",
"severity": 2,
"category": "anonymity network tool"
},
{
"name": "chisel",
"severity": 3,
"category": "port forwarding & tunneling tool"
},
{
"name": "ngrok",
"severity": 3,
"category": "port forwarding & tunneling tool"
},
{
"name": "responder",
"severity": 3,
"category": "LLMNR/NBT-NS/mDNS poisoning tool"
},
{
"name": "crackmapexec",
"severity": 3,
"category": "post-exploitation tool"
},
{
"name": "pupy",
"severity": 3,
"category": "post-exploitation RAT"
},
{
"name": "empire",
"severity": 3,
"category": "post-exploitation framework"
},
{
"name": "bloodhound",
"severity": 3,
"category": "Active Directory enumeration tool"
},
{
"name": "neo4j",
"severity": 1,
"category": "database used by BloodHound"
},
{
"name": "linpeas",
"severity": 3,
"category": "Linux privilege escalation script"
},
{
"name": "linux-exploit-suggester",
"severity": 3,
"category": "Linux privilege escalation script"
}
]
}
5 changes: 5 additions & 0 deletions pkg/hostrules/v1/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ func NewRuleCreator() *ruleenginev1.RuleCreatorImpl {
ruleenginev1.R1007XMRCryptoMiningRuleDescriptor,
ruleenginev1.R1008CryptoMiningDomainCommunicationRuleDescriptor,
ruleenginev1.R1015MaliciousPtraceUsageRuleDescriptor,
R3001NewlyModifedBinaryLaunchedRuleDescriptor,
R3002CGroupsReleaseAgentModifiedRuleDescriptor,
R3003SuspiciousToolRuleDescriptor,
R3004DockerSocketAccessRuleDescriptor,
R3005MaliciousFsMemoryInjectionRuleDescriptor,
ruleenginev1.R1030UnexpectedIouringOperationRuleDescriptor,
},
}
Expand Down
65 changes: 65 additions & 0 deletions pkg/hostrules/v1/helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package hostrules

import (
_ "embed"
"os"
"path/filepath"
"slices"
"strings"
"time"

"github.com/kubescape/node-agent/pkg/ruleengine"
)

func isSuspiciousTool(execPath string) (bool, int, string) {
parts := strings.Split(execPath, "/")
baseName := parts[len(parts)-1]

if toolInfo, exists := suspiciousTools[baseName]; exists {
return true, toolInfo.Severity, toolInfo.Category
}

return false, ruleengine.RulePriorityLow, ""
}

func isPathNewlyModified(path string, modificationTime time.Time) bool {
fileInfo, err := os.Stat(path)
if err != nil {
return false
}

return fileInfo.ModTime().After(modificationTime)
}

func isAllowedNamespace(namespace string) bool {
if namespace == "" {
return false
}

if allowedNamespaces[namespace] {
return true
}

for pattern := range allowedNamespaces {
if strings.HasPrefix(namespace, pattern+"-") {
return true
}
}

return false
}

func ComparePaths(sourcePath, targetPath string) bool {
cleanSource := filepath.Clean(sourcePath)
cleanTarget := filepath.Clean(targetPath)
return cleanSource == cleanTarget
}

func hasTargetFlags(flags []string, targetFlags []string) bool {
for _, flag := range flags {
if slices.Contains(targetFlags, flag) {
return true
}
}
return false
}
Loading