Skip to content

Commit b305b97

Browse files
committed
fixes, and pushing to new tag
1 parent e4c3c3e commit b305b97

File tree

8 files changed

+325
-53
lines changed

8 files changed

+325
-53
lines changed

README.md

+46-40
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,32 @@ I also wrote a blog post showcasing this project: [Identifying Malicious Bytes i
77

88
![GoCheck2](./assets/cobalt.gif)
99

10+
## Installation
11+
You can install `gocheck` from `go install`
12+
```bash
13+
go install github.com/gatariee/gocheck@latest
14+
```
15+
16+
Alternatively, you can download the precompiled binaries from the [releases](https://github.com/gatariee/gocheck/releases) or build it yourself.
17+
```bash
18+
git clone https://github.com/gatariee/gocheck
19+
make [ windows / win64 / win32 ]
20+
```
21+
1022
## Usage
1123
```cmd
1224
$ gocheck check --help
1325
Usage:
14-
gocheck check [flags]
26+
gocheck check [path_to_bin] /optional [flags]
1527
1628
Flags:
17-
-a, --amsi Use AMSI to scan a file
18-
-d, --defender Use Windows Defender to scan a binary
19-
-f, --file string Binary to check
20-
-h, --help help for check
29+
-a, --amsi Use AMSI to scan the binary
30+
-D, --debug Enable debug mode
31+
-d, --defender Use Windows Defender to scan the binary
32+
-h, --help help for check
33+
34+
[!] UNSTABLE
35+
-k, --kaspersky Use Kaspersky's AV Engine to scan the binary
2136
```
2237

2338
## Quick Use
@@ -49,54 +64,45 @@ Add-MpPreference -ExclusionPath [path_to_folder]
4964
```
5065
![amsi](https://i.gyazo.com/0c0a437eafe2c945c7d1188fdd9ec86d.png)
5166

52-
## Both Windows Defender & AMSI
53-
You can also scan using both Windows Defender and AMSI at the same time.
54-
```cmd
55-
gocheck [path_to_file] /optional: --defender --amsi
56-
```
57-
![both](https://i.gyazo.com/5bb7681b57cd8736329ccd22ac7e9d7c.png)
67+
## External Scanners
68+
There is currently only support for [Kaspersky](https://www.kaspersky.com/security-cloud)'s Security Cloud AV Engine. The `--kaspersky` flag can be used to scan the binary using Kaspersky's AV Engine.
5869

59-
## Debug
60-
Gocheck is in heavy WIP and may not work as expected. If you encounter any issues, please run the tool with `--debug` to provide more information about the issue. The `--debug` flag prints out which portions of the binary are being scanned, as well as sanity checks to ensure that the signatured portions are being correctly scanned.
70+
There **are** plans to integrate more AV engines in the future.
71+
72+
> It is normal for Kaspersky's AV engine to take a little longer than Windows Defender to scan the binary.
6173
```cmd
62-
gocheck [path_to_file] /optional: --debug
74+
gocheck [path_to_file] /optional: --kaspersky
6375
```
64-
![debug](https://i.gyazo.com/c6bb797e5b507b2ba7fc0d007575a410.png)
76+
![kaspersky](https://i.gyazo.com/346a57bb13a2b6fef5f6ae889c9e45d2.png)
6577

66-
## Installation
67-
You can install `gocheck` from `go install`
68-
```bash
69-
go install github.com/gatariee/gocheck@latest
70-
```
78+
## Concurrency
79+
`gocheck` allows you to scan a binary using multiple AV engines simultaneously. This is done by passing multiple flags to `gocheck`.
7180

72-
Alternatively, you can download the precompiled binaries from the [releases](https://github.com/gatariee/gocheck/releases) or build it yourself.
73-
```bash
74-
git clone https://github.com/gatariee/gocheck
75-
make [ windows / win64 / win32 ]
81+
For example, to scan a binary using both **Windows Defender** and **Kaspersky's AV Engine**, you can pass the following flags to `gocheck` & the results will be returned at runtime.
82+
```cmd
83+
gocheck [path_to_file] /optional: --defender --kaspersky
7684
```
85+
![kaspersky2](https://i.gyazo.com/3cd9b23ab285c33804a11c7440b1cdfc.png)
7786

78-
### Evasion Usage
79-
You can use `gocheck` to identify bad bytes, and then pass the identified offset of bad bytes into [ghidra](https://github.com/NationalSecurityAgency/ghidra) (or, any other decompiler) to hopefully decompile the binary and locate the bad bytes in a function.
80-
81-
I'll be using `ghidra` to decompile the binary since I'm more familiar with it. (and, it's free)
82-
#### 1. Check for Bad Bytes
87+
## Debug
88+
Gocheck is in heavy WIP and may not work as expected. If you encounter any issues, please run the tool with `--debug` to provide more information about the issue. The `--debug` flag prints out which portions of the binary are being scanned, as well as sanity checks to ensure that the signatured portions are being correctly scanned.
8389
```cmd
84-
$ gocheck <file> /optional:args
90+
gocheck [path_to_file] /optional: --debug
8591
```
92+
![debug](https://i.gyazo.com/c6bb797e5b507b2ba7fc0d007575a410.png)
8693

87-
![1](./assets/f14b57d0ca353d1de97ec67c98512cd1.png)
88-
* Identified bad bytes at offset **0x9DD** (from start of binary)
89-
* 16 bytes **before & after** the bad bytes are also printed for context, but doesn't help much in this case.
90-
91-
#### 2. Open the binary in Ghidra
92-
* Navigation -> Go To... -> **FILE ( 0x9DD )**
93-
* Alternatively, `G` also brings up the same dialog.
94+
## Common Pitfalls
95+
1. You may need to set exclusions when using `gocheck` to prevent the file from being nuked on first scan, here's how `gocheck` works under the hood:
96+
* `gocheck` first passes the original file to `MpCmdRun.exe` to scan the file using Windows Defender -> (e.g ./mimikatz.exe)
97+
* If the scan comes back malicious, we create a folder in the **current working directory** with the respective name of the scanner (e.g `windef`).
98+
* Then, we start splitting the file (with reference to the original file), and writing the split bytes to the respective folder (e.g `windef`).
9499

95-
![2](./assets/587cc1659ee36bfb12a9f2525fac40cb.png)
100+
> There are multiple exclusions you need to set, or you can exclude the entire folder where `gocheck` is located.
101+
102+
2. Where possible, we try to pass in flags that are not destructive such as `-DisableRemediation` for Windows Defender and `/i0` for Kaspersky's AV Engine. However, whether the file gets sent to the cloud for further analysis **is not** within our control.
103+
* It is ultimately the responsibility of the operator to assume that the AV engine **will** try it's best to send all binaries to the cloud for further analysis; and to take the necessary precautions to prevent this from happening such as disabling internet access.
96104

97-
* The bad bytes are identified after a call to `VirtualAlloc` and before a call to `VirtualProtect` in this case, which should be easy to find in the artifact kit.
98105

99-
![3](./assets/f6386e807de01acfa9bc301e2c0920c9.png)
100106

101107
## Benchmark
102108
> ⚠️ I am not an expert in benchmarking, and the following benchmarks are conducted on a single machine, and the results may vary on different machines. The benchmarks are conducted on a single machine to provide a rough estimate of the performance difference between `gocheck` and `DefenderCheck`.

bin/gocheck32.exe

-284 KB
Binary file not shown.

bin/gocheck64.exe

17 KB
Binary file not shown.

cmd/check.go

+33-12
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,12 @@ var checkCmd = &cobra.Command{
2929
amsi, _ := cmd.Flags().GetBool("amsi")
3030
defender, _ := cmd.Flags().GetBool("defender")
3131
debug, _ := cmd.Flags().GetBool("debug")
32+
kaspersky, _ := cmd.Flags().GetBool("kaspersky")
3233

3334
if debug {
3435
utils.PrintInfo("Debug mode enabled, verbose output will be displayed")
3536
}
3637

37-
if !amsi && !defender {
38-
/* Assume that the user wants to use defender */
39-
defender = true
40-
}
41-
4238
var (
4339
defender_path string
4440
err error
@@ -56,11 +52,36 @@ var checkCmd = &cobra.Command{
5652
defender_path = ""
5753
}
5854

55+
var avp string
56+
if kaspersky {
57+
avp, err = scanner.FindKaspersky()
58+
if err != nil {
59+
utils.PrintErr(err.Error())
60+
return
61+
}
62+
63+
if avp == "" {
64+
utils.PrintErr("Kaspersky not found, please ensure it's installed and the path is correct")
65+
utils.PrintInfo("Kaspersky is probably installed at > ")
66+
fmt.Println("\t", scanner.ScanPath)
67+
fmt.Println("\t", scanner.AltScanPath)
68+
return
69+
}
70+
71+
utils.PrintInfo(fmt.Sprintf("Found Kaspersky at %s", avp))
72+
}
73+
74+
additionals := make(map[string]string)
75+
if kaspersky {
76+
additionals["kaspersky"] = avp
77+
}
78+
5979
token := scanner.Scanner{
6080
File: file,
6181
Amsi: amsi,
6282
Defender: defender,
6383
EnginePath: defender_path,
84+
Additional: additionals,
6485
}
6586

6687
start := time.Now()
@@ -71,13 +92,6 @@ var checkCmd = &cobra.Command{
7192
},
7293
}
7394

74-
func init() {
75-
rootCmd.AddCommand(checkCmd)
76-
checkCmd.Flags().BoolP("amsi", "a", false, "Use AMSI to scan the binary")
77-
checkCmd.Flags().BoolP("defender", "d", false, "Use Windows Defender to scan the binary")
78-
checkCmd.Flags().BoolP("debug", "D", false, "Enable debug mode")
79-
}
80-
8195
func GetFileSize(file string) (int64, error) {
8296
fileInfo, err := os.Stat(file)
8397
if err != nil {
@@ -123,3 +137,10 @@ func FindDefenderPath(root string) (string, error) {
123137
})
124138
return defenderPath, err
125139
}
140+
141+
func init() {
142+
checkCmd.Flags().BoolP("amsi", "a", false, "Use AMSI to scan the binary")
143+
checkCmd.Flags().BoolP("defender", "d", false, "Use Windows Defender to scan the binary")
144+
checkCmd.Flags().BoolP("kaspersky", "k", false, "Use Kaspersky to scan the binary")
145+
checkCmd.Flags().BoolP("debug", "D", false, "Enable debug mode")
146+
}

cmd/root.go

+5
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ func Execute() {
4444
}
4545

4646
func init() {
47+
rootCmd.AddCommand(checkCmd)
4748
rootCmd.Version = VERSION
4849
rootCmd.SetVersionTemplate("GoCheck version {{.Version}}\n")
50+
51+
rootCmd.Root().CompletionOptions.DisableDefaultCmd = true
52+
rootCmd.Root().CompletionOptions.DisableDescriptions = true
53+
rootCmd.SetHelpCommand(&cobra.Command{Use: "no-help", Run: func(cmd *cobra.Command, args []string) { /* Do nothing */ }})
4954
}

0 commit comments

Comments
 (0)