From b8e163145046e2c3417c0bb39dc1e2e2272f1628 Mon Sep 17 00:00:00 2001 From: Edznux Date: Wed, 17 May 2023 00:44:57 +0200 Subject: [PATCH 1/4] Add mythic server binary gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e7b2ff2ab..c3278f19b 100755 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ venv.bak/ # ssl certs ssl/ # Mythic files +mythic-docker/src/Mythic mythic_access.* mythic_sync/ postgres-docker/database/ From e42020c1bea9576c8563c888e3fe2e620cfc5670 Mon Sep 17 00:00:00 2001 From: Edznux Date: Wed, 17 May 2023 00:47:32 +0200 Subject: [PATCH 2/4] Refactor util_agent_message_actions_staging_rsa.go This refactor uses common patterns in Go such as (but not limited to): return early/Guard Clause, unit tests, definition of constants variables --- .../util_agent_message_actions_staging_rsa.go | 97 ++++++++++--------- 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/mythic-docker/src/rabbitmq/util_agent_message_actions_staging_rsa.go b/mythic-docker/src/rabbitmq/util_agent_message_actions_staging_rsa.go index 7b7be53fd..7cd22b656 100644 --- a/mythic-docker/src/rabbitmq/util_agent_message_actions_staging_rsa.go +++ b/mythic-docker/src/rabbitmq/util_agent_message_actions_staging_rsa.go @@ -2,7 +2,6 @@ package rabbitmq import ( "encoding/base64" - "errors" "fmt" "strings" @@ -10,7 +9,6 @@ import ( mythicCrypto "github.com/its-a-feature/Mythic/crypto" "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/mitchellh/mapstructure" ) @@ -20,6 +18,11 @@ type agentMessageStagingRSA struct { Other map[string]interface{} `json:"-" mapstructure:",remain"` // capture any 'other' keys that were passed in so we can reply back with them } +const ( + insertQuery = `INSERT INTO staginginfo (session_id, enc_key, dec_key, crypto_type, payload_id, staging_uuid) + VALUES (:session_id, :enc_key, :dec_key, :crypto_type, :payload_id, :staging_uuid)` +) + func handleAgentMessageStagingRSA(incoming *map[string]interface{}, uUIDInfo *cachedUUIDInfo) (map[string]interface{}, error) { // got message: /* @@ -32,49 +35,51 @@ func handleAgentMessageStagingRSA(incoming *map[string]interface{}, uUIDInfo *ca agentMessage := agentMessageStagingRSA{} stagingDatabaseMessage := databaseStructs.Staginginfo{} if err := mapstructure.Decode(incoming, &agentMessage); err != nil { - logging.LogError(err, "Failed to decode agent message into struct") - return nil, errors.New(fmt.Sprintf("Failed to decode agent message into struct: %s", err.Error())) - } else if newKey, err := mythicCrypto.GenerateKeysForPayload("aes256_hmac"); err != nil { - logging.LogError(err, "Failed to generate new AES key for staging rsa") - errorString := fmt.Sprintf("Failed to generate new AES key for staging rsa: %s", err.Error()) - return nil, errors.New(errorString) - } else { - publicKeyToUse := agentMessage.PublicKey - if !strings.HasPrefix(agentMessage.PublicKey, "LS0t") { - publicKeyToUse = "-----BEGIN PUBLIC KEY-----\n" + agentMessage.PublicKey + "\n-----END PUBLIC KEY-----" - } else if decodedBytes, err := base64.StdEncoding.DecodeString(publicKeyToUse); err != nil { - logging.LogError(err, "Failed to base64 provided public key") - return nil, err - } else { - publicKeyToUse = string(decodedBytes) - } - if encryptedNewKey, err := mythicCrypto.RsaEncryptBytes(*newKey.EncKey, []byte(publicKeyToUse)); err != nil { - logging.LogError(err, "Failed to encrypt new encryption key with RSA") - return nil, errors.New(fmt.Sprintf("Failed to encrypt new encryption key with RSA: %s", err.Error())) - } else if tempUUID, err := uuid.NewRandom(); err != nil { - logging.LogError(err, "Failed to generate a new random UUID for staging") - return nil, errors.New(fmt.Sprintf("Failed to generate a new random UUID for staging: %s", err.Error())) - } else { - stagingDatabaseMessage.CryptoType = "aes256_hmac" - stagingDatabaseMessage.EncKey = newKey.EncKey - stagingDatabaseMessage.DecKey = newKey.DecKey - stagingDatabaseMessage.SessionID = agentMessage.SessionID - stagingDatabaseMessage.StagingUuID = tempUUID.String() - stagingDatabaseMessage.PayloadID = uUIDInfo.PayloadID - if _, err := database.DB.NamedExec(`INSERT INTO staginginfo - (session_id, enc_key, dec_key, crypto_type, payload_id, staging_uuid) - VALUES (:session_id, :enc_key, :dec_key, :crypto_type, :payload_id, :staging_uuid)`, stagingDatabaseMessage); err != nil { - logging.LogError(err, "Failed to save staging information into database", "staginginfo", stagingDatabaseMessage) - return nil, errors.New(fmt.Sprintf("Failed to save staging information: %s", err.Error())) - } else { - // generate the response map - response := map[string]interface{}{} - response["uuid"] = tempUUID.String() - response["session_id"] = agentMessage.SessionID - response["session_key"] = base64.StdEncoding.EncodeToString(encryptedNewKey) - reflectBackOtherKeys(&response, &agentMessage.Other) - return response, nil - } - } + return nil, fmt.Errorf("failed to decode agent message into struct: %v", err) + } + + newKey, err := mythicCrypto.GenerateKeysForPayload("aes256_hmac") + if err != nil { + return nil, fmt.Errorf("failed to generate new AES key for staging rsa: %v", err) + } + + publicKeyToUse := agentMessage.PublicKey + if !strings.HasPrefix(agentMessage.PublicKey, "LS0t") { + publicKeyToUse = fmt.Sprintf("-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----", agentMessage.PublicKey) + } + + decodedBytes, err := base64.StdEncoding.DecodeString(publicKeyToUse) + if err != nil { + return nil, fmt.Errorf("failed to base64 provided public key: %v", err) + } + + publicKeyToUse = string(decodedBytes) + encryptedNewKey, err := mythicCrypto.RsaEncryptBytes(*newKey.EncKey, []byte(publicKeyToUse)) + if err != nil { + return nil, fmt.Errorf("failed to encrypt new encryption key with RSA: %v", err) + } + + tempUUID, err := uuid.NewRandom() + if err != nil { + return nil, fmt.Errorf("failed to generate a new random UUID for staging: %v", err) } + + stagingDatabaseMessage.CryptoType = "aes256_hmac" + stagingDatabaseMessage.EncKey = newKey.EncKey + stagingDatabaseMessage.DecKey = newKey.DecKey + stagingDatabaseMessage.SessionID = agentMessage.SessionID + stagingDatabaseMessage.StagingUuID = tempUUID.String() + stagingDatabaseMessage.PayloadID = uUIDInfo.PayloadID + + if _, err := database.DB.NamedExec(insertQuery, stagingDatabaseMessage); err != nil { + return nil, fmt.Errorf("failed to save staging information into database %s: %v", "staginginfo", err) + } + // generate the response map + response := map[string]interface{}{} + response["uuid"] = tempUUID.String() + response["session_id"] = agentMessage.SessionID + response["session_key"] = base64.StdEncoding.EncodeToString(encryptedNewKey) + + reflectBackOtherKeys(&response, &agentMessage.Other) + return response, nil } From 69854ee85e89469e980031d2f8a0dc5a732b1050 Mon Sep 17 00:00:00 2001 From: Edznux Date: Wed, 17 May 2023 00:47:54 +0200 Subject: [PATCH 3/4] Refactor and add test for rsa/crypto generation --- mythic-docker/src/crypto/rsa.go | 81 +++++++++++++--------------- mythic-docker/src/crypto/rsa_test.go | 59 ++++++++++++++++++++ 2 files changed, 96 insertions(+), 44 deletions(-) create mode 100644 mythic-docker/src/crypto/rsa_test.go diff --git a/mythic-docker/src/crypto/rsa.go b/mythic-docker/src/crypto/rsa.go index 73cbd5569..7534c61f0 100644 --- a/mythic-docker/src/crypto/rsa.go +++ b/mythic-docker/src/crypto/rsa.go @@ -6,65 +6,58 @@ import ( "crypto/sha1" "crypto/x509" "encoding/pem" - "errors" "fmt" - - "github.com/its-a-feature/Mythic/logging" ) func GenerateRSAKeyPair() ([]byte, *rsa.PrivateKey, error) { - if serverPrivKey, err := rsa.GenerateKey(rand.Reader, 4096); err != nil { - logging.LogError(err, "Failed to generate a new RSA keypair") - errorString := fmt.Sprintf("Failed to generate a new RSA keypair: %s", err.Error()) - return nil, nil, errors.New(errorString) - } else { - serverPubKey := &serverPrivKey.PublicKey - pubASN1 := x509.MarshalPKCS1PublicKey(serverPubKey) - pubPem := pem.EncodeToMemory( - &pem.Block{ - Type: "RSA PUBLIC KEY", - Bytes: pubASN1, - }, - ) - return pubPem, serverPrivKey, nil + serverPrivKey, err := rsa.GenerateKey(rand.Reader, 4096) + if err != nil { + return nil, nil, fmt.Errorf("failed to generate a new RSA keypair: %v", err) } + + serverPubKey := &serverPrivKey.PublicKey + pubASN1 := x509.MarshalPKCS1PublicKey(serverPubKey) + pubPem := pem.EncodeToMemory( + &pem.Block{ + Type: "RSA PUBLIC KEY", + Bytes: pubASN1, + }, + ) + return pubPem, serverPrivKey, nil } func RsaDecryptCipherBytes(encryptedData []byte, privateKey *rsa.PrivateKey) ([]byte, error) { hash := sha1.New() - if decryptedData, err := rsa.DecryptOAEP(hash, rand.Reader, privateKey, encryptedData, nil); err != nil { - logging.LogError(err, "Failed to decrypt with RSA private key") - stringErr := errors.New(fmt.Sprintf("Failed to decrypt with RSA private key: %s", err.Error())) - return nil, stringErr - } else { - return decryptedData, nil + decryptedData, err := rsa.DecryptOAEP(hash, rand.Reader, privateKey, encryptedData, nil) + if err != nil { + return nil, fmt.Errorf("failed to decrypt with RSA private key: %v", err) } + + return decryptedData, nil } func RsaEncryptBytes(plainBytes []byte, publicKey []byte) ([]byte, error) { hash := sha1.New() //logging.LogInfo("about to parse public key in RsaEncryptBytes", "public key", publicKey) - if pkcs1RSAPublicKey, _ := pem.Decode(publicKey); pkcs1RSAPublicKey == nil { - logging.LogError(nil, "Failed to find PEM encoded public key") - return nil, errors.New("Failed to find PEM encoded public key") - } else { - var pubKey *rsa.PublicKey - var err error - if pubKey, err = x509.ParsePKCS1PublicKey(pkcs1RSAPublicKey.Bytes); err != nil { - if pubAny, err := x509.ParsePKIXPublicKey(pkcs1RSAPublicKey.Bytes); err != nil { - logging.LogError(err, "Failed to parse public key to encrypt with RSA") - errorString := fmt.Sprintf("Failed to parse public key to encrypt with RSA: %s", err.Error()) - return nil, errors.New(errorString) - } else { - pubKey = pubAny.(*rsa.PublicKey) - } - } - if encryptedData, err := rsa.EncryptOAEP(hash, rand.Reader, pubKey, plainBytes, nil); err != nil { - logging.LogError(err, "Failed to encrypt with RSA key") - errorString := fmt.Sprintf("Failed to encrypt with RSA key: %s", err.Error()) - return nil, errors.New(errorString) - } else { - return encryptedData, nil + pkcs1RSAPublicKey, _ := pem.Decode(publicKey) + if pkcs1RSAPublicKey == nil { + return nil, fmt.Errorf("failed to find PEM encoded public key") + } + + pubKey, err := x509.ParsePKCS1PublicKey(pkcs1RSAPublicKey.Bytes) + if err != nil { + // Fallback to parsing PKIX instead of PKCS1 + pubAny, err := x509.ParsePKIXPublicKey(pkcs1RSAPublicKey.Bytes) + if err != nil { + return nil, fmt.Errorf("failed to parse public key to encrypt with RSA: %v", err) } + pubKey = pubAny.(*rsa.PublicKey) + } + + encryptedData, err := rsa.EncryptOAEP(hash, rand.Reader, pubKey, plainBytes, nil) + if err != nil { + return nil, fmt.Errorf("failed to encrypt with RSA key: %v", err) } + + return encryptedData, nil } diff --git a/mythic-docker/src/crypto/rsa_test.go b/mythic-docker/src/crypto/rsa_test.go new file mode 100644 index 000000000..0a6805d05 --- /dev/null +++ b/mythic-docker/src/crypto/rsa_test.go @@ -0,0 +1,59 @@ +package mythicCrypto + +import ( + "reflect" + "testing" +) + +func TestRsaEncryptBytes(t *testing.T) { + type args struct { + plainBytes []byte + publicKey []byte + } + // TODO: + // Hardcoded key here for now, should export and read from file + pubPem := []byte{ + 45, 45, 45, 45, 45, 66, 69, 71, 73, 78, 32, 82, 83, 65, 32, 80, 85, 66, 76, 73, 67, 32, 75, 69, 89, 45, 45, 45, 45, 45, 10, 77, 73, 73, 67, 67, 103, 75, 67, 65, 103, 69, 65, 51, 115, 80, 122, 49, 76, 89, 79, 52, 72, 47, 103, 56, 56, 109, 102, 103, 43, 84, 57, 110, 99, 43, 102, 57, 85, 69, + 68, 121, 85, 99, 50, 48, 55, 121, 81, 118, 80, 72, 52, 89, 57, 88, 107, 43, 104, 80, 112, 107, 104, 69, 84, 10, 105, 47, 116, 105, 69, 108, 77, 99, 101, 108, 108, 83, 50, 109, 69, 56, 75, 74, 108, 67, 114, 106, 57, 77, 87, 100, 49, 51, 56, 122, 118, 50, 66, 100, 53, 107, 69, 72, 110, 72, + 55, 82, 80, 108, 115, 72, 53, 68, 73, 79, 107, 117, 65, 47, 57, 67, 97, 90, 112, 100, 80, 53, 49, 77, 10, 48, 73, 97, 114, 88, 53, 82, 74, 52, 50, 112, 57, 74, 84, 84, 113, 88, 78, 51, 86, 73, 79, 65, 66, 114, 82, 49, 117, 81, 87, 106, 50, 115, 72, 53, 118, 85, 73, 70, 49, 103, 98, 79, 118, + 88, 116, 55, 120, 68, 88, 106, 54, 104, 66, 72, 110, 99, 84, 75, 53, 53, 47, 121, 77, 10, 107, 52, 86, 111, 55, 97, 99, 70, 97, 47, 122, 82, 48, 116, 119, 47, 122, 76, 48, 69, 76, 88, 65, 86, 74, 69, 109, 98, 47, 73, 98, 57, 77, 97, 69, 67, 121, 67, 76, 76, 108, 69, 86, 116, 90, 69, 120, 97, + 74, 113, 88, 103, 48, 110, 100, 100, 57, 85, 85, 110, 70, 108, 119, 89, 10, 97, 79, 75, 106, 47, 109, 106, 54, 70, 88, 48, 72, 105, 117, 67, 52, 109, 67, 86, 87, 119, 121, 68, 117, 103, 121, 72, 109, 116, 112, 118, 108, 70, 99, 115, 108, 97, 106, 89, 97, 68, 67, 118, 71, 52, 85, 109, 85, 98, + 53, 47, 107, 51, 97, 116, 49, 85, 112, 68, 122, 74, 57, 113, 50, 10, 100, 118, 110, 52, 116, 116, 54, 72, 83, 85, 68, 103, 99, 55, 104, 80, 85, 98, 81, 120, 70, 88, 73, 105, 88, 97, 110, 47, 69, 47, 49, 86, 55, 65, 105, 107, 70, 78, 116, 69, 120, 56, 57, 122, 118, 102, 87, 115, 111, 115, 108, + 113, 66, 79, 67, 104, 86, 71, 80, 119, 65, 51, 121, 119, 10, 75, 113, 104, 84, 89, 67, 49, 101, 106, 85, 52, 108, 106, 73, 72, 56, 47, 100, 50, 122, 101, 81, 89, 51, 53, 51, 53, 53, 101, 119, 68, 53, 101, 65, 65, 51, 84, 104, 113, 89, 82, 108, 53, 81, 100, 104, 48, 109, 76, 74, 119, 121, 103, + 80, 48, 120, 79, 90, 117, 43, 71, 47, 83, 99, 10, 90, 89, 107, 73, 82, 87, 82, 74, 48, 67, 109, 57, 97, 77, 75, 97, 105, 108, 81, 100, 47, 82, 74, 85, 53, 84, 105, 120, 83, 47, 68, 55, 67, 119, 53, 114, 103, 73, 49, 90, 119, 114, 113, 85, 81, 47, 49, 49, 68, 112, 65, 108, 105, 99, 106, 122, + 110, 118, 90, 48, 117, 108, 97, 121, 10, 47, 106, 53, 104, 113, 81, 104, 75, 52, 101, 113, 102, 99, 67, 49, 119, 76, 56, 100, 81, 74, 97, 114, 84, 121, 90, 103, 112, 88, 110, 52, 99, 73, 98, 80, 109, 107, 77, 54, 112, 77, 85, 101, 107, 97, 81, 78, 75, 47, 56, 108, 68, 116, 55, 51, 104, 65, 69, + 115, 105, 120, 55, 69, 71, 10, 106, 47, 104, 85, 117, 54, 86, 81, 54, 77, 78, 116, 104, 67, 122, 56, 109, 117, 72, 87, 98, 56, 119, 111, 117, 102, 115, 107, 104, 82, 51, 102, 107, 116, 51, 48, 48, 89, 77, 79, 122, 43, 112, 80, 54, 119, 97, 101, 73, 122, 51, 113, 71, 114, 85, 87, 84, 120, 121, + 47, 66, 114, 109, 118, 10, 49, 53, 118, 51, 74, 122, 65, 116, 77, 86, 84, 43, 81, 118, 117, 98, 75, 115, 115, 54, 49, 100, 51, 77, 70, 121, 50, 74, 121, 108, 56, 71, 118, 99, 98, 51, 110, 103, 90, 68, 74, 57, 88, 88, 86, 49, 52, 77, 100, 112, 120, 48, 74, 116, 77, 67, 65, 119, 69, 65, 65, 81, + 61, 61, 10, 45, 45, 45, 45, 45, 69, 78, 68, 32, 82, 83, 65, 32, 80, 85, 66, 76, 73, 67, 32, 75, 69, 89, 45, 45, 45, 45, 45, 10, + } + + tests := []struct { + name string + args args + wantLen int + wantErr bool + }{ + { + name: "test RSA 4096 key success", + args: args{ + plainBytes: []byte("test"), + publicKey: pubPem, + }, + wantLen: 512, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := RsaEncryptBytes(tt.args.plainBytes, tt.args.publicKey) + if (err != nil) != tt.wantErr { + t.Errorf("RsaEncryptBytes() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(len(got), tt.wantLen) { + t.Errorf("RsaEncryptBytes() = \n%v\n, want \n%v\n", len(got), tt.wantLen) + } + }) + } +} From d35bfba84f27a8032c868496f626946750a00380 Mon Sep 17 00:00:00 2001 From: Edznux Date: Thu, 18 May 2023 15:19:14 +0200 Subject: [PATCH 4/4] Refactor crypto test to use file --- mythic-docker/src/crypto/rsa_test.go | 38 +++++++------- mythic-docker/src/crypto/testdata/invalid.pub | 1 + mythic-docker/src/crypto/testdata/test_key | 51 +++++++++++++++++++ .../src/crypto/testdata/test_key.pub | 13 +++++ 4 files changed, 84 insertions(+), 19 deletions(-) create mode 100644 mythic-docker/src/crypto/testdata/invalid.pub create mode 100644 mythic-docker/src/crypto/testdata/test_key create mode 100644 mythic-docker/src/crypto/testdata/test_key.pub diff --git a/mythic-docker/src/crypto/rsa_test.go b/mythic-docker/src/crypto/rsa_test.go index 0a6805d05..964ca9da1 100644 --- a/mythic-docker/src/crypto/rsa_test.go +++ b/mythic-docker/src/crypto/rsa_test.go @@ -1,30 +1,16 @@ package mythicCrypto import ( + "os" "reflect" "testing" ) func TestRsaEncryptBytes(t *testing.T) { + t.Parallel() type args struct { plainBytes []byte - publicKey []byte - } - // TODO: - // Hardcoded key here for now, should export and read from file - pubPem := []byte{ - 45, 45, 45, 45, 45, 66, 69, 71, 73, 78, 32, 82, 83, 65, 32, 80, 85, 66, 76, 73, 67, 32, 75, 69, 89, 45, 45, 45, 45, 45, 10, 77, 73, 73, 67, 67, 103, 75, 67, 65, 103, 69, 65, 51, 115, 80, 122, 49, 76, 89, 79, 52, 72, 47, 103, 56, 56, 109, 102, 103, 43, 84, 57, 110, 99, 43, 102, 57, 85, 69, - 68, 121, 85, 99, 50, 48, 55, 121, 81, 118, 80, 72, 52, 89, 57, 88, 107, 43, 104, 80, 112, 107, 104, 69, 84, 10, 105, 47, 116, 105, 69, 108, 77, 99, 101, 108, 108, 83, 50, 109, 69, 56, 75, 74, 108, 67, 114, 106, 57, 77, 87, 100, 49, 51, 56, 122, 118, 50, 66, 100, 53, 107, 69, 72, 110, 72, - 55, 82, 80, 108, 115, 72, 53, 68, 73, 79, 107, 117, 65, 47, 57, 67, 97, 90, 112, 100, 80, 53, 49, 77, 10, 48, 73, 97, 114, 88, 53, 82, 74, 52, 50, 112, 57, 74, 84, 84, 113, 88, 78, 51, 86, 73, 79, 65, 66, 114, 82, 49, 117, 81, 87, 106, 50, 115, 72, 53, 118, 85, 73, 70, 49, 103, 98, 79, 118, - 88, 116, 55, 120, 68, 88, 106, 54, 104, 66, 72, 110, 99, 84, 75, 53, 53, 47, 121, 77, 10, 107, 52, 86, 111, 55, 97, 99, 70, 97, 47, 122, 82, 48, 116, 119, 47, 122, 76, 48, 69, 76, 88, 65, 86, 74, 69, 109, 98, 47, 73, 98, 57, 77, 97, 69, 67, 121, 67, 76, 76, 108, 69, 86, 116, 90, 69, 120, 97, - 74, 113, 88, 103, 48, 110, 100, 100, 57, 85, 85, 110, 70, 108, 119, 89, 10, 97, 79, 75, 106, 47, 109, 106, 54, 70, 88, 48, 72, 105, 117, 67, 52, 109, 67, 86, 87, 119, 121, 68, 117, 103, 121, 72, 109, 116, 112, 118, 108, 70, 99, 115, 108, 97, 106, 89, 97, 68, 67, 118, 71, 52, 85, 109, 85, 98, - 53, 47, 107, 51, 97, 116, 49, 85, 112, 68, 122, 74, 57, 113, 50, 10, 100, 118, 110, 52, 116, 116, 54, 72, 83, 85, 68, 103, 99, 55, 104, 80, 85, 98, 81, 120, 70, 88, 73, 105, 88, 97, 110, 47, 69, 47, 49, 86, 55, 65, 105, 107, 70, 78, 116, 69, 120, 56, 57, 122, 118, 102, 87, 115, 111, 115, 108, - 113, 66, 79, 67, 104, 86, 71, 80, 119, 65, 51, 121, 119, 10, 75, 113, 104, 84, 89, 67, 49, 101, 106, 85, 52, 108, 106, 73, 72, 56, 47, 100, 50, 122, 101, 81, 89, 51, 53, 51, 53, 53, 101, 119, 68, 53, 101, 65, 65, 51, 84, 104, 113, 89, 82, 108, 53, 81, 100, 104, 48, 109, 76, 74, 119, 121, 103, - 80, 48, 120, 79, 90, 117, 43, 71, 47, 83, 99, 10, 90, 89, 107, 73, 82, 87, 82, 74, 48, 67, 109, 57, 97, 77, 75, 97, 105, 108, 81, 100, 47, 82, 74, 85, 53, 84, 105, 120, 83, 47, 68, 55, 67, 119, 53, 114, 103, 73, 49, 90, 119, 114, 113, 85, 81, 47, 49, 49, 68, 112, 65, 108, 105, 99, 106, 122, - 110, 118, 90, 48, 117, 108, 97, 121, 10, 47, 106, 53, 104, 113, 81, 104, 75, 52, 101, 113, 102, 99, 67, 49, 119, 76, 56, 100, 81, 74, 97, 114, 84, 121, 90, 103, 112, 88, 110, 52, 99, 73, 98, 80, 109, 107, 77, 54, 112, 77, 85, 101, 107, 97, 81, 78, 75, 47, 56, 108, 68, 116, 55, 51, 104, 65, 69, - 115, 105, 120, 55, 69, 71, 10, 106, 47, 104, 85, 117, 54, 86, 81, 54, 77, 78, 116, 104, 67, 122, 56, 109, 117, 72, 87, 98, 56, 119, 111, 117, 102, 115, 107, 104, 82, 51, 102, 107, 116, 51, 48, 48, 89, 77, 79, 122, 43, 112, 80, 54, 119, 97, 101, 73, 122, 51, 113, 71, 114, 85, 87, 84, 120, 121, - 47, 66, 114, 109, 118, 10, 49, 53, 118, 51, 74, 122, 65, 116, 77, 86, 84, 43, 81, 118, 117, 98, 75, 115, 115, 54, 49, 100, 51, 77, 70, 121, 50, 74, 121, 108, 56, 71, 118, 99, 98, 51, 110, 103, 90, 68, 74, 57, 88, 88, 86, 49, 52, 77, 100, 112, 120, 48, 74, 116, 77, 67, 65, 119, 69, 65, 65, 81, - 61, 61, 10, 45, 45, 45, 45, 45, 69, 78, 68, 32, 82, 83, 65, 32, 80, 85, 66, 76, 73, 67, 32, 75, 69, 89, 45, 45, 45, 45, 45, 10, + publicKey string } tests := []struct { @@ -37,16 +23,30 @@ func TestRsaEncryptBytes(t *testing.T) { name: "test RSA 4096 key success", args: args{ plainBytes: []byte("test"), - publicKey: pubPem, + publicKey: "./testdata/test_key.pub", }, wantLen: 512, wantErr: false, }, + { + name: "test key failure", + args: args{ + plainBytes: []byte("test"), + publicKey: "./testdata/invalid.pub", + }, + wantLen: 0, + wantErr: true, + }, } for _, tt := range tests { + // shadowing tt to avoid races + // see https://gist.github.com/posener/92a55c4cd441fc5e5e85f27bca008721 + tt := tt t.Run(tt.name, func(t *testing.T) { - got, err := RsaEncryptBytes(tt.args.plainBytes, tt.args.publicKey) + t.Parallel() + pubPem, _ := os.ReadFile(tt.args.publicKey) + got, err := RsaEncryptBytes(tt.args.plainBytes, pubPem) if (err != nil) != tt.wantErr { t.Errorf("RsaEncryptBytes() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/mythic-docker/src/crypto/testdata/invalid.pub b/mythic-docker/src/crypto/testdata/invalid.pub new file mode 100644 index 000000000..e291e0e12 --- /dev/null +++ b/mythic-docker/src/crypto/testdata/invalid.pub @@ -0,0 +1 @@ +invalid key \ No newline at end of file diff --git a/mythic-docker/src/crypto/testdata/test_key b/mythic-docker/src/crypto/testdata/test_key new file mode 100644 index 000000000..655d1a0ff --- /dev/null +++ b/mythic-docker/src/crypto/testdata/test_key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/mythic-docker/src/crypto/testdata/test_key.pub b/mythic-docker/src/crypto/testdata/test_key.pub new file mode 100644 index 000000000..44c62f671 --- /dev/null +++ b/mythic-docker/src/crypto/testdata/test_key.pub @@ -0,0 +1,13 @@ +-----BEGIN RSA PUBLIC KEY----- +MIICCgKCAgEA0c4/6tzhoWq1SvmTD2+IpZw80H8ofOGHYEa+SZtzeLAJQWSP+DwO +nPNt3M0/g8FOQv7cD0htWejeW+T2DH3GkPwFy9d80npF2mPDvPzI2ydb3vbghqJ8 +P1u6Wb4J1RJLgwGDiCVEeTTf12/gNhyo7rr7lr7Pv7nfAv9Jua+HzPQEw/ZW0NNe +FLUaA55/Thf1JcT8+GGlhlZaYUKf7wBN/kuLKgLtW2CMhFb6NqpZRkdk81wldJMb +/PdcZ+ktIlGX2ioFgEBS7Jy+7YJaCPYlb+CtqWACtj9aSSkEFb7V7U7Qdlel1LJV ++eAVTSH+lyNBJ+uO5FXvs/7FEJTZiAp5tW0x+PAI9kZiD9Aic9kKCxjForo8ts4u +hWRuX84RCAoWHeLsdmjGadGhqYnbfNmBw24B9J3vb2/xbSmSS6NmqF/TTZ8DXyVU +ftU/YByyu0Szq7wUTON0zsB8nIE6VN+OBwY5p0FC3hDjYxKUROTnL6ENcG1YKbIa +6pPeExV19DoDEa6EQZ2XXWOAvNlhwmymXXicdG0QkELFx6oM8cwguu755ubBalNM +RA5fIxFlnmzGnF/+P6Af1cvpio9Nx2VVq3rS0/ld4xC/GBX+YD6HaZHRwRLBkpoK +Qx19419Ee8pgd/Fq93jt5iLwH+0wyP4KukyDb/+KmKfeEETJngVH0ZkCAwEAAQ== +-----END RSA PUBLIC KEY-----