[SHEHZADE//ABDULLAH ANSARI]
Red Team Consultant @ Google | MS in Cybersecurity @ NYU
● 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)
196 lines · 5.8 KB
| 1 | package certgen |
| 2 | |
| 3 | import ( |
| 4 | "crypto" |
| 5 | "crypto/ecdsa" |
| 6 | "crypto/elliptic" |
| 7 | "crypto/rand" |
| 8 | "crypto/x509" |
| 9 | "crypto/x509/pkix" |
| 10 | "encoding/pem" |
| 11 | "errors" |
| 12 | "fmt" |
| 13 | "math/big" |
| 14 | "net" |
| 15 | "time" |
| 16 | ) |
| 17 | |
| 18 | // CertificateAuthority represents an ephemeral dynamic in-memory Root CA. |
| 19 | type CertificateAuthority struct { |
| 20 | Certificate *x509.Certificate |
| 21 | PrivateKey crypto.Signer |
| 22 | CertPEM []byte |
| 23 | KeyPEM []byte |
| 24 | } |
| 25 | |
| 26 | // NewCA generates a self-signed ephemeral root CA with ECDSA P-256. |
| 27 | func NewCA(commonName string) (*CertificateAuthority, error) { |
| 28 | if commonName == "" { |
| 29 | commonName = "Contraband Dynamic Root CA" |
| 30 | } |
| 31 | |
| 32 | privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) |
| 33 | if err != nil { |
| 34 | return nil, fmt.Errorf("failed to generate CA private key: %w", err) |
| 35 | } |
| 36 | |
| 37 | serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) |
| 38 | serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) |
| 39 | if err != nil { |
| 40 | return nil, fmt.Errorf("failed to generate CA serial number: %w", err) |
| 41 | } |
| 42 | |
| 43 | now := time.Now().UTC() |
| 44 | template := x509.Certificate{ |
| 45 | SerialNumber: serialNumber, |
| 46 | Subject: pkix.Name{ |
| 47 | CommonName: commonName, |
| 48 | Organization: []string{"Contraband Security Framework"}, |
| 49 | }, |
| 50 | NotBefore: now.Add(-1 * time.Hour), // Clock skew buffer |
| 51 | NotAfter: now.Add(365 * 24 * time.Hour), |
| 52 | KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign | x509.KeyUsageDigitalSignature, |
| 53 | BasicConstraintsValid: true, |
| 54 | IsCA: true, |
| 55 | MaxPathLen: 1, |
| 56 | } |
| 57 | |
| 58 | certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &privKey.PublicKey, privKey) |
| 59 | if err != nil { |
| 60 | return nil, fmt.Errorf("failed to create self-signed CA certificate: %w", err) |
| 61 | } |
| 62 | |
| 63 | cert, err := x509.ParseCertificate(certDER) |
| 64 | if err != nil { |
| 65 | return nil, fmt.Errorf("failed to parse generated CA cert: %w", err) |
| 66 | } |
| 67 | |
| 68 | certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}) |
| 69 | keyDER, err := x509.MarshalECPrivateKey(privKey) |
| 70 | if err != nil { |
| 71 | return nil, fmt.Errorf("failed to marshal CA private key: %w", err) |
| 72 | } |
| 73 | keyPEM := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: keyDER}) |
| 74 | |
| 75 | return &CertificateAuthority{ |
| 76 | Certificate: cert, |
| 77 | PrivateKey: privKey, |
| 78 | CertPEM: certPEM, |
| 79 | KeyPEM: keyPEM, |
| 80 | }, nil |
| 81 | } |
| 82 | |
| 83 | // LoadCA parses existing PEM-encoded certificate and private key blocks. |
| 84 | func LoadCA(certPEM, keyPEM []byte) (*CertificateAuthority, error) { |
| 85 | certBlock, _ := pem.Decode(certPEM) |
| 86 | if certBlock == nil || certBlock.Type != "CERTIFICATE" { |
| 87 | return nil, errors.New("failed to decode valid CERTIFICATE PEM block") |
| 88 | } |
| 89 | |
| 90 | cert, err := x509.ParseCertificate(certBlock.Bytes) |
| 91 | if err != nil { |
| 92 | return nil, fmt.Errorf("failed to parse certificate: %w", err) |
| 93 | } |
| 94 | |
| 95 | keyBlock, _ := pem.Decode(keyPEM) |
| 96 | if keyBlock == nil { |
| 97 | return nil, errors.New("failed to decode private key PEM block") |
| 98 | } |
| 99 | |
| 100 | var privKey crypto.Signer |
| 101 | if keyBlock.Type == "EC PRIVATE KEY" { |
| 102 | ecKey, err := x509.ParseECPrivateKey(keyBlock.Bytes) |
| 103 | if err != nil { |
| 104 | return nil, fmt.Errorf("failed to parse EC private key: %w", err) |
| 105 | } |
| 106 | privKey = ecKey |
| 107 | } else if keyBlock.Type == "PRIVATE KEY" { |
| 108 | pk, err := x509.ParsePKCS8PrivateKey(keyBlock.Bytes) |
| 109 | if err != nil { |
| 110 | return nil, fmt.Errorf("failed to parse PKCS#8 private key: %w", err) |
| 111 | } |
| 112 | signer, ok := pk.(crypto.Signer) |
| 113 | if !ok { |
| 114 | return nil, errors.New("parsed private key is not a crypto.Signer") |
| 115 | } |
| 116 | privKey = signer |
| 117 | } else { |
| 118 | return nil, fmt.Errorf("unsupported private key PEM type: %s", keyBlock.Type) |
| 119 | } |
| 120 | |
| 121 | return &CertificateAuthority{ |
| 122 | Certificate: cert, |
| 123 | PrivateKey: privKey, |
| 124 | CertPEM: certPEM, |
| 125 | KeyPEM: keyPEM, |
| 126 | }, nil |
| 127 | } |
| 128 | |
| 129 | // CertPool returns an x509 CertPool containing this CA cert for client verification. |
| 130 | func (ca *CertificateAuthority) CertPool() *x509.CertPool { |
| 131 | pool := x509.NewCertPool() |
| 132 | pool.AddCert(ca.Certificate) |
| 133 | return pool |
| 134 | } |
| 135 | |
| 136 | // SignServerCert issues and signs a leaf TLS certificate for the specified hosts. |
| 137 | func (ca *CertificateAuthority) SignServerCert(hosts []string, validFor time.Duration) ([]byte, []byte, error) { |
| 138 | if validFor <= 0 { |
| 139 | validFor = 30 * 24 * time.Hour |
| 140 | } |
| 141 | |
| 142 | privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) |
| 143 | if err != nil { |
| 144 | return nil, nil, fmt.Errorf("failed to generate server private key: %w", err) |
| 145 | } |
| 146 | |
| 147 | serialLimit := new(big.Int).Lsh(big.NewInt(1), 128) |
| 148 | serial, err := rand.Int(rand.Reader, serialLimit) |
| 149 | if err != nil { |
| 150 | return nil, nil, fmt.Errorf("failed to generate server serial: %w", err) |
| 151 | } |
| 152 | |
| 153 | now := time.Now().UTC() |
| 154 | cn := "localhost" |
| 155 | if len(hosts) > 0 && hosts[0] != "" { |
| 156 | cn = hosts[0] |
| 157 | } |
| 158 | |
| 159 | template := x509.Certificate{ |
| 160 | SerialNumber: serial, |
| 161 | Subject: pkix.Name{ |
| 162 | CommonName: cn, |
| 163 | Organization: []string{"Contraband Dynamic Server"}, |
| 164 | }, |
| 165 | NotBefore: now.Add(-1 * time.Hour), |
| 166 | NotAfter: now.Add(validFor), |
| 167 | KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, |
| 168 | ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, |
| 169 | } |
| 170 | |
| 171 | // Categorize DNS names vs IP addresses in SANs |
| 172 | for _, h := range hosts { |
| 173 | if ip := net.ParseIP(h); ip != nil { |
| 174 | template.IPAddresses = append(template.IPAddresses, ip) |
| 175 | } else { |
| 176 | template.DNSNames = append(template.DNSNames, h) |
| 177 | } |
| 178 | } |
| 179 | // Always include loopback SANs |
| 180 | template.IPAddresses = append(template.IPAddresses, net.ParseIP("127.0.0.1"), net.ParseIP("::1")) |
| 181 | template.DNSNames = append(template.DNSNames, "localhost") |
| 182 | |
| 183 | certDER, err := x509.CreateCertificate(rand.Reader, &template, ca.Certificate, &privKey.PublicKey, ca.PrivateKey) |
| 184 | if err != nil { |
| 185 | return nil, nil, fmt.Errorf("failed to sign server cert with CA: %w", err) |
| 186 | } |
| 187 | |
| 188 | certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}) |
| 189 | keyDER, err := x509.MarshalECPrivateKey(privKey) |
| 190 | if err != nil { |
| 191 | return nil, nil, fmt.Errorf("failed to marshal server private key: %w", err) |
| 192 | } |
| 193 | keyPEM := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: keyDER}) |
| 194 | |
| 195 | return certPEM, keyPEM, nil |
| 196 | } |