Pentesting custom TLS stacks

55
Pentesting custom TLS stacks Alex Moneger

Transcript of Pentesting custom TLS stacks

Page 1: Pentesting custom TLS stacks

Pentesting custom TLS stacksAlex Moneger

Page 2: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

2

Who am I?• Security engineer at Citrix• Interest in low level topics (crypto, fuzzing,

exploit dev)• "the views expressed herein are personal and

stated in my individual capacity and in no way a statement or position of my employer”

1/16/16

Page 3: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

3

Agenda1. TLS attacks timeline2. Difficulty in reproducing attacks3. Quick refresher on TLS4. Scapy-ssl_tls goals5. Quick demo of scapy-ssl_tls capabilities6. Custom TLS stacks, what to look for?7. Scapy-ssl_tls crypto8. Demo: detecting Poodle9. Fuzzing capabilities

1/16/16

Page 4: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

4

Introduction• TLS is a critical protocol to the internet• Very few alternatives• Session layer protocol for other protocols• Very complex

1/16/16

Page 5: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

5

Introduction• Protocol under scrutiny• Growth of the number of attacks• General lack of tooling• Attacks are developed ad-hoc:– Extensions of OpenSSL– …

1/16/16

Page 6: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

6

TLS PROTOCOL LEVEL ATTACKS

1/16/16

Page 7: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

7

Introduction• Protocol under scrutiny• Growth of the number of protocol level

attacks• Numerous implementation bugs

1/16/16

Page 8: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

8

Timeline

1/16/16

Renegotiation

2009 20162013

BEAST CRIME

2014 2015201220112010

BREACH

Lucky13

POODLE

POODLE2

FREAK

LOGJAM

SLOTH

THS

Page 9: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

9

Observations• TLS protocol attacks increase:– Frequency– Complexity

• 2 classes:– Protocol level– Crypto level

1/16/16

Page 10: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

10

REPRODUCING ATTACKS

1/16/16

Page 11: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

11

Problems• Understand the attack properly• Practical impact (as opposed to theoretical

problem)• Reproducibility• Fix (dev + Q&A) • Fix for good (regression)1/16/16

Page 12: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

12

Response• Customers do not always understand the practical impact• Your response team has to provide a definite answer• 2 solutions for custom implementations:

– Crypto code review:• Lack of comparison point• Hard to get the full picture when deep into a crypto routine

– PoC:• Lack of tooling• Big difference between regular lib and security focused lib

1/16/16

Page 13: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

13

TLS REFRESHER

1/16/16

Page 14: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

14

Basics• TLS is session layer (layer 5)• Performs a handshake then provides crypto• Transparent to protocol• High RTT (at least 4 packets, 2 RTT for handshake)• Offers session resumption• Can authenticate both client and server• Provides integrity and confidentiality• Relies on TCP for packet delivery and ordering

1/16/16

Page 15: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

15

Message format• Has sub-protocols within the protocol:

1. Handshake (negotiate parameters)2. Change Cipher Spec (signal a cipher change)3. Alert (error handling)4. Application data (move data)

• Each of these sub-protocols are encapsulated in a Record header which holds:– Proto version– Payload length– Payload type

1/16/16

Page 16: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

16

TLS Record• In charge of transporting the sub-protocols

• Record is always cleartext• Payload length is not completely protected in TLS• Records can be “stacked” inside a packet:

VersionSize

LengthHandshake, Data, …

Record Handshake, Data, … Record Handshake, Data, …1/16/16

Page 17: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

17

Handshake• In charge of negotiating:– Compression– Crypto parameters– Initiating crypto material

• In charge of ensuring handshake is free of in transit tampering (finish message)

• Extensible (through TLS extensions)1/16/16

Page 18: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

20

Handshake quirks• Max size: 2**16, can be TLS fragmented• Some messages can have arbitrary trailing data

(support for unknown extensions)• Doesn’t need a certificate (anonymous RSA, DH

and ECDH)• Can have “stacked” handshakes in a record (Java)

Record Handshake Handshake Handshake

1/16/16

Page 19: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

22

Application Data• Encrypted + authenticated packets• Cleartext is HMACd then padded => MAC then

encrypt…

Padding is not protected by the MAC• Stream ciphers:

Record Cleartext HMAC padding Paddinglength

Encrypted

Record Cleartext HMAC

Encrypted1/16/16

Page 20: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

24

SCAPY-SSL_TLS

1/16/16

Page 21: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

25

Introduction• TLS & DTLS attack stack built above scapy• Stateless (as much as possible)• Packet crafting and dissecting• Crypto session handling• Sniffing (wire, pcap, …)

1/16/16

Page 22: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

26

Why bother?• TLS stacks are built to be robust• Enforce input parameters to be valid• Tear down connection on error• Not very flexible

1/16/16

Page 23: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

27

Goals• Easy to install and use• Simplify discovery and exploitation of TLS vulnerabilities• Allow full control of any TLS field• Tries very hard to maintain absolutely no state• Good documentation and examples• No checks or enforcements (up to user if desired)• Sane defaults• Transparent encryption

1/16/16

Page 24: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

28

Features• Full support:

– SSLv3, TLS 1.0, TLS 1.1, TLS1.2 and DTLS– RSA, DHE, ECDHE key exchanges with all available ciphers– RSA and DSA signature– All TLS records and extensions– Transparent decryption of TLS traffic– Client certs

• Missing:– AES-GCM and CCM

1/16/16

Page 25: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

29

Installation• Stable branch (v1.2.2 today):– pip install scapy-ssl_tls

• Dev branch (latest features + examples):– git clone https://github.com/tintinweb/scapy-ssl_tls– Or pip install git+https://github.com/tintinweb/scapy-

ssl_tls@master• Feature branches:– Replace @master by @branch

1/16/16

Page 26: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

30

Concepts• Start scapy• All classes start with TLS:

– Allows easy autocomplete• What fields are available in a given TLS record?

– ls(TLSClientHello)• TLSSocket() is used to wrap the TCP socket

– This is your base element to send/recv traffic• Build packets scapy style:

– p = TLSRecord()/TLSHandshake()/TLSClientHello()

1/16/16

Page 27: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

31

DEMOPacket crafting/parsing

1/16/16

Page 28: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

32

Packet crafting/parsingimport socket

version = TLSVersion.TLS_1_2ciphers = [TLSCipherSuite.ECDHE_RSA_WITH_AES_128_CBC_SHA]host = ("localhost", 8443)

socket_ = socket.socket()socket_.connect(host)tls_socket = TLSSocket(socket_, client=True)packet = TLSRecord() / TLSHandshake() /\ TLSClientHello(version=version, cipher_suites=ciphers)tls_socket.sendall(packet)response = tls_socket.recvall()response.show()response[TLSServerECDHParams].show()print(tls_socket.tls_ctx)

1/16/16

Page 29: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

33

Extensions import socket

version = TLSVersion.TLS_1_2ciphers = [TLSCipherSuite.ECDHE_RSA_WITH_AES_128_CBC_SHA]host = ("localhost", 8443)sni = TLSExtension() /\ TLSExtServerNameIndication(server_names= [TLSServerName(data=”localhost",length=9)])alpn = TLSExtension() /\ TLSExtALPN(protocol_name_list=[TLSALPNProtocol(data="h2")])frag = TLSExtension() / TLSExtMaxFragmentLength(fragment_length=233)extensions = [sni, alpn, frag]

socket_ = socket.socket()socket_.connect(host)tls_socket = TLSSocket(socket_, client=True)packet = TLSRecord() / TLSHandshake() /\ TLSClientHello(version=version, cipher_suites=ciphers, extensions=extensions)tls_socket.sendall(packet)response = tls_socket.recvall()response.show()

1/16/16

Page 30: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

34

Transparent traffic decryptionimport socket

version = TLSVersion.TLS_1_2ciphers = [TLSCipherSuite.ECDHE_RSA_WITH_AES_128_CBC_SHA]host = ("localhost", 8443)app_payload = "GET / HTTP/1.1\r\nHOST: example.com\r\n\r\n"

socket_ = socket.socket()socket_.connect(host)tls_socket = TLSSocket(socket_, client=True)# Handshaketls_do_handshake(tls_socket, version, ciphers)# Application datatls_socket.sendall(to_raw(TLSPlaintext(data=app_payload), tls_socket.tls_ctx))response = tls_socket.recvall()response.show()print(tls_socket.tls_ctx)

1/16/16

Page 31: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

35

WHAT TO LOOK FOR

1/16/16

Page 32: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

36

Basic recon• Supported TLS versions• Supported ciphers• Supported compression methods• Cipher preference ordering• Certificates• Trust chain1/16/16

Page 33: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

37

Recon• Fingerprint possible fork• OpenSSL empty plaintext fragment• JSSE stacked handshake• Difference in Alert type when tampering with

Finish message

1/16/16

Page 34: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

38

State machine• Tricky testing: mostly manual work and knowledge of

RFC• Automated testing: FlexTLS:– Example: mono FlexApps.exe -s efin --connect

localhost:8443• Gives a good starting point for manual testing• Lot of legacy stuff: server-gated cryptography anyone?

1/16/16

Page 35: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

39

Diffie Hellman• Check the validity of server (EC)DH params

– Group size– Primality– Subgroup confinement attack (e.g: Off curve test (EC))– Signature algo used– …

• Send random values (small, non-prime, …)• Scapy-ssl_tls uses TinyEC for EC calculation• Allows to perform EC arithmetic

1/16/16

Page 36: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

40

Side channels (RSA)• Pre Master Secret is decrypted• TLS mandates PKCS1 v1.5 for padding• This needs to be constant time, see classic Bleichenbacher• Time and Check for response difference on invalid

padding (alert vs tcp reset)• Can use pybleach pkcs1_test_client.py to generate faulty

padding for your PMS

1/16/16

Page 37: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

41

Side channels (ciphers)• Padding and MAC checks must be constant

time• Alert type must be identical• Time and check response when flipping bytes

in padding and MAC

1/16/16

Page 38: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

42

Proper byte checking• Some implementation only verify a few bytes

of padding, MAC and verify_data (finish hash)• All bytes must be checked for obvious reasons• Send application data packets with flipped

padding, MAC and verify_data• Make sure you always get an alert1/16/16

Page 39: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

43

DDoS• DTLS is UDP• Returns a certificate chain on first packet• DTLS hello => 64 bytes• DTLS response => can be several kB• Protection is built into the protocol, but is a MAY =>

HelloVerifyRequest• Make sure to check cookie is returned upon multiple spoofed

requests

1/16/16

Page 40: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

44

Fragmentation• Any packet above 2**14 (16384) bytes must be fragmented• But any fragment size can be chosen• Few stacks support TLS re-assembly• Can be used to bypass devices which parse TLS, but fail-open• Server can be requested to fragment using the Maximum

Fragment Length Negotiation extension• DTLS allows to specify the fragment offset in the handshake

1/16/16

Page 41: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

45

CRYPTO HOOKS

1/16/16

Page 42: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

46

tls_to_raw• Scapy-ssl_tls exposes tls_to_raw()

• Calculates all crypto material for the packet• Exposes some hooks:

– At compression time– Pre and post encryption

• Allows to act on pre-calculated padding and MACs1/16/16

to_raw(pkt, tls_ctx, include_record=True, compress_hook=None, pre_encrypt_hook=None, encrypt_hook=None)

Page 43: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

47

Crypto container• All crypto material stored in a CryptoContainer:– IV, mac, padding, padding length

• Passed to and returned by crypto hooks:

1/16/16

def modify_padding(crypto_container): padding = crypto_container.padding byte_flip = chr(ord(padding[index]) ^ 0xff) crypto_container.padding = "%s%s%s" % (padding[:index], byte_flip, padding[index + 1:]) return crypto_container

tls_to_raw(TLSPlaintext(data=data), tls_socket.tls_ctx, pre_encrypt_hook=modify_padding)

Page 44: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

48

Usage• Very useful to modify crypto state• Without keeping track of PRF, ciphers, MACs,…• Allows to easily reproduce attacks on crypto

material

1/16/16

Page 45: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

49

DEMO POODLE2 CHECK

1/16/16

Page 46: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

50

DEMOFragmentation

1/16/16

Page 47: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

51

Fragmentation code import socket

version = TLSVersion.TLS_1_2ciphers = [TLSCipherSuite.ECDHE_RSA_WITH_AES_128_CBC_SHA]host = ("localhost", 8443)frag = TLSExtension() / TLSExtMaxFragmentLength(fragment_length=1)extensions = [frag]

s = socket.socket()s.connect(host)ts = TLSSocket(s, client=True)payload = TLSHandshake()/TLSClientHello(version=version, cipher_suites=ciphers, extensions=extensions)frags = tls_fragment_payload(payload, TLSRecord(version=version, content_type=TLSContentType.HANDSHAKE), 16)ts.sendall(frags)r = ts.recvall()

1/16/16

Page 48: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

52

CONCLUSION

1/16/16

Page 49: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

53

Strengths• Scapy-ssl_tls can speed up PoC development• PoC can be re-used as part of testing QA and

regression• Valuable to reproduce findings & develop

mitigations• Help in learning & experimenting with TLS1/16/16

Page 50: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

54

Thanks• Thanks to tintinweb who started the project• Bugs:

https://github.com/tintinweb/scapy-ssl_tls/• Contact:– Github: alexmgr

1/16/16

Page 51: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

55

THANKS

1/16/16

Page 52: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

56

IF TIME ALLOWS

1/16/16

Page 53: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

57

Fuzzing• Provides basic fuzzing through scapy• Tries to be smart by preserving semantically necessary fields• Use fuzz() function on any element

1/16/16

fuzz(TLSRecord()/TLSHandshake(type=TLSHandshakeType.SUPPLEMENTAL_DATA)/TLSAlert()).show2()###[ TLS Record ]### content_type= handshake <= preserved version= 0x7391 <= fuzzed length= 0x6 <= preserved###[ TLS Handshake ]### type= supplemental_data <= overriden length= 0x2 <= preserved###[ Raw ]### load= '(\r’ <= fuzzed

Page 54: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

58

Fuzzing• Only good for basic fuzzing• Simple to plug in your own fuzzer• Just generate data, scapy-ssl_tls takes care of

the rest• Good targets: TLS extensions, certificates, …

1/16/16

Page 55: Pentesting custom TLS stacks

Alex Moneger - Pentesting custom TLS stacks

59

Examples• The example section contains some useful base tools:

– RSA session sniffer: given a cert, can decrypt wire traffic (like Wireshark)

– Security scanner: a rudimentary TLS scanner (versions, ciphers, SCSV, …)

– Downgrade test– …

• Just baselines to write your own tools1/16/16