● Notice //GitHub (@shehzade) is temporarily suspended pending an automated false-positive review. All tools are hosted on this Code Mirror and available on request (contact); GitHub links will return once reinstated.
PUBLIC MIRRORGo v1.0

Multi-protocol network egress assessment and DLP verification framework featuring automated L4 sweeps, corporate proxy traversal, and covert protocol smuggling across 20+ channels.

$ git clone https://shehzade.io/repos/contraband.git Copy
Source ZIP (1.93 MB)
Code 174 Commits 1
contraband / pkg / client / evasion / crypto.go
← Back to directory
91 lines · 2.5 KB
Raw
1package evasion
2
3import (
4 "crypto/aes"
5 "crypto/cipher"
6 "crypto/rand"
7 "crypto/sha256"
8 "errors"
9 "fmt"
10 "io"
11
12 "golang.org/x/crypto/pbkdf2"
13)
14
15const (
16 PBKDF2Iterations = 100000
17 SaltSize = 32
18 NonceSize = 12
19 KeySize = 32 // AES-256
20)
21
22func DeriveKey(passphrase string, salt []byte) []byte {
23 return pbkdf2.Key([]byte(passphrase), salt, PBKDF2Iterations, KeySize, sha256.New)
24}
25
26func EncryptAESGCM(plaintext []byte, key []byte) ([]byte, error) {
27 if len(key) != KeySize {
28 return nil, fmt.Errorf("invalid AES-256 key size: expected %d bytes, got %d", KeySize, len(key))
29 }
30 block, err := aes.NewCipher(key)
31 if err != nil {
32 return nil, err
33 }
34 gcm, err := cipher.NewGCM(block)
35 if err != nil {
36 return nil, err
37 }
38 nonce := make([]byte, gcm.NonceSize())
39 if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
40 return nil, fmt.Errorf("failed to generate random nonce: %w", err)
41 }
42 // Seal appends ciphertext + 16-byte auth tag to nonce
43 return gcm.Seal(nonce, nonce, plaintext, nil), nil
44}
45
46func DecryptAESGCM(ciphertextWithNonce []byte, key []byte) ([]byte, error) {
47 if len(key) != KeySize {
48 return nil, fmt.Errorf("invalid AES-256 key size: expected %d bytes, got %d", KeySize, len(key))
49 }
50 block, err := aes.NewCipher(key)
51 if err != nil {
52 return nil, err
53 }
54 gcm, err := cipher.NewGCM(block)
55 if err != nil {
56 return nil, err
57 }
58 if len(ciphertextWithNonce) < gcm.NonceSize() {
59 return nil, errors.New("ciphertext too short (missing nonce)")
60 }
61 nonce := ciphertextWithNonce[:gcm.NonceSize()]
62 ciphertext := ciphertextWithNonce[gcm.NonceSize():]
63 return gcm.Open(nil, nonce, ciphertext, nil)
64}
65
66func EncryptWithPassphrase(plaintext []byte, passphrase string) ([]byte, error) {
67 salt := make([]byte, SaltSize)
68 if _, err := io.ReadFull(rand.Reader, salt); err != nil {
69 return nil, fmt.Errorf("failed to generate random salt: %w", err)
70 }
71 key := DeriveKey(passphrase, salt)
72 encrypted, err := EncryptAESGCM(plaintext, key)
73 if err != nil {
74 return nil, err
75 }
76 // Layout: [Salt (32B)][Nonce (12B)][Ciphertext + Tag]
77 out := make([]byte, SaltSize+len(encrypted))
78 copy(out[:SaltSize], salt)
79 copy(out[SaltSize:], encrypted)
80 return out, nil
81}
82
83func DecryptWithPassphrase(data []byte, passphrase string) ([]byte, error) {
84 if len(data) < SaltSize+NonceSize+16 {
85 return nil, errors.New("data too short for salt + nonce + tag")
86 }
87 salt := data[:SaltSize]
88 ciphertextWithNonce := data[SaltSize:]
89 key := DeriveKey(passphrase, salt)
90 return DecryptAESGCM(ciphertextWithNonce, key)
91}