tintinweb / scapy-ssl_tls

SSL/TLS layers for scapy the interactive packet manipulation tool
GNU General Public License v2.0
419 stars 156 forks source link

- fix dissection of stacked tlsrecords within SSL() #17

Closed tintinweb closed 9 years ago

tintinweb commented 9 years ago

@alexmgr does this fix problems with stacked records for you? if so, we can also fix this by having scapy dissect our packets by implementing extract_padding on TLSRecord.

Note that packets after the change_cipher_spec are encrypted. We do not handle this at the moment thats why the packet after change_cipher_spec looks odd. Need to implement that on a TLSRecord level to fall back to Raw or a special TLSEncrypted layer in case the payload to TLSRecord carries an invalid length.

this is what I get with python2.6 on that branch, trying to process a recorded handshake tls1_0 aes128-sha (openssl s_client/s_server):

test code:

pcaps = rdpcap(r'ssl.pcap')
for p in pcaps:
    if p.haslayer(SSL):
        p[TCP].show2()

output:

WARNING: No route found for IPv6 destination :: (no default route?)
###[ TCP ]###
  sport     = 12046
  dport     = https
  seq       = 627883325
  ack       = 3436110327L
  dataofs   = 5L
  reserved  = 0L
  flags     = PA
  window    = 65535
  chksum    = 0x7caf
  urgptr    = 0
  options   = []
###[ SSL/TLS ]###
     \records   \
      |###[ TLS Record ]###
      |  content_type= handshake
      |  version   = TLS_1_0
      |  length    = 0xd1
      |###[ TLS Handshake ]###
      |     type      = client_hello
      |     length    = 0xcd
      |###[ TLS Client Hello ]###
      |        version   = TLS_1_0
      |        gmt_unix_time= 4288841879L
      |        random_bytes= '|A\xa1\x084,\x98\xc2p\x04\xa0]_9\xef\xe0p\xd5\x12\xf15\x17\xb6\r\xc4\xd3\t\x85'
      |        session_id_length= 0x0
      |        session_id= ''
      |        cipher_suites_length= 0x5a
      |        cipher_suites= [49172, 49162, 57, 56, 136, 135, 49167, 49157, 53, 132, 49171, 49161, 51, 50, 154, 153, 69, 68, 49166, 49156, 47, 150, 65, 49169, 49159, 49164, 49154, 5, 4, 49170, 49160, 22, 19, 49165, 49155, 10, 21, 18, 9, 20, 17, 8, 6, 3, 255]
      |        compression_methods_length= 0x2
      |        compression_methods= [1, 0]
      |        extensions_length= 0x49
      |        \extensions\
      |         |###[ TLS Extension ]###
      |         |  type      = ec_point_formats
      |         |  length    = 0x4
      |         |###[ TLS Extension EC Points Format ]###
      |         |     length    = 0x3
      |         |     ec_point_formats= [0, 1, 2]
      |         |###[ TLS Extension ]###
      |         |  type      = elliptic_curves
      |         |  length    = 0x34
      |         |###[ TLS Extension Elliptic Curves ]###
      |         |     length    = 0x32
      |         |     elliptic_curves= [14, 13, 25, 11, 12, 24, 9, 10, 22, 23, 8, 6, 7, 20, 21, 4, 5, 18, 19, 1, 2, 3, 15, 16, 17]
      |         |###[ TLS Extension ]###
      |         |  type      = session_ticket_tls
      |         |  length    = 0x0
      |         |###[ TLS Extension ]###
      |         |  type      = heartbeat
      |         |  length    = 0x1
      |         |###[ TLS Extension HeartBeat ]###
      |         |     mode      = '\x01'
###[ TCP ]###
  sport     = https
  dport     = 12046
  seq       = 3436110327L
  ack       = 627883539
  dataofs   = 5L
  reserved  = 0L
  flags     = PA
  window    = 123
  chksum    = 0xe52e
  urgptr    = 0
  options   = []
###[ SSL/TLS ]###
     \records   \
      |###[ TLS Record ]###
      |  content_type= handshake
      |  version   = TLS_1_0
      |  length    = 0x3a
      |###[ TLS Handshake ]###
      |     type      = server_hello
      |     length    = 0x36
      |###[ TLS Server Hello ]###
      |        version   = TLS_1_0
      |        gmt_unix_time= 1432147607
      |        random_bytes= '\xa3\x97\xe9\xf4\x0c\xf4V\x14\x9f\xe4$\xf9\xebI\xd4\xd1_\xfc\x12\xb4\xfdEN=\xebj\xad\xcf'
      |        session_id_length= 0x0
      |        session_id= ''
      |        cipher_suite= RSA_WITH_AES_128_CBC_SHA
      |        compression_method= DEFLATE
      |        extensions_length= 0xe
      |        \extensions\
      |         |###[ TLS Extension ]###
      |         |  type      = renegotiationg_info
      |         |  length    = 0x1
      |         |###[ Raw ]###
      |         |     load      = '\x00'
      |         |###[ TLS Extension ]###
      |         |  type      = session_ticket_tls
      |         |  length    = 0x0
      |         |###[ TLS Extension ]###
      |         |  type      = heartbeat
      |         |  length    = 0x1
      |         |###[ TLS Extension HeartBeat ]###
      |         |     mode      = '\x01'
      |###[ TLS Record ]###
      |  content_type= handshake
      |  version   = TLS_1_0
      |  length    = 0x190
      |###[ TLS Handshake ]###
      |     type      = certificate
      |     length    = 0x18c
      |###[ TLS Certificate List ]###
      |        length    = 0x189
      |        \certificates\
      |         |###[ TLS Certificate ]###
      |         |  length    = 0x186
      |         |  \data      \
      |         |   |###[ X509Cert ]###
      |         |   |  version   = None
      |         |   |  sn        = <ASN1_INTEGER[4L]>
      |         |   |  sign_algo = <ASN1_OID['.1.2.840.113549.1.1.4']>
      |         |   |  sa_value  = <ASN1_NULL[0L]>
      |         |   |  \issuer    \
      |         |   |   |###[ X509RDN ]###
      |         |   |   |  oid       = <ASN1_OID['.2.5.4.6']>
      |         |   |   |  value     = <ASN1_PRINTABLE_STRING['AU']>
      |         |   |   |###[ X509RDN ]###
      |         |   |   |  oid       = <ASN1_OID['.2.5.4.8']>
      |         |   |   |  value     = <ASN1_PRINTABLE_STRING['QLD']>
      |         |   |   |###[ X509RDN ]###
      |         |   |   |  oid       = <ASN1_OID['.2.5.4.3']>
      |         |   |   |  value     = <ASN1_PRINTABLE_STRING['SSLeay/rsa test CA']>
      |         |   |  not_before= <ASN1_UTC_TIME['951009233205Z']>
      |         |   |  not_after = <ASN1_UTC_TIME['980705233205Z']>
      |         |   |  \subject   \
      |         |   |   |###[ X509RDN ]###
      |         |   |   |  oid       = <ASN1_OID['.2.5.4.6']>
      |         |   |   |  value     = <ASN1_PRINTABLE_STRING['AU']>
      |         |   |   |###[ X509RDN ]###
      |         |   |   |  oid       = <ASN1_OID['.2.5.4.8']>
      |         |   |   |  value     = <ASN1_PRINTABLE_STRING['QLD']>
      |         |   |   |###[ X509RDN ]###
      |         |   |   |  oid       = <ASN1_OID['.2.5.4.10']>
      |         |   |   |  value     = <ASN1_PRINTABLE_STRING['Mincom Pty. Ltd.']>
      |         |   |   |###[ X509RDN ]###
      |         |   |   |  oid       = <ASN1_OID['.2.5.4.11']>
      |         |   |   |  value     = <ASN1_PRINTABLE_STRING['CS']>
      |         |   |   |###[ X509RDN ]###
      |         |   |   |  oid       = <ASN1_OID['.2.5.4.3']>
      |         |   |   |  value     = <ASN1_PRINTABLE_STRING['SSLeay demo server']>
      |         |   |  pubkey_algo= <ASN1_OID['.1.2.840.113549.1.1.1']>
      |         |   |  pk_value  = <ASN1_NULL[0L]>
      |         |   |  pubkey    = <ASN1_BIT_STRING['\x000H\x02A\x00\xb7,%\xdcI\xc5\xaekC\xc5.A\xc1.m\x95z:\xa9\x03QxE\x0f*\xd1X\xd1\x88\xf6\x9f\x8f\x1f\xd9\xfd\xa5\x87\xde*]1[\xee$f\xbf\xc0U\xdb\xfep\xc5,9_Z\x9f\xa8\x08\xfc!\x06\xd5O\x02\x03\x01\x00\x01']>
      |         |   |  x509v3ext = []
      |         |   |  sign_algo2= <ASN1_OID['.1.2.840.113549.1.1.4']>
      |         |   |  sa2_value = <ASN1_NULL[0L]>
      |         |   |  signature = <ASN1_BIT_STRING['\x00+4["\x85b#\x076\xf4\x0c+\x14\xd0\x1b\xcb\xd9\xbb\xd2\xc0\x9a\xcf\x12\xa1e\x90:\xb7\x17\x83:\x10k\xad/\xd6\xb1\x11\xc0\rZ\x06\xdb\x11\xd0/4\x90\xf5va&\xa1i\xf2\xdb\xb3\xe7 \xcb:d\xe6A']>
      |###[ TLS Record ]###
      |  content_type= handshake
      |  version   = TLS_1_0
      |  length    = 0x4
      |###[ TLS Handshake ]###
      |     type      = server_hello_done
      |     length    = 0x0
###[ TCP ]###
  sport     = 12046
  dport     = https
  seq       = 627883539
  ack       = 3436110804L
  dataofs   = 5L
  reserved  = 0L
  flags     = PA
  window    = 65058
  chksum    = 0xac08
  urgptr    = 0
  options   = []
###[ SSL/TLS ]###
     \records   \
      |###[ TLS Record ]###
      |  content_type= handshake
      |  version   = TLS_1_0
      |  length    = 0x46
      |###[ TLS Handshake ]###
      |     type      = client_key_exchange
      |     length    = 0x42
      |###[ TLS Client Key Exchange ]###
      |        length    = 0x40
      |###[ Raw ]###
      |           load      = '\x9es\xdf\xe0\xf2\xd0@2D\x9a4\x7fW\x86\x10\xea=\xc5\xe2\xf9\xa5iC\xc9\x0b\x00~\x911W\xfc\xc5e\x18\rD\xfdQ\xf8\xda\x8az\xab\x16\x03\xeb\xac#n\x8d\xdd\xbb\xf4u\xe7\xb7\xa3\xce\xdbgk}0*'
      |###[ TLS Record ]###
      |  content_type= change_cipher_spec
      |  version   = TLS_1_0
      |  length    = 0x1
      |###[ TLS ChangeCipherSpec ]###
      |     message   = '\x01'
      |###[ TLS Record ]###
      |  content_type= handshake
      |  version   = TLS_1_0
      |  length    = 0x30
      |###[ TLS Handshake ]###
      |     type      = certificate_url
      |     length    = 0xcb7a5b
      |###[ Raw ]###
      |        load      = "-\xc0'\t(b\x95D\x9f\xa1\x1eNj\xfbI\x9dj$D\xc6\x8e&\xbc\xc1(\x8c'\xcc\xa2\xba\xec8cnd\xd8R\x94\x17\x96a\xfd\x9cT"
###[ TCP ]###
  sport     = https
  dport     = 12046
  seq       = 3436110804L
  ack       = 627883673
  dataofs   = 5L
  reserved  = 0L
  flags     = PA
  window    = 131
  chksum    = 0xc77f
  urgptr    = 0
  options   = []
###[ SSL/TLS ]###
     \records   \
      |###[ TLS Record ]###
      |  content_type= handshake
      |  version   = TLS_1_0
      |  length    = 0xaa
      |###[ TLS Handshake ]###
      |     type      = 4
      |     length    = 0xa6
      |###[ Raw ]###
      |        load      = '\x00\x00\x1c \x00\xa0\xd4\xee\xb0\x9b\xb5\xa2\xd3\x00W\x84Y\xec\r\xbf\x05\x0c\xd5\xb9\xe2\xf82\xb5\xec\xce\xe2\x9c%%\xd9>J\x94[\xca\x18+\x0f_\xf6s8b\xcd\xcc\xf129\xe4^0\xf3\x94\xf5\xc5\x94:\x8c\x8e\xe5\x12J\x1e\xd81\xb5\x17\t\xa6Li\xca\xae\xfb\x04\x17dT\x9e\xc2\xfa\xf3m\xe9\xa5\xed\xa6e\xfe/\xf3\xc6\xcex@\xf7e\xe0\x13\xd3w\xc7\xc5y\x16VL0\x94\xcf\xb0<\x00\x91\xbd\x86\x08\x9f/\x05g\x03o\xa7;\xb96\xf2\x80O`]L\xc4B]\x02D\xba1\x8f9\x8e\x0c\x1e\xa8&O>\x01\x96\xb3o\xc6%\xe40\x03\xd6:}'
      |###[ TLS Record ]###
      |  content_type= change_cipher_spec
      |  version   = TLS_1_0
      |  length    = 0x1
      |###[ TLS ChangeCipherSpec ]###
      |     message   = '\x01'
      |###[ TLS Record ]###
      |  content_type= handshake
      |  version   = TLS_1_0
      |  length    = 0x30
      |###[ TLS Handshake ]###
      |     type      = 37
      |     length    = 0xb858c1
      |###[ Raw ]###
      |        load      = '\xa6?\xf8\xbd\xe6\xae\xbd\x98\xd4u\xa5E\x1b\xd8jpy\x86)NOd\xba\xe7\x1f\xcaK\x96\x9b\xf7\x0bP\xf5O\xfd\xda\xda\xcd\xcdK\x12.\xdf\xd5'
###[ TCP ]###
  sport     = 12046
  dport     = https
  seq       = 627883673
  ack       = 3436111038L
  dataofs   = 5L
  reserved  = 0L
  flags     = PA
  window    = 64824
  chksum    = 0xf6a8
  urgptr    = 0
  options   = []
###[ SSL/TLS ]###
     \records   \
      |###[ TLS Record ]###
      |  content_type= application_data
      |  version   = TLS_1_0
      |  length    = 0x20
      |###[ Raw ]###
      |     load      = 'j=\xd7c\x08\x89\xd2g\t\xc6\xe7\xfdT0\xd1\xbbg\xb4 \xd0<}}</\xb7\x1a\t\xcbve$'
      |###[ TLS Record ]###
      |  content_type= application_data
      |  version   = TLS_1_0
      |  length    = 0x20
      |###[ Raw ]###
      |     load      = '-\xaa\xf59\xd02\xea\x88\x99&F\xdar\xafAk\x83M\x84\xe7\xe7\xa6\xde\xdd\xbdz\xa3\x98\xbe\x11D\xa7'
###[ TCP ]###
  sport     = 12046
  dport     = https
  seq       = 627883747
  ack       = 3436111038L
  dataofs   = 5L
  reserved  = 0L
  flags     = PA
  window    = 64824
  chksum    = 0x67f8
  urgptr    = 0
  options   = []
###[ SSL/TLS ]###
     \records   \
      |###[ TLS Record ]###
      |  content_type= application_data
      |  version   = TLS_1_0
      |  length    = 0x20
      |###[ Raw ]###
      |     load      = 'w:\x94}\xb4GJ\x1d\xd4lZit\x03\x932\xcaT^\xa5\x81\x99jsf\xbf\x06\xa0\xdcj\x9c\xb1'
      |###[ TLS Record ]###
      |  content_type= application_data
      |  version   = TLS_1_0
      |  length    = 0x20
      |###[ Raw ]###
      |     load      = 'Dd\xc8\xc2Z\xfcJ\x82\xddSm0\x82M5"\xf1_;\x96fya\x9fQ\x93\x1b\xbfS;\xf8&'
###[ TCP ]###
  sport     = 12046
  dport     = https
  seq       = 627883821
  ack       = 3436111038L
  dataofs   = 5L
  reserved  = 0L
  flags     = PA
  window    = 64824
  chksum    = 0x5a0b
  urgptr    = 0
  options   = []
###[ SSL/TLS ]###
     \records   \
      |###[ TLS Record ]###
      |  content_type= application_data
      |  version   = TLS_1_0
      |  length    = 0x20
      |###[ Raw ]###
      |     load      = '\x89\xa0\x89`Hp\x03W\xd0?x^~CxNtBM\x15\x02\xe0\x0eom[\x11\x08\x96\xd3z\xe6'
      |###[ TLS Record ]###
      |  content_type= application_data
      |  version   = TLS_1_0
      |  length    = 0x30
      |###[ Raw ]###
      |     load      = '-d\xb0#\x1a\xa8\x10\\c\xec\xd3Mh\xe3\xdaS\xe60@\xf4\xc2\xffw\xd8+\xf6,x\xf7?+\xa5\x1c\xb32\xd8w\xdd\xb1{\x91u\xf0\xae\x14\xa8\xef\x1b'
alexmgr commented 9 years ago

I'll give it a shot, but I doubt it will fix it, because that was one of the first fixes I tried on that code branch. Also this will not fix the optional extensions problem. we can also fix this by having scapy dissect our packets by implementing extract_padding on TLSRecord. => This is roughly what I did in PR#16, but it also deals with optional extensions and removes the dead code in do_dissect() I'll check it out and let you know.

tintinweb commented 9 years ago

Oh, you're right, seems like extensions are optional to hello packets! Totally skipped that part while going through the RFC.

will close this one. please go ahead and merge #17, thanks!