Skip to content

Commit 6cd6fa7

Browse files
authored
Merge pull request #1950 from stephenbradshaw/v1.5x/stager-rc4-support
Add RC4 support to shellcode stager - 1.5x backport
2 parents ca483cf + d05697b commit 6cd6fa7

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

client/command/commands.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ func BindCommands(con *console.SliverConsoleClient) {
484484
f.Bool("e", "lets-encrypt", false, "attempt to provision a let's encrypt certificate (HTTPS only)")
485485
f.StringL("aes-encrypt-key", "", "encrypt stage with AES encryption key")
486486
f.StringL("aes-encrypt-iv", "", "encrypt stage with AES encryption iv")
487+
f.StringL("rc4-encrypt-key", "", "encrypt stage with RC4 encryption key")
487488
f.String("C", "compress", "none", "compress the stage before encrypting (zlib, gzip, deflate9, none)")
488489
f.Bool("P", "prepend-size", false, "prepend the size of the stage to the payload (to use with MSF stagers)")
489490
},

client/command/jobs/stage.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
4444
listenerURL := ctx.Flags.String("url")
4545
aesEncryptKey := ctx.Flags.String("aes-encrypt-key")
4646
aesEncryptIv := ctx.Flags.String("aes-encrypt-iv")
47+
rc4EncryptKey := ctx.Flags.String("rc4-encrypt-key")
4748
prependSize := ctx.Flags.Bool("prepend-size")
4849
compress := strings.ToLower(ctx.Flags.String("compress"))
4950

@@ -70,6 +71,21 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
7071
return
7172
}
7273

74+
if rc4EncryptKey != "" && aesEncryptKey != "" {
75+
con.PrintErrorf("Cannot use both RC4 and AES encryption\n")
76+
return
77+
}
78+
79+
rc4Encrypt := false
80+
if rc4EncryptKey != "" {
81+
// RC4 keysize can be between 1 to 256 bytes
82+
if len(rc4EncryptKey) < 1 || len(rc4EncryptKey) > 256 {
83+
con.PrintErrorf("Incorrect length of RC4 Key\n")
84+
return
85+
}
86+
rc4Encrypt = true
87+
}
88+
7389
aesEncrypt := false
7490
if aesEncryptKey != "" {
7591
// check if aes encryption key is correct length
@@ -121,6 +137,10 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
121137
stage2 = util.PreludeEncrypt(stage2, []byte(aesEncryptKey), []byte(aesEncryptIv))
122138
}
123139

140+
if rc4Encrypt {
141+
stage2 = util.RC4EncryptUnsafe(stage2, []byte(rc4EncryptKey))
142+
}
143+
124144
switch stagingURL.Scheme {
125145
case "http":
126146
if prependSize {
@@ -203,6 +223,10 @@ func StageListenerCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
203223
con.PrintInfof("AES KEY: %v\n", aesEncryptKey)
204224
con.PrintInfof("AES IV: %v\n", aesEncryptIv)
205225
}
226+
227+
if rc4Encrypt {
228+
con.PrintInfof("RC4 KEY: %v\n", rc4EncryptKey)
229+
}
206230
}
207231

208232
func prependPayloadSize(payload []byte) []byte {

util/cryptography.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,24 @@ import (
2222
"crypto/aes"
2323
"crypto/cipher"
2424
"crypto/rand"
25+
"crypto/rc4"
2526
"errors"
2627
"io"
2728
)
2829

30+
// RC4 encryption - Cryptographically insecure!
31+
// Added for stage-listener shellcode obfuscation
32+
// Dont use for anything else!
33+
func RC4EncryptUnsafe(data []byte, key []byte) []byte {
34+
cipher, err := rc4.NewCipher(key)
35+
if err != nil {
36+
return make([]byte, 0)
37+
}
38+
cipherText := make([]byte, len(data))
39+
cipher.XORKeyStream(cipherText, data)
40+
return cipherText
41+
}
42+
2943
// PreludeEncrypt the results
3044
func PreludeEncrypt(data []byte, key []byte, iv []byte) []byte {
3145
plainText, err := pad(data, aes.BlockSize)

0 commit comments

Comments
 (0)