Merge pull request #4 from FourCoreLabs/fix-remove-struct

refactor: remove EDRHunt structure; doc: add comments for various functions; move scanners global to pkg/edrRecon
This commit is contained in:
achilles4828
2021-10-12 17:44:41 +05:30
committed by GitHub
12 changed files with 67 additions and 56 deletions
+7 -16
View File
@@ -14,17 +14,8 @@ var (
services bool
registry bool
all bool
versionStr string = "1.0"
versionStr string = "1.1"
versionCheck bool
recon edrRecon.EdrHunt
scanners = []edrRecon.EDRDetection{
&edrRecon.WinDefenderDetection{},
&edrRecon.KaskperskyDetection{},
&edrRecon.CrowdstrikeDetection{},
&edrRecon.CylanceDetection{},
&edrRecon.McafeeDetection{},
&edrRecon.SymantecDetection{},
}
)
func printBanner() {
@@ -57,25 +48,25 @@ func edrCommand(cmd *cobra.Command, args []string) {
if processes {
fmt.Println("[PROCESSES]")
summary, _ := recon.CheckProcesses()
summary, _ := edrRecon.CheckProcesses()
printProcess(summary)
fmt.Println()
}
if drivers {
fmt.Println("[DRIVERS]")
summary, _ := recon.CheckDrivers()
summary, _ := edrRecon.CheckDrivers()
printDrivers(summary)
fmt.Println()
}
if services {
fmt.Println("[SERVICES]")
summary, _ := recon.CheckServices()
summary, _ := edrRecon.CheckServices()
printServices(summary)
fmt.Println()
}
if registry {
fmt.Println("[REGISTRY]")
summary, _ := recon.CheckRegistry()
summary, _ := edrRecon.CheckRegistry()
printRegistry(summary)
fmt.Println()
}
@@ -87,9 +78,9 @@ func versionCommand(cmd *cobra.Command, args []string) {
func scanEDRCommand(cmd *cobra.Command, args []string) {
fmt.Println("[EDR]")
systemData, _ := recon.GetSystemData()
systemData, _ := edrRecon.GetSystemData()
for _, scanner := range scanners {
for _, scanner := range edrRecon.Scanners {
_, ok := scanner.Detect(systemData)
if ok {
fmt.Printf("Detected EDR: %s\n", scanner.Name())
+1 -1
View File
@@ -2,6 +2,6 @@ package edrRecon
import "fmt"
func (edr *EdrHunt) CheckDirectory() (string, error) {
func CheckDirectory() (string, error) {
return "", fmt.Errorf("directory scan is not implemented: unnecessarily slow, genrates false positives, also, monitoring command line so, reduntant, again")
}
+2 -2
View File
@@ -231,8 +231,8 @@ func AnalyzeDriver(driverFileName string, driverBaseName string) (DriverMetaData
return DriverMetaData{ScanMatch: make([]string, 0)}, err
}
func (edr *EdrHunt) CheckDrivers() ([]DriverMetaData, error) {
// CheckDrivers return a list of drivers matching any suspicious driver names present in edrdata.go.
func CheckDrivers() ([]DriverMetaData, error) {
sizeOfDriverArrayInBytes, err := GetSizeOfDriversArray()
if err != nil {
return []DriverMetaData{}, err
-2
View File
@@ -8,8 +8,6 @@ type Recon interface {
CheckDirectory() (string, error)
}
type EdrHunt struct{}
type FileMetaData struct {
ProductName string
OriginalFilename string
+5 -7
View File
@@ -6,11 +6,9 @@ import (
"testing"
)
var recon EdrHunt
func TestCheckDrivers(t *testing.T) {
summary, err := recon.CheckDrivers()
summary, err := CheckDrivers()
for _, driver := range summary {
output := fmt.Sprintf("\nSuspicious Driver Module: %s\nDriver FilePath: %s\nDriver File Metadata: %s\nMatched Keyword: %s\n", driver.DriverBaseName, driver.DriverFilePath, FileMetaDataParser(driver.DriverSysMetaData), driver.ScanMatch)
fmt.Println(output)
@@ -21,7 +19,7 @@ func TestCheckDrivers(t *testing.T) {
}
func TestCheckRegistry(t *testing.T) {
summary, err := recon.CheckRegistry()
summary, err := CheckRegistry()
fmt.Println("Scanning registry: ")
for _, match := range summary.ScanMatch {
fmt.Printf("\t%s\n", match)
@@ -33,7 +31,7 @@ func TestCheckRegistry(t *testing.T) {
}
func TestCheckServices(t *testing.T) {
summary, err := recon.CheckServices()
summary, err := CheckServices()
for _, service := range summary {
output := fmt.Sprintf("\nSuspicious Service Name: %s\nDisplay Name: %s\nDescription: %s\nCaption: %s\nCommandLine: %s\nStatus: %s\nProcessID: %s\nFile Metadata: %s\nMatched Keyword: %s\n", service.ServiceName, service.ServiceDisplayName, service.ServiceDescription, service.ServiceCaption, service.ServicePathName, service.ServiceState, service.ServiceProcessId, FileMetaDataParser(service.ServiceExeMetaData), service.ScanMatch)
fmt.Println(output)
@@ -44,7 +42,7 @@ func TestCheckServices(t *testing.T) {
}
func TestCheckProcesses(t *testing.T) {
summary, err := recon.CheckProcesses()
summary, err := CheckProcesses()
for _, process := range summary {
output := fmt.Sprintf("\nSuspicious Process Name: %s\nDescription: %s\nCaption: %s\nBinary: %s\nProcessID: %s\nParent Process: %s\nProcess CmdLine : %s\nFile Metadata: %s\nMatched Keyword: %s\n", process.ProcessName, process.ProcessDescription, process.ProcessCaption, process.ProcessPath, process.ProcessPID, process.ProcessParentPID, process.ProcessCmdLine, FileMetaDataParser(process.ProcessExeMetaData), process.ScanMatch)
fmt.Println(output)
@@ -64,7 +62,7 @@ func TestGetFileMetaData(t *testing.T) {
}
func TestGetDirectory(t *testing.T) {
_, err := recon.CheckDirectory()
_, err := CheckDirectory()
if err != nil {
t.Error(err)
}
+2 -1
View File
@@ -13,7 +13,8 @@ var (
err error
)
// crashes at line 334 sometimes.
// GetFileMetaData retuns the metadata of a file at filepath from the windows version information resources using the go-fileversion library.
// TODO: crashes at line 334 sometimes.
func GetFileMetaData(filepath string) (FileMetaData, error) {
defer func() {
if r := recover(); r != nil {
+1
View File
@@ -4,6 +4,7 @@ import (
"os"
)
// CheckIfAdmin checks if the process has administrator privileges by trying to open the PHYSICALDRIVE0 (C:\\) raw device on Windows.
func CheckIfAdmin() bool {
f, err := os.Open("\\\\.\\PHYSICALDRIVE0")
if err != nil {
+4 -1
View File
@@ -20,7 +20,8 @@ type Win32_Process struct {
// StartMode string
}
func (edr *EdrHunt) CheckProcesses() ([]ProcessMetaData, error) {
// CheckProcesses returns a list of processes matching any suspicious running process names present in edrdata.go.
func CheckProcesses() ([]ProcessMetaData, error) {
var (
processList []Win32_Process
errArray []string
@@ -56,9 +57,11 @@ func AnalyzeProcess(process Win32_Process) (ProcessMetaData, error) {
ProcessPID: fmt.Sprint(process.ProcessId),
ProcessParentPID: fmt.Sprint(process.ParentProcessId),
}
if analysis.ProcessPath != "" {
analysis.ProcessExeMetaData, err = GetFileMetaData(analysis.ProcessPath)
}
for _, edr := range EdrList {
if strings.Contains(
strings.ToLower(fmt.Sprint(analysis)),
+1 -1
View File
@@ -60,7 +60,7 @@ func EnumRegistry() []string {
return output
}
func (edr *EdrHunt) CheckRegistry() (RegistryMetaData, error) {
func CheckRegistry() (RegistryMetaData, error) {
output := strings.Join(EnumRegistry(), " ")
var analysis RegistryMetaData
+40 -24
View File
@@ -1,30 +1,18 @@
package edrRecon
func (e *EdrHunt) GetSystemData() (SystemData, error) {
var systemData SystemData
systemData.Processes, err = e.CheckProcesses()
if err != nil {
return systemData, err
var (
Scanners = []EDRDetection{
&CarbonBlackDetection{},
&CrowdstrikeDetection{},
&CylanceDetection{},
&FireEyeDetection{},
&KaskperskyDetection{},
&McafeeDetection{},
&SymantecDetection{},
&SentinelOneDetection{},
&WinDefenderDetection{},
}
systemData.Services, err = e.CheckServices()
if err != nil {
return systemData, err
}
systemData.Registry, err = e.CheckRegistry()
if err != nil {
return systemData, err
}
systemData.Drivers, err = e.CheckDrivers()
if err != nil {
return systemData, err
}
return systemData, nil
}
)
type SystemData struct {
Processes []ProcessMetaData
@@ -33,6 +21,7 @@ type SystemData struct {
Drivers []DriverMetaData
}
// CountMatchesAll collects all the scanned matches of suspicious names and checks for passed keywords in the matches.
func (s *SystemData) CountMatchesAll(keywords ...[]string) (int, bool) {
var match bool
var count int
@@ -74,6 +63,33 @@ func (s *SystemData) CountMatchesAll(keywords ...[]string) (int, bool) {
return count, match
}
// GetSystemData collects the parsed list of processes, services, drivers and registry keys to be used for EDR heuristics.
func GetSystemData() (SystemData, error) {
var systemData SystemData
systemData.Processes, err = CheckProcesses()
if err != nil {
return systemData, err
}
systemData.Services, err = CheckServices()
if err != nil {
return systemData, err
}
systemData.Registry, err = CheckRegistry()
if err != nil {
return systemData, err
}
systemData.Drivers, err = CheckDrivers()
if err != nil {
return systemData, err
}
return systemData, nil
}
type EDRDetection interface {
Detect(data SystemData) (EDRType, bool)
Name() string
+2 -1
View File
@@ -19,7 +19,8 @@ type Win32_Service struct {
// StartMode string
}
func (edr *EdrHunt) CheckServices() ([]ServiceMetaData, error) {
// CheckServices return a list of installed services matching any suspicious service names present in edrdata.go.
func CheckServices() ([]ServiceMetaData, error) {
var (
serviceList []Win32_Service
errArray []string
+2
View File
@@ -2,6 +2,7 @@ package edrRecon
import "strings"
// StrSliceEqual checks wheter slice s contains a string exactly like e.
func StrSliceEqual(s []string, e string) bool {
for _, a := range s {
if strings.EqualFold(a, e) {
@@ -11,6 +12,7 @@ func StrSliceEqual(s []string, e string) bool {
return false
}
// StrSliceContains checks wheter slice s contains a string which contains e.
func StrSliceContains(s []string, e string) bool {
for _, a := range s {
if strings.Contains(a, e) {