44 "encoding/json"
55 "errors"
66 "fmt"
7+ "os"
8+ "strings"
9+ "time"
710
811 "github.com/go-resty/resty/v2"
912 "github.com/mariocandela/beelzebub/v3/parser"
@@ -12,10 +15,38 @@ import (
1215 "gopkg.in/yaml.v3"
1316)
1417
18+ type EventDTO struct {
19+ DateTime string
20+ RemoteAddr string
21+ Protocol string
22+ Command string
23+ CommandOutput string
24+ Status string
25+ Msg string
26+ ID string
27+ Environ string
28+ User string
29+ Password string
30+ Client string
31+ Headers string
32+ HeadersMap map [string ][]string
33+ Cookies string
34+ UserAgent string
35+ HostHTTPRequest string
36+ Body string
37+ HTTPMethod string
38+ RequestURI string
39+ Description string
40+ SourceIp string
41+ SourcePort string
42+ TLSServerName string
43+ }
44+
1545type beelzebubCloud struct {
16- URI string
17- AuthToken string
18- client * resty.Client
46+ URI string
47+ AuthToken string
48+ client * resty.Client
49+ PollingInterval time.Duration
1950}
2051
2152type HoneypotConfigResponseDTO struct {
@@ -25,16 +56,30 @@ type HoneypotConfigResponseDTO struct {
2556 LastUpdatedOn string `json:"lastUpdatedOn"`
2657}
2758
28- func InitBeelzebubCloud (uri , authToken string ) * beelzebubCloud {
29- return & beelzebubCloud {
30- URI : uri ,
31- AuthToken : authToken ,
32- client : resty .New (),
59+ func InitBeelzebubCloud (uri , authToken string , enableVerifyConfigurationsChanged bool ) * beelzebubCloud {
60+ beelzebubCloud := & beelzebubCloud {
61+ URI : uri ,
62+ AuthToken : authToken ,
63+ client : resty .New (),
64+ PollingInterval : 15 * time .Second ,
65+ }
66+ if enableVerifyConfigurationsChanged {
67+ go func () {
68+ if err := beelzebubCloud .verifyConfigurationsChanged (); err != nil {
69+ log .Fatalf ("Error verify configurations changed: %s" , err .Error ())
70+ }
71+ }()
3372 }
73+ return beelzebubCloud
3474}
3575
3676func (beelzebubCloud * beelzebubCloud ) SendEvent (event tracer.Event ) (bool , error ) {
37- requestJson , err := json .Marshal (event )
77+ eventDTO , err := beelzebubCloud .mapToEventDTO (event )
78+ if err != nil {
79+ return false , err
80+ }
81+
82+ requestJson , err := json .Marshal (eventDTO )
3883 if err != nil {
3984 return false , err
4085 }
@@ -59,9 +104,9 @@ func (beelzebubCloud *beelzebubCloud) SendEvent(event tracer.Event) (bool, error
59104 return response .StatusCode () == 200 , nil
60105}
61106
62- func (beelzebubCloud * beelzebubCloud ) GetHoneypotsConfigurations () ([]parser.BeelzebubServiceConfiguration , error ) {
107+ func (beelzebubCloud * beelzebubCloud ) GetHoneypotsConfigurations () ([]parser.BeelzebubServiceConfiguration , string , error ) {
63108 if beelzebubCloud .AuthToken == "" {
64- return nil , errors .New ("authToken is empty" )
109+ return nil , "" , errors .New ("authToken is empty" )
65110 }
66111
67112 response , err := beelzebubCloud .client .R ().
@@ -71,34 +116,98 @@ func (beelzebubCloud *beelzebubCloud) GetHoneypotsConfigurations() ([]parser.Bee
71116 Get (fmt .Sprintf ("%s/honeypots" , beelzebubCloud .URI ))
72117
73118 if err != nil {
74- return nil , err
119+ return nil , "" , err
75120 }
76121
77122 if response .StatusCode () != 200 {
78- return nil , errors .New (fmt .Sprintf ("Response code: %v, error: %s" , response .StatusCode (), string (response .Body ())))
123+ return nil , "" , errors .New (fmt .Sprintf ("Response code: %v, error: %s" , response .StatusCode (), string (response .Body ())))
79124 }
80125
81126 var honeypotsConfig []HoneypotConfigResponseDTO
82127
83128 if err = json .Unmarshal (response .Body (), & honeypotsConfig ); err != nil {
84- return nil , err
129+ return nil , "" , err
85130 }
86131
87132 var servicesConfiguration = make ([]parser.BeelzebubServiceConfiguration , 0 )
133+ var localHashBuilder strings.Builder
88134
89135 for _ , honeypotConfig := range honeypotsConfig {
90136 var honeypotsConfig parser.BeelzebubServiceConfiguration
91137
92138 if err = yaml .Unmarshal ([]byte (honeypotConfig .Config ), & honeypotsConfig ); err != nil {
93- return nil , err
139+ return nil , "" , err
94140 }
95141 if err := honeypotsConfig .CompileCommandRegex (); err != nil {
96- return nil , fmt .Errorf ("unable to load service config from cloud: invalid regex: %v" , err )
142+ return nil , "" , fmt .Errorf ("unable to load service config from cloud: invalid regex: %v" , err )
97143 }
98144 servicesConfiguration = append (servicesConfiguration , honeypotsConfig )
145+
146+ if hashCode , err := honeypotsConfig .HashCode (); err != nil {
147+ return nil , "" , err
148+ } else {
149+ localHashBuilder .WriteString (hashCode )
150+ }
151+
99152 }
100153
101- log .Debug (servicesConfiguration )
154+ return servicesConfiguration , localHashBuilder .String (), nil
155+ }
156+
157+ var exitFunction func (code int ) = os .Exit
158+
159+ func (beelzebubCloud * beelzebubCloud ) verifyConfigurationsChanged () error {
160+ var lastConfigurationsHash = ""
161+ for {
162+ log .Debug ("Checking configurations..." )
163+ _ , configurationsHash , err := beelzebubCloud .GetHoneypotsConfigurations ()
164+ if err != nil {
165+ return err
166+ }
167+ if len (lastConfigurationsHash ) == 0 {
168+ lastConfigurationsHash = configurationsHash
169+ }
170+ if lastConfigurationsHash != configurationsHash {
171+ log .Debug ("Configurations changed." )
172+ exitFunction (0 )
173+ }
174+ time .Sleep (beelzebubCloud .PollingInterval )
175+ }
176+ }
177+
178+ func (beelzebubCloud * beelzebubCloud ) mapToEventDTO (event tracer.Event ) (EventDTO , error ) {
179+ eventDTO := EventDTO {
180+ DateTime : event .DateTime ,
181+ RemoteAddr : event .RemoteAddr ,
182+ Protocol : event .Protocol ,
183+ Command : event .Command ,
184+ CommandOutput : event .CommandOutput ,
185+ Status : event .Status ,
186+ Msg : event .Msg ,
187+ ID : event .ID ,
188+ Environ : event .Environ ,
189+ User : event .User ,
190+ Password : event .Password ,
191+ Client : event .Client ,
192+ Cookies : event .Cookies ,
193+ UserAgent : event .UserAgent ,
194+ HostHTTPRequest : event .HostHTTPRequest ,
195+ Body : event .Body ,
196+ HTTPMethod : event .HTTPMethod ,
197+ RequestURI : event .RequestURI ,
198+ Description : event .Description ,
199+ SourceIp : event .SourceIp ,
200+ SourcePort : event .SourcePort ,
201+ TLSServerName : event .TLSServerName ,
202+ }
203+
204+ if len (event .Headers ) > 0 {
205+ headersJSON , err := json .Marshal (event .Headers )
206+ if err != nil {
207+ return EventDTO {}, fmt .Errorf ("failed to marshal headers: %w" , err )
208+ }
209+ eventDTO .Headers = string (headersJSON )
210+ }
102211
103- return servicesConfiguration , nil
212+ return eventDTO , nil
104213}
0 commit comments