
Libreria Python per Turbo Intruder che aggiunge il supporto per posizioni di payload e tipi di attacco Sniper/Clusterbomb/Pitchfork con generazione di test basata su tag per fuzzing HTTP.

Haptyc è una libreria Python creata per aggiungere il supporto alle posizioni dei payload e i tipi di attacco Sniper/Clusterbomb/Batteringram/Pitchfork in Turbo Intruder. Sebbene Haptyc raggiunga abbastanza bene questi obiettivi, introduce anche un modo più semplice per esprimere le sequenze di test in generale. Sebbene questa libreria sia stata pensata per Turbo Intruder, non ha dipendenze rigide da Turbo Intruder e può essere utilizzata ovunque sia necessaria la generazione di test in un contesto Python. Purtroppo, al momento, poiché Haptyc è stato costruito per un interprete Jython, supporta solo Python 2.7 (tuttavia modifiche future risolveranno questo problema).
I tag Haptyc sono tag che un tester può utilizzare per annotare un payload di input originale. Un tester può usare più tag per circondare parti chiave dei dati in una richiesta HTTP, incapsulandoli come payload posizionale. Quando vengono generati i test, Haptyc analizzerà tutti i tag nel payload originale e genererà test in base alle funzioni associate ai nomi dei tag. Quando Haptyc valuta un tag Haptyc, eseguirà la funzione del tag associato (chiamata Haptyc Transform) per un payload di test da inserire nella posizione del tag corrispondente nella richiesta. Ogni funzione del tag riceverà un argomento data e un argomento state. L'argomento data può contenere i dati interni del tag o qualche altra sequenza di payload di test. L'argomento state è un oggetto di stato associato al tag in cui lo stato può essere memorizzato tra le iterazioni del test. Vediamo un esempio.
Original Payload:
GET /animal/[+GuessAnimal]dog[+end] HTTP/1.1
Haptyc Class & Haptyc Transform:
from haptyc import *
original = "GET /animal/[+GuessAnimal]dog[+end] HTTP/1.1"
class TestLogic(Transform):
@ApplyList(["snake","cat","owl","lion"])
def test_GuessAnimal(self, data, state):
return data + "?original=" + self.inner() + "&attempt=" + str(state.iter)
TestFactory = TestLogic(original)
for test in TestFactory:
print(test)
Tests Generated:
GET /animal/snake?original=dog&attempt=0 HTTP/1.1
GET /animal/cat?original=dog&attempt=1 HTTP/1.1
GET /animal/owl?original=dog&attempt=2 HTTP/1.1
GET /animal/lion?original=dog&attempt=3 HTTP/1.1
Nell'esempio sopra vediamo come si possono esprimere i test in modo semplice usando Haptyc. Prima di tutto viene importata la libreria Haptyc. In secondo luogo abbiamo definito i dati originali con le nostre annotazioni di tag Haptyc (GuessAnimal). Successivamente viene definita la classe TestLogic estesa come classe Transform. All'interno di questa classe, ogni metodo che inizia con test_ verrà registrato come tag Haptyc per la valutazione nel payload originale. Usiamo un decoratore di logica per applicare la logica di stato per questa trasformazione Haptyc. In questo caso usiamo il decoratore @ApplyList(list) per dire a Haptyc di generare un test per ogni elemento nella lista specificata e inserire quell'elemento nella trasformazione Haptyc come argomento data. All'interno della trasformazione restituiamo una versione mutata dei dati da reinserire nella posizione del tag. In questo caso la mutazione è l'elemento della lista come dati concatenati con i dati racchiusi dal tag (dog) e poi concatenati con il valore iter nell'oggetto di stato. Infine il resto del codice Python mostra la creazione dell'oggetto TestFactory e la generazione di tutti i test in un ciclo for. Questo è un esempio di un attacco standard di tipo sniper che prende di mira una singola posizione del payload. Ora diamo un'occhiata ad altri tipi di attacchi.
Original Payload:
GET /animal?type=[%type]dog[%end]&name=[%name]fido[%end] HTTP/1.1
Haptyc Class & Haptyc Transform:
from haptyc import *
original = "GET /animal?type=[%type]dog[%end]&name=[%name]fido[%end] HTTP/1.1"
class TestLogic(Transform):
@ApplyList("snake","cat","owl","lion")
def test_type(self, data, state):
return data
@ApplyList("Frank", "Lisa", "Jin", "Tooth")
def test_name(self, data, state):
return data
TestFactory = TestLogic(original)
for test in TestFactory:
print(test)
Tests Generated:
GET /animal?type=snake&name=Frank HTTP/1.1
GET /animal?type=snake&name=Lisa HTTP/1.1
GET /animal?type=snake&name=Jin HTTP/1.1
GET /animal?type=snake&name=Tooth HTTP/1.1
GET /animal?type=cat&name=Frank HTTP/1.1
GET /animal?type=cat&name=Lisa HTTP/1.1
GET /animal?type=cat&name=Jin HTTP/1.1
GET /animal?type=cat&name=Tooth HTTP/1.1
GET /animal?type=owl&name=Frank HTTP/1.1
GET /animal?type=owl&name=Lisa HTTP/1.1
GET /animal?type=owl&name=Jin HTTP/1.1
GET /animal?type=owl&name=Tooth HTTP/1.1
GET /animal?type=lion&name=Frank HTTP/1.1
GET /animal?type=lion&name=Lisa HTTP/1.1
GET /animal?type=lion&name=Jin HTTP/1.1
GET /animal?type=lion&name=Tooth HTTP/1.1
L'esempio 1 ha mostrato come valutare le trasformazioni in stile sniper usando l'annotazione '+' nel tag [+tag][+end]. L'esempio 2 mostra come possiamo usare 2 trasformazioni/posizioni per condurre un attacco di tipo clusterbomb. Come puoi vedere, usiamo due tag di trasformazione separati chiamati [%type][%end] e [%name][%end]. Il segno '%' dice a Haptyc di valutare queste trasformazioni in stile clusterbomb: per ogni payload nella prima trasformazione, crea un test con il payload della seconda trasformazione. Il numero di test è il numero di test di ogni trasformazione coinvolta moltiplicato tra loro.
Usando lo stesso identico codice Python possiamo passare dallo stile di attacco clusterbomb a pitchfork cambiando '%' in '#'. Gli attacchi in stile pitchfork posizionano i payload delle posizioni tutti in parallelo. Il numero di test è il numero più basso di test tra tutte le trasformazioni coinvolte.
Original Payload:
GET /animal?type=[#type]dog[#end]&name=[#name]fido[#end] HTTP/1.1
Tests Generated:
GET /animal?type=snake&name=Frank HTTP/1.1
GET /animal?type=cat&name=Lisa HTTP/1.1
GET /animal?type=owl&name=Jin HTTP/1.1
GET /animal?type=lion&name=Tooth HTTP/1.1
Original Payload:
GET /animal?type=dog&id=[+idor]0[+end]&process=[@randbool]False[@end] HTTP/1.1
Haptyc Class & Haptyc Transform:
from haptyc import *
import random
original = "GET /animal?type=dog&id=[+idor]0[+end]&process=[@randbool]False[@end] HTTP/1.1"
class TestLogic(Transform):
@ApplyIteration(10)
def test_idor(self, data, state):
return str(state.iter)
def per_randbool(self, data):
return random.choice(["True", "False"])
TestFactory = TestLogic(original)
for test in TestFactory:
print(test)
Tests Generated:
GET /animal?type=dog&id=0&process=False HTTP/1.1
GET /animal?type=dog&id=1&process=True HTTP/1.1
GET /animal?type=dog&id=2&process=False HTTP/1.1
GET /animal?type=dog&id=3&process=True HTTP/1.1
GET /animal?type=dog&id=4&process=False HTTP/1.1
GET /animal?type=dog&id=5&process=True HTTP/1.1
GET /animal?type=dog&id=6&process=False HTTP/1.1
GET /animal?type=dog&id=7&process=True HTTP/1.1
GET /animal?type=dog&id=8&process=False HTTP/1.1
GET /animal?type=dog&id=9&process=False HTTP/1.1