Skip to content

Commit

Permalink
Added OSVersion common function
Browse files Browse the repository at this point in the history
Adjust chainsaw response flow
  • Loading branch information
Hunter-Pittman committed Mar 9, 2023
1 parent dbb515c commit 0b5fa34
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 6 deletions.
1 change: 0 additions & 1 deletion chainsaw/chainsaw.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ func ScanAll() ([]Event, error) {
var CHAINSAW_PATH string = config.GetChainsawPath()
var CHAINSAW_MAPPING_PATH string = config.GetChainsawMapping()
var CHAINSAW_RULES_PATH string = config.GetChainSawRulesBad()
//cmdOutput, err := exec.Command("c:\\Users\\Hunter Pittman\\Documents\\repos\\wingoEDR\\externalresources\\chainsaw\\chainsaw.exe", "--no-banner", "hunt", "C:\\Windows\\System32\\winevt\\Logs", "-s", "C:\\Users\\Hunter Pittman\\Documents\\repos\\wingoEDR\\externalresources\\chainsaw\\rules\\bad", "--mapping", "C:\\Users\\Hunter Pittman\\Documents\\repos\\wingoEDR\\externalresources\\chainsaw\\mappings\\sigma-event-logs-all.yml", "--json").Output()
cmdOutput, err := exec.Command(CHAINSAW_PATH, "--no-banner", "hunt", "C:\\Windows\\System32\\winevt\\Logs\\", "-s", CHAINSAW_RULES_PATH, "--mapping", CHAINSAW_MAPPING_PATH, "--json").Output()
if err != nil {
if strings.Contains(err.Error(), "Specified event log path is invalid") {
Expand Down
14 changes: 11 additions & 3 deletions chainsaw/chainsawResponse.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package chainsaw

import (
"fmt"

"github.com/Jeffail/gabs"
"go.uber.org/zap"
)
Expand All @@ -15,6 +13,16 @@ func FullEventCheck() {
zap.S().Error("Chainsaw events were not scanned: ", err.Error())
}

fmt.Printf("%+v", events[0])
println(events)
}

func RangedEventCheck(fromTimestamp string, toTimestamp string) {
_ = gabs.New()

events, err := ScanTimeRange(fromTimestamp, toTimestamp)
if err != nil {
zap.S().Error("Chainsaw events were not scanned: ", err.Error())
}

println(events)
}
92 changes: 92 additions & 0 deletions common/getOSVersion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package common

import (
"fmt"
"syscall"
"unsafe"
)

type osVersionInfoEx struct {
dwOSVersionInfoSize uint32
dwMajorVersion uint32
dwMinorVersion uint32
dwBuildNumber uint32
dwPlatformId uint32
szCSDVersion [128]uint16
wServicePackMajor uint16
wServicePackMinor uint16
wSuiteMask uint16
wProductType byte
wReserved byte
}

var kernel32 = syscall.NewLazyDLL("kernel32.dll")
var getVersionEx = kernel32.NewProc("GetVersionExW")

func getWindowsVersion() (string, error) {
var info osVersionInfoEx
info.dwOSVersionInfoSize = uint32(unsafe.Sizeof(info))

ret, _, err := getVersionEx.Call(uintptr(unsafe.Pointer(&info)))
if ret == 0 {
return "", err
}

version := fmt.Sprintf("Windows %d.%d", info.dwMajorVersion, info.dwMinorVersion)
if info.dwMajorVersion == 10 {
switch info.dwMinorVersion {
case 0:
version += " (Windows 10)"
case 1:
version += " (Windows 10 Anniversary Update)"
case 2:
version += " (Windows 10 Creators Update)"
case 3:
version += " (Windows 10 Fall Creators Update)"
case 4:
version += " (Windows 10 April 2018 Update)"
case 5:
version += " (Windows 10 October 2018 Update)"
case 6:
version += " (Windows 10 May 2019 Update)"
case 7:
version += " (Windows 10 November 2019 Update)"
case 8:
version += " (Windows 10 May 2020 Update)"
case 9:
version += " (Windows 10 October 2020 Update)"
case 10:
version += " (Windows 10 May 2021 Update)"
default:
version += fmt.Sprintf(" (%d.%d)", info.dwMajorVersion, info.dwMinorVersion)
}
}

if info.dwMajorVersion == 6 {
switch info.dwMinorVersion {
case 0:
version += " (Windows Vista)"
case 1:
version += " (Windows 7)"
case 2:
if info.wServicePackMajor == 0 {
version += " (Windows 8)"
} else {
version += " (Windows 8.1)"
}
default:
version += fmt.Sprintf(" (%d.%d)", info.dwMajorVersion, info.dwMinorVersion)
}
}

return version, nil
}

func OSversion() string {
version, err := getWindowsVersion()
if err != nil {
fmt.Println("Error:", err)
return "Error"
}
return version
}
3 changes: 1 addition & 2 deletions common/inventory.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package common
import (
"fmt"
"os"
"runtime"
"wingoEDR/firewall"
"wingoEDR/processes"
"wingoEDR/servicemanager"
Expand Down Expand Up @@ -43,7 +42,7 @@ func GetInventory() InventoryObject {
SerialScripterName: GetSerialScripterHostName(),
HostName: hostname,
IP: GetIP(),
Os: runtime.GOOS,
Os: OSversion(),
Services: servicemanager.Servicelister(),
Tasks: nil,
Firewall: firewall.FirewallLister(),
Expand Down
28 changes: 28 additions & 0 deletions config/getConfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ type Configuration struct {
URL string `json:"url"`
UserAgent string `json:"user_agent"`
} `json:"serial_scripter"`
Siem struct {
APIKey string `json:"api_key"`
URL string `json:"url"`
} `json:"siem"`
} `json:"apis"`
Blacklist struct {
Ips []any `json:"ips"`
Expand Down Expand Up @@ -165,3 +169,27 @@ func GetChainSawRulesBad() string {
}
return configuration.Chainsaw.Rules.Path.Bad
}

func GetSiemApiKey() string {
file, _ := os.Open(CONFIG_LOC)
defer file.Close()
decoder := json.NewDecoder(file)
configuration := Configuration{}
err := decoder.Decode(&configuration)
if err != nil {
zap.S().Error("error:", err)
}
return configuration.Apis.Siem.APIKey
}

func GetSiemUrl() string {
file, _ := os.Open(CONFIG_LOC)
defer file.Close()
decoder := json.NewDecoder(file)
configuration := Configuration{}
err := decoder.Decode(&configuration)
if err != nil {
zap.S().Error("error:", err)
}
return configuration.Apis.Siem.URL
}
2 changes: 2 additions & 0 deletions config/setupConfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ func generateJSON() {
jsonOBJ.Set("random_placeholder", "apis", "serial_scripter", "api_key")
jsonOBJ.Set("secret", "apis", "serial_scripter", "user_agent")
jsonOBJ.Set("no_url", "apis", "serial_scripter", "url")
jsonOBJ.Set("no_key", "apis", "siem", "api_key")
jsonOBJ.Set("no_url", "apis", "siem", "url")

// EXE Paths
jsonOBJ.Set(externalresourcesPath+"yara\\yara.exe", "exe_paths", "yara")
Expand Down
36 changes: 36 additions & 0 deletions logger/globalLogging.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package logger

import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"time"
"wingoEDR/config"

"go.uber.org/zap"
"go.uber.org/zap/zapcore"
Expand All @@ -20,16 +25,47 @@ Logging level reference
FatalLevel: logs a message, then calls os.Exit(1).
*/

// Add a call to the SIEM if one is available
type RemoteLogger struct {
url string
}

type logMessage struct {
Message string `json:"message"`
Level string `json:"level"`
}

func (rl *RemoteLogger) Write(p []byte) (n int, err error) {
// Marshal the log message as JSON
message := &logMessage{Message: string(p), Level: "error"}
body, err := json.Marshal(message)
if err != nil {
return 0, err
}

// Send a POST request to the remote server with the log message as the body
resp, err := http.Post(rl.url, "application/json", bytes.NewReader(body))
if err != nil {
return 0, err
}
defer resp.Body.Close()
// Discard the response body
_, _ = ioutil.ReadAll(resp.Body)
return len(p), nil
}

func InitLogger() {
createLogDirectory()
writerSync := getLogWriter()
encoder := getEncoder()

//core := zapcore.NewCore(encoder, writerSync, zapcore.DebugLevel)
siemUrl := config.GetSiemUrl()

core := zapcore.NewTee(
zapcore.NewCore(encoder, writerSync, zapcore.DebugLevel),
zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.DebugLevel),
zapcore.NewCore(encoder, zapcore.AddSync(&RemoteLogger{url: siemUrl}), zapcore.ErrorLevel),
)
logg := zap.New(core, zap.AddCaller())

Expand Down

0 comments on commit 0b5fa34

Please sign in to comment.