-
-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathdetection.go
128 lines (111 loc) · 3.28 KB
/
detection.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Kraken
// Copyright (C) 2016-2020 Claudio Guarnieri
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package main
import (
"os"
"path/filepath"
log "github.com/Sirupsen/logrus"
"github.com/botherder/go-savetime/files"
"github.com/botherder/go-savetime/hashes"
)
// Detection contains the information to report a Yara detection.
type Detection struct {
Type string `json:"type"`
ImagePath string `json:"image_path"`
ImageName string `json:"image_name"`
MD5 string `json:"md5"`
SHA1 string `json:"sha1"`
SHA256 string `json:"sha256"`
ProcessID int32 `json:"process_id"`
Signature string `json:"signature"`
}
// NewDetection instantiates a new Detection.
func NewDetection(recordType, imagePath, imageName, signature string, pid int32) *Detection {
md5, _ := hashes.FileMD5(imagePath)
sha1, _ := hashes.FileSHA1(imagePath)
sha256, _ := hashes.FileSHA256(imagePath)
return &Detection{
Type: recordType,
ImagePath: imagePath,
ImageName: imageName,
MD5: md5,
SHA1: sha1,
SHA256: sha256,
ProcessID: pid,
Signature: signature,
}
}
// Report sends information on a detection tot he API server.
func (d *Detection) Report() error {
// First we try to report the detection automatically, so that don't have
// to wait for the next heartbeat iterations in order to report it.
err := apiDetection(d)
// If the report was successful, we don't need to mark it as pending in the
// local database.
if err != nil {
log.Error(err.Error())
return err
}
return nil
}
// Store stores the Detection record in the local SQLite database.
func (d *Detection) Store(wasReported bool) error {
db := NewDatabase()
err := db.Open()
if err != nil {
log.Error(err.Error())
return err
}
defer db.Close()
_, err = db.StoreDetection(d, wasReported)
if err != nil {
log.Error(err.Error())
return err
}
return nil
}
// Backup will keep a copy
func (d *Detection) Backup() error {
if _, err := os.Stat(d.ImagePath); err != nil {
return err
}
dstPath := filepath.Join(StorageFiles, d.SHA1)
if _, err := os.Stat(dstPath); os.IsNotExist(err) {
err = files.Copy(d.ImagePath, dstPath)
if err != nil {
return err
}
}
return nil
}
// ReportAndStore is a helper function that will correctly report to the API
// server and store an entry in the local database. Created to avoid code reuse.
func (d *Detection) ReportAndStore() error {
// If the report flag was enabled, we send the detection to the API server.
wasReported := false
if *report == true {
err := d.Report()
if err == nil {
wasReported = true
}
}
// If we're running in daemon mode, we store results locally.
if *daemon == true {
d.Store(wasReported)
d.Backup()
}
return nil
}