Domanda Aiuto Script Brute force di directory web

k0Br@3390

Utente Bronze
16 Marzo 2020
46
18
1
31
Salve, stavo scrivendo uno script per effettuare il brute forcing delle directory "nascoste" in un web server, e volevo migliorarlo usando il modulo thread di python, volevo sapere se ho applicato bene il thread (ps Allo script va passato sia l'url da attaccare che una wordlist.):
Python:
#! /usr/bin/python
import sys
import socket
import requests
from threading import Thread

try:
    rhost = sys.argv[1]
    wordlist = sys.argv[2]

    print ('[*] Checking RHOST... '),
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        status = s.connect_ex((rhost, 80))
        s.close()
        if status == 0:
            print ('[DONE]')
            pass
        else:
            print ('[FAIL]')
            print ('[!] Error: Cannot Reach RHOST %s\n' %(rhost))
            sys.exit(1)
    except socket.error:
        print ('[FAIL]')
        print ('[!] Error: Cannot Reach RHOST: %s\n' %(rhost))
        sys.exit(1)

    print ('[*] Parsing Wordlist... ',)
    try:
        with open(wordlist) as file:
            to_check = file.read().strip().split('\n')
        print ('[DONE]')
        print ('[*] Total Paths to Check: %s' %(str(len(to_check))))
    except IOError:
        print ('[FAIL]')
        print ('[!] Error: Failed to Read Specified File\n')
        sys.exit(1)
    
    def checkpath(path):
        try:
            response = requests.get('http://' + rhost + '/' + path).status_code
        except Exception:
            print ('[!] Error: An Unexpected Error Occured')
            sys.exit(1)
        if response == 200:
            print ('[*] Valid Path Found: /%s' %(path))
    
    print ('\n[*] Beginning Scan...\n')
    for i in range(len(to_check)):
        t = Thread(target=checkpath, args=to_check)
        checkpath(to_check[i])
    print ('\n[*] Scan Complete!')
except KeyboardInterrupt:
    print ('\n[!] Error: User Interrupted Scan')
    sys.exit(1)
 
Salve, stavo scrivendo uno script per effettuare il brute forcing delle directory "nascoste" in un web server, e volevo migliorarlo usando il modulo thread di python, volevo sapere se ho applicato bene il thread (ps Allo script va passato sia l'url da attaccare che una wordlist.):
Python:
#! /usr/bin/python
import sys
import socket
import requests
from threading import Thread

try:
    rhost = sys.argv[1]
    wordlist = sys.argv[2]

    print ('[*] Checking RHOST... '),
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        status = s.connect_ex((rhost, 80))
        s.close()
        if status == 0:
            print ('[DONE]')
            pass
        else:
            print ('[FAIL]')
            print ('[!] Error: Cannot Reach RHOST %s\n' %(rhost))
            sys.exit(1)
    except socket.error:
        print ('[FAIL]')
        print ('[!] Error: Cannot Reach RHOST: %s\n' %(rhost))
        sys.exit(1)

    print ('[*] Parsing Wordlist... ',)
    try:
        with open(wordlist) as file:
            to_check = file.read().strip().split('\n')
        print ('[DONE]')
        print ('[*] Total Paths to Check: %s' %(str(len(to_check))))
    except IOError:
        print ('[FAIL]')
        print ('[!] Error: Failed to Read Specified File\n')
        sys.exit(1)
 
    def checkpath(path):
        try:
            response = requests.get('http://' + rhost + '/' + path).status_code
        except Exception:
            print ('[!] Error: An Unexpected Error Occured')
            sys.exit(1)
        if response == 200:
            print ('[*] Valid Path Found: /%s' %(path))
 
    print ('\n[*] Beginning Scan...\n')
    for i in range(len(to_check)):
        t = Thread(target=checkpath, args=to_check)
        checkpath(to_check[i])
    print ('\n[*] Scan Complete!')
except KeyboardInterrupt:
    print ('\n[!] Error: User Interrupted Scan')
    sys.exit(1)
Ciao, sei riuscito a far funzionare il tuo script alla fine? Io ho notato un paio di cose che credo siano sbagliate. Quando crei il thread dovresti usare questa sintassi:
Python:
t = threading.Thread(target = funzione_usata, args = argomento) #Creazione del thread
Però dopo dovresti anche avviarlo, sempre nel tuo for:
Python:
t.start() #Avvio del thread
Inoltre, credo non sia necessario chiamare alle fine del for la funzione che passi al thread, dato che la esegue già quest' ultimo (la riceve come parametro durante la creazione). Dovresti provare a iterare sulla wordlist attraverso gli argomenti che passi al thread durante la creazione dello stesso e non con la successiva chiamata di funzione (per capirci la checkpath che fai alla fine). Questo, difatti, dovrebbe corrispondere ad assegnare un thread diverso per ogni percorso da cercare tra le directory del server. Teoricamente, poi, i thread andrebbero riuniti (join()) al padre, ma dovrebbe andare bene anche senza questa operazione.
 
Il problema di avviare un nuovo thread per ogni riga della wordlist è che diventerà inefficiente appena il numero di righe supera il numero di core del processore fisico (andranno in time-sharing e avviare un thread è un operazione dispendiosa). L'approccio che sfrutta meglio i thread sarebbe dividere la wordlist per il numero di core, avviare tanti thread quanti core ci sono e dare una frazione diversa della wordlist a ciascuno.
 
  • Mi piace
Reazioni: --- Ra ---
Il problema di avviare un nuovo thread per ogni riga della wordlist è che diventerà inefficiente appena il numero di righe supera il numero di core del processore fisico (andranno in time-sharing e avviare un thread è un operazione dispendiosa). L'approccio che sfrutta meglio i thread sarebbe dividere la wordlist per il numero di core, avviare tanti thread quanti core ci sono e dare una frazione diversa della wordlist a ciascuno.
Vero vero, hai detto una cosa buona e giusta. Si potrebbe pensare anche di usare le funzioni predefinite di Python per il bloccaggio delle risorse ai primi thread e, una volta terminato il loro lavoro, il rilascio delle stesse ai thread che vengono dopo. Così facendo questi ultimi
non potranno accedere alle risorse dei primi, almeno fin quando i thread precedenti non avranno terminato il loro lavoro.
 
Il problema di avviare un nuovo thread per ogni riga della wordlist è che diventerà inefficiente appena il numero di righe supera il numero di core del processore fisico (andranno in time-sharing e avviare un thread è un operazione dispendiosa). L'approccio che sfrutta meglio i thread sarebbe dividere la wordlist per il numero di core, avviare tanti thread quanti core ci sono e dare una frazione diversa della wordlist a ciascuno.
In realtà in python non funziona proprio così perché per colpa del GIL il multithreading non può essere parallelo: se hai due threads, l'interprete esegue un po' del codice del primo thread, poi lo blocca ed esegue un po' del codice del secondo thread e così via, ma non viene mai eseguito più di un thread per volta. Se vuoi sfruttare più di un core sei costretto ad usare il multiprocessing che però ha più overheads rispetto al multithreading. Il multithreading di python è un multithreading finto, ma anche il multiprocessing di python è un multiprocessing finto perché non spawna necessariamente un nuovo processo. Non è un linguaggio pensato per essere performante e anche quando si usano questi strumenti non si va tanto lontano.

Nel caso di @k0Br@3390 il multithreading va bene perché in ogni caso il bottleneck di questo bruteforce è sicuramente l'I/O dalla rete che è lentissimo rispetto al resto.
 
In realtà in python non funziona proprio così perché per colpa del GIL il multithreading non può essere parallelo: se hai due threads, l'interprete esegue un po' del codice del primo thread, poi lo blocca ed esegue un po' del codice del secondo thread e così via, ma non viene mai eseguito più di un thread per volta. Se vuoi sfruttare più di un core sei costretto ad usare il multiprocessing che però ha più overheads rispetto al multithreading. Il multithreading di python è un multithreading finto, ma anche il multiprocessing di python è un multiprocessing finto perché non spawna necessariamente un nuovo processo. Non è un linguaggio pensato per essere performante e anche quando si usano questi strumenti non si va tanto lontano.

Nel caso di @k0Br@3390 il multithreading va bene perché in ogni caso il bottleneck di questo bruteforce è sicuramente l'I/O dalla rete che è lentissimo rispetto al resto.
Si, ho scoperto che esistono molte più funzionalità di multithreading in linguaggi più datati come il C/C++. Pensandoci, è piuttosto banale: accade perché la maggior parte dei kernel dei SO sono scritti in parte in assembly e in parte in C/C++, quindi è obbligatorio che questi linguaggi siano più performanti e supportino il multithreading. La cosa che ho trovato più interessante, però, è il meccanismo del threading implicito. Fino a qualche tempo fa era compito del programmatore creare e gestire thread, mentre adesso sono disponibili sistemi che attribuiscono ai compilatori e alle API la capacità di gestire in modo autonomo questi componenti. Utilizzano degli algoritmi euristici per creare i thread in base all'architettura della CPU ed assegnare il numero adeguato di risorse ad ogni thread. @St3ve, @JunkCoder mai sentito parlare di OpenMP? Il compito del programmatore è solo quello di individuare i task da svolgere, poi si occuperà l'API di creare i thread. Pure i thread pool sembrano una soluzione interessante per la gestione implicita dei thread, soprattutto se si parla di richieste di servizi asincrone.