Enhance detection logic to include process-based suspicious connection checks and refine firewall rule attributes in eliminate package. Add PID-to-process name mapping functionality.
This commit is contained in:
@@ -40,16 +40,57 @@ func DetectOutboundConnections() []NetworkConnection {
|
|||||||
func compareConnections(connections []NetworkConnection) []NetworkConnection {
|
func compareConnections(connections []NetworkConnection) []NetworkConnection {
|
||||||
var suspiciousConnections []NetworkConnection
|
var suspiciousConnections []NetworkConnection
|
||||||
|
|
||||||
for _, conn := range connections {
|
// Get process names for all PIDs
|
||||||
remote := conn.RemoteHost
|
pidToProcessName := getProcessNamesForPIDs(connections)
|
||||||
|
|
||||||
|
for _, conn := range connections {
|
||||||
|
isSuspicious := false
|
||||||
|
reason := ""
|
||||||
|
|
||||||
|
// Check 1: DNS pattern match (domain-based detection)
|
||||||
|
remote := conn.RemoteHost
|
||||||
for _, dns := range common.CommonDNS {
|
for _, dns := range common.CommonDNS {
|
||||||
if matchesDNSPattern(remote, dns) {
|
if matchesDNSPattern(remote, dns) {
|
||||||
fmt.Printf(" [?] Found %s\n", conn.RemoteHost)
|
isSuspicious = true
|
||||||
suspiciousConnections = append(suspiciousConnections, conn)
|
reason = fmt.Sprintf("DNS match: %s", conn.RemoteHost)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check 2: Process name match (catches RMMs using custom relay servers)
|
||||||
|
if !isSuspicious && conn.PID != "" {
|
||||||
|
if processName, exists := pidToProcessName[conn.PID]; exists {
|
||||||
|
processNameLower := strings.ToLower(processName)
|
||||||
|
|
||||||
|
// Check against known RMM names
|
||||||
|
for _, rmm := range common.CommonRMMs {
|
||||||
|
if strings.Contains(processNameLower, strings.ToLower(rmm)) {
|
||||||
|
isSuspicious = true
|
||||||
|
reason = fmt.Sprintf("RMM process: %s", processName)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check against known RMM executable patterns
|
||||||
|
if !isSuspicious {
|
||||||
|
for _, pattern := range common.CommonImageSuffixes {
|
||||||
|
patternLower := strings.ToLower(pattern)
|
||||||
|
// Remove leading backslash for matching
|
||||||
|
patternClean := strings.TrimPrefix(patternLower, "\\")
|
||||||
|
if strings.Contains(processNameLower, patternClean) {
|
||||||
|
isSuspicious = true
|
||||||
|
reason = fmt.Sprintf("RMM executable: %s", processName)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isSuspicious {
|
||||||
|
fmt.Printf(" [?] Found %s (%s)\n", conn.RemoteHost, reason)
|
||||||
|
suspiciousConnections = append(suspiciousConnections, conn)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("[+] Found %d Suspicious Outbound Connections\n", len(suspiciousConnections))
|
fmt.Printf("[+] Found %d Suspicious Outbound Connections\n", len(suspiciousConnections))
|
||||||
@@ -190,3 +231,39 @@ func GetHTTPHostnames() []string {
|
|||||||
|
|
||||||
return hostnames
|
return hostnames
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getProcessNamesForPIDs returns a map of PID -> process name for all connections
|
||||||
|
func getProcessNamesForPIDs(connections []NetworkConnection) map[string]string {
|
||||||
|
pidMap := make(map[string]string)
|
||||||
|
|
||||||
|
// Collect unique PIDs
|
||||||
|
uniquePIDs := make(map[string]bool)
|
||||||
|
for _, conn := range connections {
|
||||||
|
if conn.PID != "" && conn.PID != "0" {
|
||||||
|
uniquePIDs[conn.PID] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query process names for each PID
|
||||||
|
for pid := range uniquePIDs {
|
||||||
|
processName := getProcessNameByPID(pid)
|
||||||
|
if processName != "" {
|
||||||
|
pidMap[pid] = processName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pidMap
|
||||||
|
}
|
||||||
|
|
||||||
|
// getProcessNameByPID returns the process name for a given PID
|
||||||
|
func getProcessNameByPID(pid string) string {
|
||||||
|
cmd := exec.Command("powershell", "-Command",
|
||||||
|
fmt.Sprintf("(Get-Process -Id %s -ErrorAction SilentlyContinue).ProcessName", pid))
|
||||||
|
output, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
processName := strings.TrimSpace(string(output))
|
||||||
|
return processName
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,16 +21,16 @@ func EliminateConnection(dst string) error {
|
|||||||
|
|
||||||
// Add a block rule for the destination
|
// Add a block rule for the destination
|
||||||
return fw.AddRule(firewall.FirewallRule{
|
return fw.AddRule(firewall.FirewallRule{
|
||||||
Name: fmt.Sprintf("Block Outgoing %s", dst),
|
Name: fmt.Sprintf("Block Outgoing %s", dst),
|
||||||
Direction: "outbound",
|
Direction: "outbound",
|
||||||
Protocol: "*",
|
Protocol: "*",
|
||||||
LocalPort: "",
|
LocalPort: "",
|
||||||
RemotePort: "",
|
RemotePort: "",
|
||||||
LocalAddress: "",
|
LocalAddress: "",
|
||||||
RemoteAddress: "%s",
|
RemoteIPAddresses: "",
|
||||||
Action: "block",
|
Action: "block",
|
||||||
Profile: "",
|
Profile: "",
|
||||||
Destination: dst,
|
DestinationHostname: dst,
|
||||||
Source: "",
|
Source: "",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user