Skip to content

Commit

Permalink
updating file hosting processes
Browse files Browse the repository at this point in the history
  • Loading branch information
its-a-feature committed Nov 18, 2024
1 parent 8a96739 commit 2752e5f
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 25 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [3.3.1-rc25] - 2024-11-18

### Changed

- Updated how file hosting works for C2 profiles
- When syncing to Mythic, C2 profiles get updated file hosting based on existing FileHosted tags in Mythic
- When stopping file hosting, Mythic ensures that the C2 profile successfully processed the request before updating the corresponding Tag

## [3.3.1-rc24] - 2024-11-18

### Changed
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.1-rc24
3.3.1-rc25
2 changes: 1 addition & 1 deletion mythic-docker/src/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.1-rc24
3.3.1-rc25
2 changes: 1 addition & 1 deletion mythic-docker/src/rabbitmq/check_container_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ type rabbitmqAPIQuery struct {

func createGraphQLSpectatorAPITokenAndSendOnStartMessage(containerName string) {
operations := []databaseStructs.Operation{}
err := database.DB.Select(&operations, `SELECT id FROM operation WHERE deleted=false and completed=true`)
err := database.DB.Select(&operations, `SELECT id FROM operation WHERE deleted=false and complete=false`)
if err != nil {
logging.LogError(err, "Failed to fetch operations")
return
Expand Down
47 changes: 47 additions & 0 deletions mythic-docker/src/rabbitmq/recv_c2_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/its-a-feature/Mythic/logging"
"github.com/its-a-feature/Mythic/utils"
amqp "github.com/rabbitmq/amqp091-go"
"strings"
)

// C2_SYNC STRUCTS
Expand Down Expand Up @@ -311,4 +312,50 @@ func autoStartC2Profile(c2Profile databaseStructs.C2profile) {
}
}
}
autoReHostFiles(c2Profile)
}

func autoReHostFiles(c2Profile databaseStructs.C2profile) {
fileHostedTagType := databaseStructs.TagType{
Name: "FileHosted",
}
err := database.DB.Get(&fileHostedTagType, `SELECT id FROM tagtype WHERE name=$1`, fileHostedTagType.Name)
if err != nil {
logging.LogError(err, "failed to get existing tag types")
return
}
currentTags := []databaseStructs.Tag{}
err = database.DB.Select(&currentTags, `SELECT * FROM tag WHERE tagtype_id=$1`, fileHostedTagType.ID)
if err != nil {
logging.LogError(err, "failed to get existing tags for FileHosted tagtype")
return
}
for _, tag := range currentTags {
dataStruct := tag.Data.StructValue()
for key, _ := range dataStruct {
if strings.HasPrefix(key, fmt.Sprintf("%s; ", c2Profile.Name)) {
newTagMap := dataStruct[key].(map[string]interface{})
c2HostFileResponse, err := RabbitMQConnection.SendC2RPCHostFile(C2HostFileMessage{
Name: newTagMap["c2_profile"].(string),
FileUUID: newTagMap["agent_file_id"].(string),
HostURL: newTagMap["host_url"].(string),
Remove: false,
})
if err != nil {
logging.LogError(err, "failed to send host file message to c2 profile")
go SendAllOperationsMessage(fmt.Sprintf(
"%s failed to start hosting file:\n%s", newTagMap["c2_profile"].(string),
err.Error()), tag.Operation, "", database.MESSAGE_LEVEL_WARNING)
continue
}
if !c2HostFileResponse.Success {
logging.LogError(err, "c2 profile failed to start hosting file")
go SendAllOperationsMessage(fmt.Sprintf(
"%s failed to start hosting file:\n%s", newTagMap["c2_profile"].(string),
c2HostFileResponse.Error), tag.Operation, "", database.MESSAGE_LEVEL_WARNING)
continue
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/its-a-feature/Mythic/database"
databaseStructs "github.com/its-a-feature/Mythic/database/structs"
"github.com/its-a-feature/Mythic/logging"
"github.com/its-a-feature/Mythic/rabbitmq"
)

type C2HostFileMessageInput struct {
Expand Down Expand Up @@ -84,27 +83,6 @@ func C2HostFileMessageWebhook(c *gin.Context) {
})
return
}
c2HostFileResponse, err := rabbitmq.RabbitMQConnection.SendC2RPCHostFile(rabbitmq.C2HostFileMessage{
Name: c2Profile.Name,
FileUUID: input.Input.FileUUID,
HostURL: input.Input.HostURL,
Remove: input.Input.Remove,
})
if err != nil {
logging.LogError(err, "Failed to send RPC call to c2 profile in C2ProfileHostFileWebhook", "c2_profile", c2Profile.Name)
c.JSON(http.StatusOK, C2HostFileMessageResponse{
Status: "error",
Error: "Failed to send RPC message to c2 profile",
})
return
}
if !c2HostFileResponse.Success {
c.JSON(http.StatusOK, C2HostFileMessageResponse{
Status: "error",
Error: c2HostFileResponse.Error,
})
return
}
go tagFileAs(hostFile.ID, operatorOperation.CurrentOperator.Username, hostFile.OperationID, tagTypeHostedByC2, map[string]interface{}{
c2Profile.Name + "; " + input.Input.HostURL: map[string]interface{}{
"c2_profile": c2Profile.Name,
Expand Down
41 changes: 41 additions & 0 deletions mythic-docker/src/webserver/controllers/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,53 @@ Target Host: %s`,
newTagMap["c2_profile"].(string) == oldTagMap["c2_profile"].(string) &&
(newTagMap["host_url"].(string) == "" ||
newTagMap["host_url"].(string) == oldTagMap["host_url"].(string)) {
c2HostFileResponse, err := rabbitmq.RabbitMQConnection.SendC2RPCHostFile(rabbitmq.C2HostFileMessage{
Name: newTagMap["c2_profile"].(string),
FileUUID: newTagMap["agent_file_id"].(string),
HostURL: newTagMap["host_url"].(string),
Remove: remove,
})
if err != nil {
logging.LogError(err, "failed to send message to container to stop hosting it")
go rabbitmq.SendAllOperationsMessage(fmt.Sprintf(
"%s failed to stop hosting file:\n%s", newTagMap["c2_profile"].(string),
err.Error()), operationID, "", database.MESSAGE_LEVEL_WARNING)
continue
}
if !c2HostFileResponse.Success {
logging.LogError(err, "c2 profile failed to stop hosting file")
go rabbitmq.SendAllOperationsMessage(fmt.Sprintf(
"%s failed to stop hosting file:\n%s", newTagMap["c2_profile"].(string),
c2HostFileResponse.Error), operationID, "", database.MESSAGE_LEVEL_WARNING)
continue
}
delete(updateTagData, key)
}
}
}
} else {
for key, val := range tagData {
newTagMap := val.(map[string]interface{})
c2HostFileResponse, err := rabbitmq.RabbitMQConnection.SendC2RPCHostFile(rabbitmq.C2HostFileMessage{
Name: newTagMap["c2_profile"].(string),
FileUUID: newTagMap["agent_file_id"].(string),
HostURL: newTagMap["host_url"].(string),
Remove: remove,
})
if err != nil {
logging.LogError(err, "failed to send host file message to c2 profile")
go rabbitmq.SendAllOperationsMessage(fmt.Sprintf(
"%s failed to start hosting file:\n%s", newTagMap["c2_profile"].(string),
err.Error()), operationID, "", database.MESSAGE_LEVEL_WARNING)
continue
}
if !c2HostFileResponse.Success {
logging.LogError(err, "c2 profile failed to start hosting file")
go rabbitmq.SendAllOperationsMessage(fmt.Sprintf(
"%s failed to start hosting file:\n%s", newTagMap["c2_profile"].(string),
c2HostFileResponse.Error), operationID, "", database.MESSAGE_LEVEL_WARNING)
continue
}
updateTagData[key] = val
}
}
Expand Down

0 comments on commit 2752e5f

Please sign in to comment.