Skip to content

Commit b77077b

Browse files
committed
Bug fixes for file searching and task completion
1 parent 5df6d04 commit b77077b

17 files changed

+68
-20
lines changed

CHANGELOG.MD

+8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [3.3.0-rc2] - 2024-07-11
8+
9+
### Changed
10+
11+
- Updated eventing tasks to properly address when tasks fail and continue on with the eventing steps
12+
- Updated the LimitByCallback field when searching for files to also account of a fileID was used in a task in a callback
13+
- this helps with files that might be uploaded as part of workflows, but still loaded into callbacks
14+
715
## [3.3.0-rc1] - 2024-07-09
816

917
### Changed

MythicReactUI/src/components/pages/Eventing/Eventing.js

+4
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ export function Eventing({me}){
184184
const onFileChange = async (evt) => {
185185
for(let i = 0; i < evt.target.files.length; i++){
186186
let uploadStatus = await UploadEventFile(evt.target.files[i], "New Eventing Workflow");
187+
if(!uploadStatus){
188+
snackActions.error("Failed to upload file");
189+
continue
190+
}
187191
if(uploadStatus.status === "error"){
188192
snackActions.error(uploadStatus.error);
189193
}

MythicReactUI/src/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {snackActions} from './components/utilities/Snackbar';
1414
import jwt_decode from 'jwt-decode';
1515
import {meState} from './cache';
1616

17-
export const mythicUIVersion = "0.2.0";
17+
export const mythicUIVersion = "0.2.1";
1818

1919
let fetchingNewToken = false;
2020

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.3.0-rc1
1+
3.3.0-rc2

mythic-docker/src/VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.3.0-rc1
1+
3.3.0-rc2

mythic-docker/src/rabbitmq/eventingStructs.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ type EventActionDataCreateTask struct {
99
CommandName string `json:"command_name" mapstructure:"command_name"`
1010
PayloadType *string `json:"payload_type,omitempty" mapstructure:"payload_type,omitempty"`
1111
Params string `json:"params" mapstructure:"params"`
12-
ParamDictionary map[string]interface{} `json:"param_dictionary,omitempty" mapstructure:"param_dictionary"`
12+
ParamDictionary map[string]interface{} `json:"params_dictionary,omitempty" mapstructure:"params_dictionary"`
1313
ParameterGroupName *string `json:"parameter_group_name,omitempty" mapstructure:"parameter_group_name"`
1414
Token *int `json:"token,omitempty" mapstructure:"token"`
1515
ParentTaskID *int `json:"parent_task_id,omitempty" mapstructure:"parent_task_id"`

mythic-docker/src/rabbitmq/recv_mythic_rpc_file_search.go

+12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package rabbitmq
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"time"
67

78
"github.com/its-a-feature/Mythic/database"
@@ -165,7 +166,18 @@ func MythicRPCFileSearch(input MythicRPCFileSearchMessage) MythicRPCFileSearchMe
165166
} else if fileCallbackID == callbackId {
166167
finalFiles = append(finalFiles, convertFileMetaToFileData(file))
167168
}
169+
} else {
170+
// this means this file wasn't directly uploaded _just_ for this callback, but could be used in this callback anyway
171+
tasks := []databaseStructs.Task{}
172+
err := database.DB.Select(&tasks, `SELECT id FROM task WHERE
173+
callback_id=$1 AND params LIKE $2 LIMIT 1`, callbackId, fmt.Sprintf("%%%s%%", file.AgentFileID))
174+
if err != nil {
175+
logging.LogError(err, "failed to search for tasks with params that include file id")
176+
} else if len(tasks) > 0 {
177+
finalFiles = append(finalFiles, convertFileMetaToFileData(file))
178+
}
168179
}
180+
169181
} else {
170182
finalFiles = append(finalFiles, convertFileMetaToFileData(file))
171183
}

mythic-docker/src/rabbitmq/recv_pt_task_create_response.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,16 @@ func processPtTaskCreateMessages(msg amqp.Delivery) {
3737
go SendAllOperationsMessage(payloadMsg.Error, 0, "", database.MESSAGE_LEVEL_WARNING)
3838
return
3939
}
40-
err = database.DB.Get(&task, `SELECT status, operation_id FROM task WHERE id=$1`, task.ID)
40+
err = database.DB.Get(&task, `SELECT status, operation_id, eventstepinstance_id FROM task WHERE id=$1`, task.ID)
4141
if err != nil {
4242
logging.LogError(err, "Failed to find task from create_tasking")
4343
go SendAllOperationsMessage(err.Error(), 0, "", database.MESSAGE_LEVEL_WARNING)
4444
return
4545
}
46+
_, err = database.DB.Exec(`UPDATE apitokens SET deleted=true AND active=false WHERE task_id=$1`, task.ID)
47+
if err != nil {
48+
logging.LogError(err, "Failed to update the apitokens to set to deleted")
49+
}
4650
//logging.LogInfo("got response back from create message", "resp", payloadMsg, "original", string(msg.Body))
4751

4852
var updateColumns []string
@@ -145,7 +149,7 @@ func processPtTaskCreateMessages(msg amqp.Delivery) {
145149
OperatorID: task.OperatorID,
146150
EventStepInstanceID: int(task.EventStepInstanceID.Int64),
147151
TaskID: task.ID,
148-
ActionSuccess: !strings.Contains(task.Status, "error"),
152+
ActionSuccess: !strings.Contains(strings.ToLower(task.Status), "error"),
149153
}
150154
go CheckAndProcessTaskCompletionHandlers(task.ID)
151155
}
@@ -166,7 +170,7 @@ func processPtTaskCreateMessages(msg amqp.Delivery) {
166170
OperatorID: task.OperatorID,
167171
EventStepInstanceID: int(task.EventStepInstanceID.Int64),
168172
TaskID: task.ID,
169-
ActionSuccess: !strings.Contains(task.Status, "error"),
173+
ActionSuccess: false,
170174
}
171175
// we hit an error in processing, so check if others are waiting on us to finish
172176
go CheckAndProcessTaskCompletionHandlers(task.ID)

mythic-docker/src/rabbitmq/recv_pt_task_opsec_post_response.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ func processPtTaskOPSECPostMessages(msg amqp.Delivery) {
3737
go SendAllOperationsMessage(payloadMsg.Error, 0, "", database.MESSAGE_LEVEL_WARNING)
3838
return
3939
}
40+
err = database.DB.Get(&task, `SELECT status, operation_id, eventstepinstance_id FROM task WHERE id=$1`, task.ID)
41+
if err != nil {
42+
logging.LogError(err, "Failed to find task from create_tasking")
43+
go SendAllOperationsMessage(err.Error(), 0, "", database.MESSAGE_LEVEL_WARNING)
44+
return
45+
}
46+
_, err = database.DB.Exec(`UPDATE apitokens SET deleted=true AND active=false WHERE task_id=$1`, task.ID)
47+
if err != nil {
48+
logging.LogError(err, "Failed to update the apitokens to set to deleted")
49+
}
4050
if payloadMsg.Success {
4151
if !payloadMsg.OpsecPostBlocked || (payloadMsg.OpsecPostBlocked && payloadMsg.OpsecPostBypassed != nil && *payloadMsg.OpsecPostBypassed) {
4252
task.Status = PT_TASK_FUNCTION_STATUS_SUBMITTED
@@ -103,7 +113,7 @@ func processPtTaskOPSECPostMessages(msg amqp.Delivery) {
103113
OperationID: task.OperationID,
104114
EventStepInstanceID: int(task.EventStepInstanceID.Int64),
105115
TaskID: task.ID,
106-
ActionSuccess: !strings.Contains(task.Status, "error"),
116+
ActionSuccess: !strings.Contains(strings.ToLower(task.Status), "error"),
107117
}
108118
} else {
109119
checkForTaskInterception(&task)
@@ -144,7 +154,7 @@ func processPtTaskOPSECPostMessages(msg amqp.Delivery) {
144154
OperationID: task.OperationID,
145155
EventStepInstanceID: int(task.EventStepInstanceID.Int64),
146156
TaskID: task.ID,
147-
ActionSuccess: !strings.Contains(task.Status, "error"),
157+
ActionSuccess: !strings.Contains(strings.ToLower(task.Status), "error"),
148158
}
149159
}
150160
}

mythic-docker/src/rabbitmq/recv_pt_task_opsec_pre_response.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ func processPtTaskOPSECPreMessages(msg amqp.Delivery) {
3232
go SendAllOperationsMessage(payloadMsg.Error, 0, "", database.MESSAGE_LEVEL_WARNING)
3333
return
3434
}
35+
err = database.DB.Get(&task, `SELECT status, operation_id, eventstepinstance_id FROM task WHERE id=$1`, task.ID)
36+
if err != nil {
37+
logging.LogError(err, "Failed to find task from create_tasking")
38+
go SendAllOperationsMessage(err.Error(), 0, "", database.MESSAGE_LEVEL_WARNING)
39+
return
40+
}
3541
_, err = database.DB.Exec(`UPDATE apitokens SET deleted=true AND active=false WHERE task_id=$1`, task.ID)
3642
if err != nil {
3743
logging.LogError(err, "Failed to update the apitokens to set to deleted")
@@ -88,7 +94,7 @@ func processPtTaskOPSECPreMessages(msg amqp.Delivery) {
8894
OperatorID: task.OperatorID,
8995
EventStepInstanceID: int(task.EventStepInstanceID.Int64),
9096
TaskID: task.ID,
91-
ActionSuccess: !strings.Contains(task.Status, "error"),
97+
ActionSuccess: !strings.Contains(strings.ToLower(task.Status), "error"),
9298
}
9399
}
94100
}

mythic-docker/src/rabbitmq/recv_pt_task_process_response.go

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ func processPtTaskProcessResponseMessages(msg amqp.Delivery) {
2424
logging.LogError(err, "Failed to process PTTaskProcessResponseMessageResponse into struct")
2525
} else {
2626
// now process the create_tasking response body to update the task
27+
_, err = database.DB.Exec(`UPDATE apitokens SET deleted=true AND active=false WHERE task_id=$1`, payloadMsg.TaskID)
28+
if err != nil {
29+
logging.LogError(err, "Failed to update the apitokens to set to deleted")
30+
}
2731
if !payloadMsg.Success {
2832
go SendAllOperationsMessage(fmt.Sprintf("Failed to process response message for task %d:\n%s", payloadMsg.TaskID, payloadMsg.Error),
2933
0, "", database.MESSAGE_LEVEL_WARNING)

mythic-docker/src/rabbitmq/utils.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ func CheckAndProcessTaskCompletionHandlers(taskId int) {
763763
task.parent_task_id, task.operator_id,
764764
task.subtask_callback_function, task.subtask_callback_function_completed,
765765
task.group_callback_function, task.group_callback_function_completed, task.completed_callback_function,
766-
task.completed_callback_function_completed, task.subtask_group_name, task.id, task.status
766+
task.completed_callback_function_completed, task.subtask_group_name, task.id, task.status, task.eventstepinstance_id
767767
FROM task
768768
WHERE task.id=$1`, taskId)
769769
if err != nil {
@@ -775,7 +775,7 @@ func CheckAndProcessTaskCompletionHandlers(taskId int) {
775775
}
776776
if task.ParentTaskID.Valid {
777777
err = database.DB.Get(&parentTask, `SELECT
778-
task.id, task.status, task.completed,
778+
task.id, task.status, task.completed, task.eventstepinstance_id,
779779
c.script_only "command.script_only"
780780
from task
781781
LEFT OUTER JOIN command c on task.command_id = c.id
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"files": {
33
"main.css": "/new/static/css/main.7e143bf2.css",
4-
"main.js": "/new/static/js/main.180c42c2.js",
4+
"main.js": "/new/static/js/main.4fbb60c3.js",
55
"static/media/mythic-red.png": "/new/static/media/mythic-red.203468a4e5240d239aa0.png",
66
"static/media/mythic_red_small.svg": "/new/static/media/mythic_red_small.793b41cc7135cdede246661ec232976b.svg",
77
"index.html": "/new/index.html",
88
"main.7e143bf2.css.map": "/new/static/css/main.7e143bf2.css.map",
9-
"main.180c42c2.js.map": "/new/static/js/main.180c42c2.js.map"
9+
"main.4fbb60c3.js.map": "/new/static/js/main.4fbb60c3.js.map"
1010
},
1111
"entrypoints": [
1212
"static/css/main.7e143bf2.css",
13-
"static/js/main.180c42c2.js"
13+
"static/js/main.4fbb60c3.js"
1414
]
1515
}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/new/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><link rel="apple-touch-icon" href="/new/logo192.png"/><link rel="manifest" href="/new/manifest.json"/><title>Mythic</title><script defer="defer" src="/new/static/js/main.180c42c2.js"></script><link href="/new/static/css/main.7e143bf2.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
1+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/new/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><link rel="apple-touch-icon" href="/new/logo192.png"/><link rel="manifest" href="/new/manifest.json"/><title>Mythic</title><script defer="defer" src="/new/static/js/main.4fbb60c3.js"></script><link href="/new/static/css/main.7e143bf2.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

mythic-react-docker/mythic/public/static/js/main.180c42c2.js mythic-react-docker/mythic/public/static/js/main.4fbb60c3.js

+3-3
Large diffs are not rendered by default.

mythic-react-docker/mythic/public/static/js/main.180c42c2.js.map mythic-react-docker/mythic/public/static/js/main.4fbb60c3.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)