Hydra bruteforce and JSON

4

Estoy teniendo problemas con Hydra y una carga JSON.

La solicitud de inicio de sesión (interceptada con Fiddler), es la siguiente:

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 Respuesta, en caso de una contraseña incorrecta, está realmente vacía debido a que se trata de una Aplicación de una sola página. El servidor devolverá un código de error 404 (No encontrado) o 405 en su lugar. En caso de que las credenciales sean correctas, se procederá a devolver una página 200.

Como puede ver, la solicitud fluye de un cliente a un servicio. En realidad, no hay un formulario en el servicio, toma en cuenta los parámetros rellenados en el cliente (esto es todo en mi máquina local, adaptó el archivo HOSTS). Cuando las credenciales son correctas, se creará una cookie (esta es la primera cookie, no hay ninguna cookie de sesión o algo antes de iniciar sesión).

Ahora, las credenciales se pasan en formato JSON. Mi comando Hydra tiene el siguiente aspecto:

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

Sin embargo, esto devuelve que todas las contraseñas son válidas. ¿Es posible utilizar Hydra con formato JSON y una aplicación de una sola página?

ACTUALIZACIÓN Gracias a la respuesta de Iserni, pude construir el siguiente 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: Tenga en cuenta que no es necesario escapar de dos puntos en los valores del encabezado. De hecho, esto rompe el comando, por lo que no debe escapar de los dos puntos allí.

Intercepté esta solicitud con Wireshark, y se ve exactamente igual a la hecha desde Firefox, excepto por la carga útil de JSON. Hydra crea un cuerpo 'x-www-form-urlencoded'. Si intento codificarlo de esta manera utilizando una solicitud de Firefox (interceptada con fiddler), obtengo un error "no encontrado". Así que de hecho necesito poder crear un tipo de contenido JSON. ¿Es esto posible con Hydra?

Para aclarar las cosas, aquí hay una captura de pantalla de la captura de Wireshark: TodoesexactamenteigualquecuandoserealizaunasolicituddeFirefox,exceptoelencabezadoContent-Typey,porlotanto,tambiénlacargaútildelcuerpo(desdeFirefoxesJSON).

ACTUALIZACIÓN:SOLUCIÓN

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.

El comando anterior funciona, en caso de que adapte la fuente de Hydra de la siguiente manera (para Hydra 7.6): Alrededor de la línea 327 de 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;

Como puede ver, tomé la solución más fea posible (cambiar el valor del encabezado codificado de "x-www-form-urlencoded" a "json". Iserni (vea la respuesta a continuación) sugirió un mejor enfoque, pero tengo algo de sintaxis errores y decidió simplemente codificar el valor json. Además, el tipo de contenido está codificado en varios lugares en el archivo hydra-http-form.c, cámbielo cuando sea necesario para su situación.

Ahora, puedes usar Hydra para aplicar las aplicaciones web bruteforce json.

    
pregunta Michael 13.05.2014 - 11:12
fuente

1 respuesta

3

Si el JSON está bien (ver al final), el problema es probable que los encabezados que ahora envía Hydra no sean los mismos que los del formulario de inicio de sesión de AJAX.

Las principales fuentes de problemas de encabezado (aparte de User-Agent, por supuesto) suelen ser

  • el encabezado Content-Type
  • el encabezado Accept
  • el encabezado Origin
  • el encabezado X-Requested-With
  • Comprobaciones de referencia y CSRF.
  • Cookies,

Muchos marcos, tanto como ayuda para la depuración como como "seguridad", verifican el encabezado XRW y / o las contramedidas CSRF, y varios enrutadores ofrecerán una redirección ( o una página HTTP/1.1 200 OK ) si los parámetros de tipo de contenido y aceptación no son adecuados para ser una solicitud JSON, como debe ser su nombre de usuario,

Las cookies no parecen ser tu problema.

En primer lugar, necesita revisar todos los encabezados que son necesarios, lo que puede hacer utilizando la tecla CURL y marcando un inicio de sesión único (siempre lo mismo).

(Otra comprobación valiosa que se debe ejecutar es interceptar la respuesta del marco a una sola solicitud de Hydra. Supongamos que los errores de Hydra de 200 páginas como el inicio de sesión correcto digan "Error tal y como en la entrada ..."). / p>

Una vez que se han encontrado los encabezados relevantes y sus valores, debes incluirlos en la secuencia de Hydra. Permisos tipográficos, algo así como

"/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"

Observe que la secuencia que usó no parece ser el mismo tipo JSON de su solicitud HTTP ; utiliza comillas simples , pero algunos decodificadores (especialmente PHP json_decode() ) se resistirán. La intercepción POST que usted cita, en su lugar, utiliza comillas dobles

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

ACTUALIZACIÓN sobre el tipo de contenido

He dado un cheque al código fuente de Hydra. Al parecer, Content-Type está codificado de forma rígida cuando el método es POST . (Código Hydra 8.0, archivo 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/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 {
    ...

Soluciones. Hmmm Un hack feo y sucio :

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

... esto producirá un nuevo binario que no enviará un encabezado Content-Type sino un X-Would-Type uno. Si las dos cadenas tienen la misma longitud y los binarios no están firmados o no se ha sumado MD5, debería funcionar. Ahora puedes agregar tu propio encabezado Content-Type , y eso debería pasar.

Sin embargo, no estoy completamente seguro de cómo enviar múltiples con Hydra. Los comandos parecen estar separados por dos puntos, y como los encabezados también contienen dos puntos ...

Una mejor solución

Edite el código para que se lea (cerca de la línea 298 en mi fuente):

  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 {

... para que si suministre un Content-Type de su propia cuenta, no agregue uno por sí mismo.

    
respondido por el LSerni 13.05.2014 - 14:43
fuente

Lea otras preguntas en las etiquetas