πŸ”’ TLS/SSL β€” Deep Dive: Handshake, Cipher Suites, Certificate Chain, Attacks & Detection

Nota ini adalah panduan komprehensif Transport Layer Security β€” dari sejarah SSL sampai TLS 1.3. Mencakup handshake step-by-step (TLS 1.2 vs 1.3), cipher suite anatomy, Certificate Authority hierarchy & chain validation, key exchange (RSA vs DH vs ECDHE), forward secrecy, session resumption, TLS fingerprinting (JA3/JA3S), TLS in HTTP/2 and HTTP/3, downgrade attacks (BEAST, CRIME, POODLE, ROBOT), dan practical detection of malicious TLS (C2 beaconing, encrypted traffic analysis). TLS adalah perimeter baru setelah network perimeter hilang.

Posisi di Vault

Nota ini terkait dengan http-protocol-deepdive (HTTPS = HTTP + TLS), cryptography-biometrics (crypto primitives yang dipake TLS), networking-fundamentals-tcpip-bgp (TCP handshake yang terjadi sebelum TLS), waf-reverse-proxy-deepdive (TLS termination di reverse proxy), container-kubernetes-security-deepdive (mTLS di service mesh), cloudflare-ruleset-engine-phases (TLS inspection), cobalt-strike dan sliver (C2 HTTPS profiles, JA3 evasion), dan comprehensive-threat-directory (TLS attack taxonomy).


Daftar Isi


Foundation

Timeline SSL β†’ TLS

VersiTahunStatusMasalah
SSL 1.01994 (Netscape)πŸ”΄ Tidak pernah rilisBugs parah
SSL 2.01995πŸ”΄ Deprecated (RFC 6176)Multiple security flaws: same key for auth+encryption, MD5, weak MAC
SSL 3.01996πŸ”΄ Deprecated (RFC 7568)POODLE attack (CVE-2014-3566)
TLS 1.01999 (RFC 2246)πŸ”΄ DeprecatedBEAST (CVE-2011-3389), Lucky13
TLS 1.12006 (RFC 4346)πŸ”΄ DeprecatedCBC timing attacks
TLS 1.22008 (RFC 5246)🟑 Masih dipakeMasih aman dengan konfigurasi benar (AES-GCM, ECDHE)
TLS 1.32018 (RFC 8446)🟒 RecommendedForward secrecy wajib, 1-RTT handshake, hapus cipher lemah

Kenapa TLS Bukan SSL?

SSL adalah nama lama (Netscape). Setelah diadopsi IETF, namanya diubah jadi TLS (Transport Layer Security). Tapi masyarakat umum masih nyebut β€œSSL” β€” makanya sertifikat disebut β€œSSL certificate” padahal sebenarnya TLS.

What TLS Does (dan Tidak)

LapisanDilindungi TLS?Catatan
URI/Path❌ TidakHanya hostname yang di-enkripsi (SNI sebelumnya bocor, sekarang ECH/ESNI)
Query Parametersβœ… YaSemua data HTTP body dan query di-enkripsi setelah TLS handshake
Headersβœ… YaSetelah TLS handshake selesai, HTTP headers ter-enkripsi
Server Certificate🟑 SebagianSertifikat server ter-enkripsi di TLS 1.3, bocor di TLS 1.2
Server IP❌ TidakIP tujuan selalu kelihatan (harus pakai VPN/Tor)
SNI (Server Name Indication)🟑 SebagianECH (Encrypted Client Hello) baru mulai diadopsi β€” sebelum itu SNI plaintext
Traffic Length❌ TidakUkuran packet bocor β€” bisa dipakai traffic analysis (site fingerprinting)
DNS Query❌ TidakDNS biasanya plaintext (kecuali DNS over HTTPS/TLS)

X.509 Certificate Chain

Hierarki Kepercayaan

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      Root CA (Self-Signed)   β”‚ ← Root store: ~150 CA di browser/OS
β”‚   "ISRG Root X1"             β”‚   Private key: offline, penyimpanan super aman
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚ Signed by Root CA
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Intermediate CA            β”‚ ← Bisa beberapa level
β”‚   "R3" (Let's Encrypt)       β”‚   Private key: online, rotasi teratur
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚ Signed by Intermediate CA
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Leaf / End-Entity Cert     β”‚ ← Yang dipasang di server
β”‚   "*.example.com"            β”‚   Private key: di server web
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Kenapa pake intermediate, bukan langsung dari Root?

  • Root CA private key disimpan offline (air-gapped) β€” jarang dipake
  • Intermediate bisa di-revoke tanpa revoke Root
  • Kalo intermediate compromised, Root masih aman β€” bisa revoke intermediate dan terbitkan baru

Certificate Fields

FieldContohFungsi
SubjectCN=*.example.com, O=Example Corp, C=USIdentitas pemilik sertifikat
Subject Alternative Names (SAN)DNS:example.com, DNS:*.example.comDomain yang dilindungi β€” modern browser cuma lihat SAN, gak lihat CN
IssuerCN=R3, O=Let's EncryptCA yang nerbitin
ValidityNot Before: Jul 15 2026, Not After: Oct 15 2026Masa berlaku β€” 90 hari untuk Let’s Encrypt (Auto Renew)
Public KeyRSA 2048-bit atau ECDSA P-256Kunci publik milik server
Signature Algorithmsha256WithRSAEncryptionAlgoritma yang dipake CA untuk sign cert
Key UsageDigital Signature, Key EnciphermentCara kunci boleh dipake
Extended Key UsageTLS Web Server AuthenticationKonteks penggunaan
CRL Distribution Pointshttp://crl.example.com/root.crlLokasi daftar sertifikat yang di-revoke
OCSP Responderhttp://ocsp.example.comEndpoint pengecekan status real-time
Fingerprint (SHA-256)a1:b2:c3:...Hash sertifikat β€” identifier unik

Chain Validation

Browser saat connect ke https://example.com:

1. Server kirim: Leaf Cert + Intermediate Cert(s) (tapi gak kirim Root)
2. Browser:
   a. Verifikasi signature Leaf ← Intermediate
   b. Verifikasi signature Intermediate ← Root (Root ada di trust store browser)
   c. Cek validity period (belum expired)
   d. Cek hostname (SAN cocok dengan domain yang dikunjungi)
   e. Cek revocation status (CRL atau OCSP)
   f. Cek Key Usage / Extended Key Usage
3. Kalau semua lolos β†’ πŸ”’ padlock hijau

Certificate Validation Failures

ErrorArtiPenyebab Umum
Self-signed certCertificate Authority gak dikenalDev server, internal tools
Hostname mismatchSAN gak cocok dengan domain di URLWildcard gak cover subdomain, cert buat server beda
Expired certMelewati Not AfterGak renew tepat waktu
Revoked certCA udah revokePrivate key compromised, domain ganti
Incomplete chainIntermediate gak dikirim serverServer config salah
Unknown issuerRoot gak ada di trust storeRoot CA baru, atau fake cert

Let’s Encrypt & ACME Protocol

Apa: CA gratis yang otomatis nerbitin sertifikat via ACME protocol. 90 hari validity β€” auto-renewal.

1. Install certbot / acme.sh
2. Domain validation: HTTP-01 (file di /.well-known/acme-challenge/) atau DNS-01 (TXT record)
3. ACME server terbitkan cert + private key
4. Auto-renew: cron/systemd timer check tiap 60 hari

Kenapa 90 hari? Biar dampak kompromi terbatas. Kalo compromised, maksimal 90 hari dipake β€” bukan 2 tahun.


Cipher Suite Anatomy

Cipher suite adalah kombinasi algoritma yang disepakati client & server untuk satu koneksi TLS.

Format TLS 1.2

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
β””β”€β”€β”˜ β””β”€β”€β”˜ β””β”€β”€β”˜ β””β”€β”€β”€β”˜ β””β”€β”˜ β””β”€β”€β”€β”€β”˜
 1    2     3      4     5     6
KomponenContohFungsiOpsi Umum
1. ProtokolTLSProtocolTLS
2. Key ExchangeECDHEPertukaran kunci β€” cara client & server sepakat session keyRSA, DH, DHE, ECDHE, PSK
3. AuthenticationRSAAutentikasi server β€” verifikasi identitas via certRSA, ECDSA, DSS
4. EncryptionAES_128_GCMEnkripsi data setelah handshakeAES-GCM, AES-CBC, ChaCha20
5. MAC/HashSHA256Integrity check β€” verifikasi data gak diubahSHA, SHA256, SHA384, Poly1305
6. Key Exchange (opsional)β€”Beberapa format include _ untuk variasiβ€”

TLS 1.3 β€” Simplified

TLS 1.3 hapus banyak opsi:

TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256

Hanya 5 cipher suite yang diizinkan β€” semuanya pake AEAD + HKDF. Gak ada RSA key exchange (gak ada forward secrecy tanpa), gak ada CBC mode, gak ada RC4.

Forward Secrecy

Konsep: Kalo private key server bocor, session key koneksi masa lalu tetap aman.

Cara kerja: Session key diturunkan dari ephemeral key exchange (DHE atau ECDHE), bukan dari RSA private key. RSA key exchange: session key di-enkripsi dengan private key β†’ kalo private key bocor, semua session masa lalu bisa di-dekripsi. ECDHE: tiap session pake temporary key baru, dihapus setelah session selesai.

Status: TLS 1.3 mewajibkan forward secrecy. TLS 1.2 dengan cipher ECDHE juga aman. Cipher RSA key exchange harus di-disable.

AEAD β€” Authenticated Encryption with Associated Data

Kombinasi enkripsi + integrity check dalam satu operasi. Cegah padding oracle attack (CBC mode rentan). Contoh: AES-GCM, ChaCha20-Poly1305.


TLS Handshake β€” Step by Step

TLS 1.2 Full Handshake (2 RTT)

Client (browser)                               Server (nginx)
      β”‚                                              β”‚
      │────── 1. ClientHello ───────────────────────→│
      β”‚    TLS version, cipher suites,               β”‚
      β”‚    random bytes, session ID                  β”‚
      β”‚                                              β”‚
      │←──── 2. ServerHello ─────────────────────────│
      β”‚    Chosen version, cipher suite,             β”‚
      β”‚    random bytes, session ID                  β”‚
      β”‚                                              β”‚
      │←──── 3. Certificate ─────────────────────────│
      β”‚    Server cert chain                         β”‚
      β”‚                                              β”‚
      │←──── 4. ServerKeyExchange ───────────────────│
      β”‚    ECDHE params (pubkey, signature)          β”‚
      β”‚                                              β”‚
      │←──── 5. ServerHelloDone ─────────────────────│
      β”‚    "Udah, giliran lo"                        β”‚
      β”‚                                              β”‚
      │────── 6. ClientKeyExchange ─────────────────→│
      β”‚    ECDHE client pubkey                       β”‚
      β”‚    β†’ Kedua pihak compute shared secret       β”‚
      β”‚    β†’ Turunkan session key                    β”‚
      β”‚                                              β”‚
      │────── 7. ChangeCipherSpec ──────────────────→│
      β”‚    "Mulai enkripsi"                          β”‚
      β”‚                                              β”‚
      │────── 8. Finished (encrypted) ──────────────→│
      β”‚    MAC of all handshake messages             β”‚
      β”‚                                              β”‚
      │←──── 9. ChangeCipherSpec ────────────────────│
      │←──── 10. Finished (encrypted) ───────────────│
      β”‚    Server verify handshake integrity         β”‚
      β”‚                                              β”‚
      │←══════════════ Data (encrypted) ═════════════→│

Total: 2 RTT setelah TCP handshake (yang 1 RTT). Jadi HTTPS = TCP (1 RTT) + TLS 1.2 (2 RTT) = 3 RTT sebelum byte data pertama.

Detail Message

ClientHello:

Version: TLS 1.2 (0x0303)
Random: 32-byte random (client_random)
Session ID: (untuk resumption)
Cipher Suites: [TLS_AES_128_GCM_SHA256, TLS_CHACHA20_POLY1305, ...]
Compression: [null] # null-satu-satunya yang aman
Extensions:
  - SNI: "example.com"
  - ALPN: ["h2", "http/1.1"]
  - Supported Groups: [x25519, secp256r1, secp384r1] # ECDHE curves
  - Signature Algorithms: [rsa_pss_rsae_sha256, ecdsa_secp256r1_sha256]
  - Key Share (TLS 1.3): ...

ServerHello:

Version: TLS 1.2
Random: 32-byte (server_random)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Extensions:
  - ALPN: "h2"

Key Generation

Pre-Master Secret = ECDHE(client_private, server_public)  # shared secret
                           ↓
Master Secret = PRF(Pre-Master Secret + client_random + server_random)
                           ↓
Session Key = PRF(Master Secret + "key expansion" + ...)
    β”œβ”€β”€ Client Write Key (encrypt data from client β†’ server)
    β”œβ”€β”€ Server Write Key (encrypt data from server β†’ client)
    β”œβ”€β”€ Client Write IV
    └── Server Write IV

Kenapa random client & server ikut? Biar kalo dua koneksi beda pake pre-master secret yang sama (sangat kecil kemungkinannya) tetap menghasilkan session key yang beda.


TLS 1.3 β€” Simplified

TLS 1.3 Handshake (1 RTT)

Client                                          Server
  β”‚                                                  β”‚
  │────── ClientHello ──────────────────────────────→│
  β”‚    Key Share (ECDHE pubkey langsung!)             β”‚
  β”‚    Supported versions: [1.3, 1.2]                β”‚
  β”‚    Cipher suites: [TLS_AES_128_GCM_SHA256, ...]  β”‚
  β”‚                                                  β”‚
  │←──── ServerHello ────────────────────────────────│
  β”‚    Key Share (ECDHE pubkey)                      β”‚
  β”‚    β†’ Kedua pihak compute shared secret           β”‚
  β”‚    β†’ Turunkan handshake traffic key              β”‚
  β”‚                                                  β”‚
  │←──── EncryptedExtensions ────────────────────────│
  │←──── Certificate (encrypted!) ───────────────────│
  │←──── CertificateVerify (encrypted!) ─────────────│
  │←──── Finished (encrypted!) ──────────────────────│
  β”‚                                                  β”‚
  │────── Finished (encrypted!) ────────────────────→│
  β”‚                                                  β”‚
  │←══════════════════ Data ═════════════════════════→│

Perbedaan utama TLS 1.2 vs 1.3:

AspekTLS 1.2TLS 1.3
Handshake RTT2 RTT (full)1 RTT (full), 0-RTT (resumption)
Certificate deliveryPlaintext (bocor)Encrypted
Forward secrecyOpsionalβœ… Wajib
Cipher suites37+ kombinasi5 AEAD-only
Key exchangeRSA, DH, DHE, ECDHEECDHE, (EC)DHE only
Algorithm negotiationClientHello β†’ ServerHello (sequential)ClientHello β†’ ServerHello + KeyShare (parallel)
Session resumptionSession ID, Session TicketPSK (Pre-Shared Key)
CompressionAda (risk)❌ Dihapus
RenegotiationAda (risk)❌ Dihapus
ChangeCipherSpecExplicit messageImplicit (hapus dari spec)

0-RTT (Early Data)

Dengan TLS 1.3 + PSK (resumption), client bisa langsung kirim data di ClientHello sebelum handshake selesai:

Client (pernah connect sebelumnya)            Server
      β”‚                                              β”‚
      │────── ClientHello + PSK + Early Data ───────→│
      β”‚    Data HTTP request LANGSUNG!                 β”‚
      β”‚                                              β”‚
      │←──── ServerHello + Finished ─────────────────│
      │←──── Response (encrypted) ───────────────────│

⚠️ Risiko 0-RTT:

  • Replay attack β€” attacker bisa intercept dan kirim ulang early data yang sama. Server harus implement replay protection (key idempotent request seperti GET, atau nonce).
  • Forward secrecy β€” data 0-RTT dienkripsi dengan PSK, bukan ephemeral key. Kalo PSK bocor, data 0-RTT bisa di-dekripsi.

Session Resumption

Biar gak perlu full handshake setiap kali:

Session ID (TLS 1.2, stateful)

1. Handshake pertama: Server simpan session di memory, kirim Session ID
2. Handshake kedua: Client kirim Session ID β†’ server cek memory β†’ kalo cocok, pake session key lama
3. Server harus simpan session β†’ masalah di load balancer (harus session store shared)

Session Ticket (TLS 1.2, stateless)

1. Server kirim Session Ticket (encrypted blob β€” session key di-enkripsi server key)
2. Client simpan ticket
3. Handshake berikutnya: client kirim ticket β†’ server decrypt β†’ dapet session key
4. Lebih scalable (gak perlu shared store)

PSK (TLS 1.3)

Evolusi dari session ticket. Client kirim PSK identity, server match, langsung 1-RTT atau 0-RTT.


TLS in HTTP/2 & HTTP/3

HTTP/2 + TLS

HTTP/2 tidak mewajibkan TLS secara spesifik (spec bilang β€œencryption optional”), tapi semua browser cuma implement HTTP/2 over TLS β€” jadi praktisnya HTTP/2 = HTTPS.

ALPN (Application-Layer Protocol Negotiation):

ClientHello: ALPN = ["h2", "http/1.1"]
ServerHello: ALPN = "h2"  β†’ client & server pake HTTP/2

HTTP/3 + QUIC

HTTP/3 = HTTP over QUIC. QUIC menggabungkan TLS 1.3 built-in β€” bukan layer terpisah:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      HTTP/3          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     QUIC Transport   β”‚
β”‚  β”œβ”€β”€ TLS 1.3 ─────────  ← Built-in, bukan layer terpisah
β”‚  └── UDP ─────────────
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚         UDP          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

TLS Fingerprinting β€” JA3 JA3S

Konsep

Setiap client TLS (browser, curl, Go net/http, Python requests, Cobalt Strike beacon) mengirim ClientHello dengan kombinasi unik dari:

  • TLS version yang didukung
  • Cipher suites (urutan)
  • Extensions (tipe + urutan)
  • Supported curves
  • Elliptic curve formats
  • Signature algorithms

Kombinasi ini β†’ hash β†’ JA3 fingerprint.

Cara Kerja

ClientHello dari Chrome 130:
  Version: 0x0303 (TLS 1.2)
  Cipher Suites: [0x1301, 0x1302, 0x1303, 0xc02b, 0xc02f, ...]  # 17 suites
  Extensions: [0x0000, 0x001b, 0x002d, 0x0033, 0x4469, ...]  # 10 extensions
  Supported Groups: [0x001d, 0x0017, 0x0018]
  β†’ JA3 = "771,4865-4866-4867-49195-49199-...-52392,0-11-...-65281,29-23-24,0"
  β†’ MD5 = efebb8252f524b7c4a2d6e7c1a4e8f2a

Penggunaan Security

Use CaseCara
C2 detectionCobalt Strike HTTPS beacon punya JA3 signature yang dikenal (51c64c77f60c4b6b…). Block JA3 = block C2
Malware detectionMalware pake library TLS sendiri β†’ JA3 unik yang gak cocok browser normal
Impersonation detectionAttacker pake curl dengan user-agent β€œChrome” tapi JA3 curl beda sama JA3 Chrome asli
Bot detectionBot/scraper punya JA3 beda dari browser real

Keterbatasan:

  • JA3 bisa diubah dengan memodifikasi TLS library (Cobalt Strike sudah support JA3 randomization sejak v4.7)
  • JA3 yang sama dari dua tools berbeda bisa terjadi collision
  • Private library bisa generate JA3 baru yang belum dikenal

Implementation

# Capture JA3 dari pcap
# Di Suricata:
ja3-fingerprints: yes
# Di zeek:
@load protocols/ssl/ja3
 
# Custom detection command:
tshark -r capture.pcap -Y "tls.handshake.type == 1" -T fields \
  -e tls.handshake.ja3 -e tls.handshake.ja3s

TLS Attack Surface

Downgrade Attacks

AttackTargetCara KerjaTLS 1.3 Mitigasi?
POODLE (SSL 3.0)CBC modeExploit padding oracle di SSL 3.0βœ… (SSL 3.0 dihapus)
BEAST (TLS 1.0)CBC modePredict IV via block chainingβœ… (AEAD-only)
CRIMECompressionInject known plaintext β†’ ukur perubahan ukuran kompresiβœ… (kompresi dihapus)
Lucky13CBC modeTiming oracle dari CBC paddingβœ… (AEAD-only)
LogjamDHE exportForce DHE ke export-grade (512-bit)βœ… (export cipher dihapus)
FREAKRSA exportForce RSA ke export-grade (512-bit)βœ… (export cipher dihapus)
ROBOTRSA key exchangeReturn of Bleichenbacher oracle (CVE-2017-17305)βœ… (RSA key exchange dihapus)
Downgrade to TLS 1.2Protocol versionForced downgrade via network MITM🟑 Sebagian (downgrade protection SCSV)

Mitigasi utama: Nonaktifkan semua protokol sebelum TLS 1.2, pake cipher AEAD-only, disable compression, disable renegotiation (client-side renego).

Certificate Attacks

AttackCaraMitigasi
MITM dengan fake CAInstall fake Root CA di device korbanCertificate Pinning, CRL, OCSP
Certificate SpoofingCompromise CA β†’ terbitkan cert palsuCertificate Transparency (CT logs) β€” deteksi cert aneh
OCSP BypassBlock OCSP responder β†’ browser gak bisa cek statusOCSP Stapling (server yang ngasih timestamped OCSP response)
Revoked cert masih dipakeBrowser offline β†’ gak bisa OCSPCRLSet (Chrome), OneCRL (Firefox) β€” distributed CRL

TLS Renegotiation Attack

Attacker inject plaintext di tengah session TLS β€” server kira itu bagian dari autentikasi client. Ditemukan 2009. TLS 1.3 sudah hapus renegotiation.

Protocol Downgrade via SNI

Sebelum ECH (Encrypted Client Hello), SNI dikirim plaintext β€” attacker bisa lihat domain mana yang dikunjungi, bahkan di HTTPS. ECH fix ini dengan mengenkripsi seluruh ClientHello.


Practical Detection of Malicious TLS

Indicators of Malicious TLS

IndicatorKemungkinanDetection
JA3 tidak dikenalCustom TLS stack (malware, C2)JA3 blocklist / allowlist (browser-only)
Cipher suite tidak wajarMalware pake cipher tua (RC4, CBC) karena library lawasSuricata: tls.ciphers rule
TLS version tuaMalware pake OpenSSL lama β†’ TLS 1.0/1.1Log tls.version
Self-signed certC2 server pake self-signedAlert tls.certificate.self_signed
Certificate mismatchC2 domain gak cocok sama CN/SANSuricata: tls.certificate.issuer
Unusual cert issuerC2 pake cert dari CA gak dikenalThreat intel feed
Beacon interval + TLSKoneksi TLS periodik ke IP asingZeek conn.log + time pattern
TLS handshake ke IP (bukan domain)C2 langsung ke IP tanpa SNISuricata: tls.sni kosong
Large certCustom CA yang generate cert gede >2KBtls.certificate.length
No ALPNC2 gak negotiate HTTP/2 β€” langsungtls.alpn kosong

Detection Tool

# Zeek β€” TLS logging
# conn.log: waktu, IP, port, bytes
# ssl.log: JA3, cipher, version, certificate chain, ALPN, SNI
 
# Query TLS ke IP tanpa SNI
cat ssl.log | zeek-cut ts server_name server_ip cipher | awk '$2 == "-"'
 
# Deteksi JA3 mencurigakan
cat ssl.log | zeek-cut ja3 | sort | uniq -c | sort -rn | head
 
# Python detection script
python3 << 'EOF'
import json
# Cek beacon interval: koneksi TLS periodik?
# Logika: group by IP, hitung interval rata-rata
# Kalo std dev rendah + interval tetap = beacon
EOF

Suricata Rule β€” Deteksi C2 TLS

alert tls $HOME_NET any -> $EXTERNAL_NET any (
    msg:"ET MALWARE Possible C2 - TLS to IP without SNI";
    flow:established,to_server;
    tls.sni; content:"|00|"; distance:0; within:1;
    tls.version; content:"|03 03|";  # TLS 1.2 minimum
    reference:url,attack.mitre.org/techniques/T1573/001;
    classtype:trojan-activity;
    sid:1000001; rev:1;
)

Hardening Checklist

☐ TLS 1.2 minimum β€” disable TLS 1.0, TLS 1.1, SSL 3.0, SSL 2.0
☐ Cipher AEAD-only: TLS_AES_128_GCM_SHA256, TLS_CHACHA20_POLY1305_SHA256
☐ Forward secrecy wajib β€” disable RSA key exchange
☐ Disable compression (CRIME)
☐ Disable client-side renegotiation
☐ HPKP deprecated β€” jangan pake
☐ HSTS: max-age=31536000; includeSubDomains; preload
☐ OCSP Stapling: aktifkan dan monitor
☐ Certificate Transparency: pastiin cert terdaftar di CT logs
☐ Private key: 2048-bit RSA minimum, prefer ECDSA P-256
☐ ED25519 untuk SSH β€” bukan TLS (tapi good practice)
☐ ECH (Encrypted Client Hello): aktifkan kalo tersedia
☐ TLS 1.3 preferred β€” optimalkan konfigurasi untuk 1-RTT/0-RTT
☐ Monitor JA3 β€” detect unusual TLS fingerprint
☐ Automatic renewal: Let's Encrypt (90 hari) β€” prevent expired cert
☐ Revocation: pastiin OCSP responder reachable, fallback ke CRL

OpenSSL Config Example

# nginx TLS config β€” strong, modern
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;  # Client pilih (modern β€” sesuai rekomendasi Mozilla)
ssl_ecdh_curve X25519:secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;

Koneksi ke Vault


References

  1. IETF. RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3. 2018. https://datatracker.ietf.org/doc/rfc8446/
  2. IETF. RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2. 2008.
  3. IETF. RFC 6066: TLS Extensions (SNI, ALPN, etc). 2011.
  4. IETF. RFC 7301: ALPN. 2014.
  5. IETF. RFC 8879: TLS Certificate Compression. 2021.
  6. Mozilla. Security/Server Side TLS. https://wiki.mozilla.org/Security/Server_Side_TLS
  7. Mozilla. SSL Configuration Generator. https://ssl-config.mozilla.org/
  8. Qualys SSL Labs. SSL Server Test. https://www.ssllabs.com/ssltest/
  9. Qualys SSL Labs. SSL/TLS Deployment Best Practices. https://github.com/ssllabs/research/wiki/SSL-and-TLS-Deployment-Best-Practices
  10. Cloudflare. TLS 1.3 Overview. https://www.cloudflare.com/learning-resources/tls-1-3/
  11. Cloudflare. What is SNI? https://www.cloudflare.com/learning/ssl/what-is-sni/
  12. Cloudflare. ECH β€” Encrypted Client Hello. https://blog.cloudflare.com/encrypted-client-hello/
  13. Let’s Encrypt. ACME Protocol. https://letsencrypt.org/docs/acme-protocol/
  14. Certificate Transparency. RFC 6962. https://certificate.transparency.dev/
  15. JA3. JA3 Fingerprinting. https://github.com/salesforce/ja3
  16. Suricata. TLS/SSL Detection Rules. https://suricata.readthedocs.io/en/latest/rules/tls-keywords.html
  17. Zeek. SSL/TLS Logging. https://docs.zeek.org/en/current/scripts/base/protocols/ssl/main.zeek.html
  18. Cipherli.st. Strong Ciphers for Apache, nginx, etc. https://cipherli.st/
  19. OpenSSL. OpenSSL Documentation. https://www.openssl.org/docs/
  20. BoringSSL. BoringSSL Documentation. https://boringssl.googlesource.com/boringssl/
  21. Google. TLS 1.3 0-RTT Replay Attack. https://www.rfc-editor.org/rfc/rfc9001.html
  22. sslLabs. SSL/TLS Attack History. https://github.com/ssllabs/research/wiki/SSL-and-TLS-Attacks

Bottom Line

TLS adalah fondasi keamanan transport modern β€” tapi bukan solusi ajaib. TLS mengamankan isi percakapan, tapi metadata (IP, panjang packet, timing) tetap bocor. Buat security engineer: (1) Cipher suite pilih AEAD + ECDHE β€” jangan sentuh CBC, jangan sentuh RSA key exchange. (2) TLS 1.3 wajib β€” lebih cepat, lebih aman, lebih sederhana. (3) JA3 fingerprinting adalah alat deteksi C2 yang powerful tapi harus dipahami keterbatasannya β€” attacker bisa JA3 randomization. (4) Certificate Transparency mengubah sertifikat dari β€œtrust based on secrecy” menjadi β€œtrust based on transparency” β€” setiap cert yang diterbitkan untuk domain lo tanpa sepengetahuan lo = indikasi compromise. (5) Forward secrecy mengubah dampak private key leakage dari β€œsemua masa lalu terbaca” jadi β€œhanya masa depan” β€” ini bukan opsi, ini wajib.