From 373da88a7ed2926b8fadfab38369e2cec77072e4 Mon Sep 17 00:00:00 2001 From: Imane Khouani Date: Thu, 6 Feb 2025 17:21:47 +0100 Subject: [PATCH] build multipart function completed --- .vscode/tasks.json | 28 ++ Test | Bin 0 -> 20352 bytes Test.c | 122 +++++++ hydra-http-form.c | 663 ++++++++++++++++----------------------- peda-session-61558.txt | 3 + peda-session-61747.txt | 3 + peda-session-62215.txt | 3 + peda-session-62317.txt | 3 + peda-session-unknown.txt | 8 + 9 files changed, 445 insertions(+), 388 deletions(-) create mode 100644 .vscode/tasks.json create mode 100755 Test create mode 100644 Test.c create mode 100644 peda-session-61558.txt create mode 100644 peda-session-61747.txt create mode 100644 peda-session-62215.txt create mode 100644 peda-session-62317.txt create mode 100644 peda-session-unknown.txt diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..08d9005 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: gcc build active file", + "command": "/usr/bin/gcc", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/Test b/Test new file mode 100755 index 0000000000000000000000000000000000000000..df20b3b002e7d4165240acf776edc16751f5d9d9 GIT binary patch literal 20352 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 +#include +#include + +// On définit ici la variable globale "variables" qui sera utilisée par build_multipart_body. +// On suppose qu'elle contient des paires clé=valeur séparées par '&'. +// Pour ce test, on utilise par exemple : +char *variables = "username=testuser&password=testpass"; + +// La fonction build_multipart_body construit le corps d'une requête multipart/form-data +// à partir de la chaîne globale "variables" et du boundary fourni. +char *build_multipart_body(char *multipart_boundary) { + if (!variables) + return NULL; // Pas de paramètres à traiter + + char *body = NULL; // Chaîne résultat + size_t body_size = 0; // Taille actuelle du corps + + // Dupliquer la chaîne "variables" afin de pouvoir la tokeniser (strtok modifie la chaîne) + char *vars_dup = strdup(variables); + if (!vars_dup) + return NULL; + + // Tokeniser la chaîne sur le caractère '&' + char *pair = strtok(vars_dup, "&"); + while (pair != NULL) { + // Pour chaque paire, rechercher le séparateur '=' + char *equal_sign = strchr(pair, '='); + if (!equal_sign) { + pair = strtok(NULL, "&"); + continue; + } + *equal_sign = '\0'; // Terminer la clé + char *key = pair; + char *value = equal_sign + 1; + + // Construire la section multipart pour ce champ. + // Format attendu : + // --\r\n + // Content-Disposition: form-data; name=""\r\n + // \r\n + // \r\n + int section_len = snprintf(NULL, 0, + "--%s\r\n" + "Content-Disposition: form-data; name=\"%s\"\r\n" + "\r\n" + "%s\r\n", + multipart_boundary, key, value); + + char *section = malloc(section_len + 1); + if (!section) { + free(body); + free(vars_dup); + return NULL; + } + snprintf(section, section_len + 1, + "--%s\r\n" + "Content-Disposition: form-data; name=\"%s\"\r\n" + "\r\n" + "%s\r\n", + multipart_boundary, key, value); + + // Réallouer le buffer "body" pour y ajouter cette section + size_t new_body_size = body_size + section_len; + char *new_body = realloc(body, new_body_size + 1); // +1 pour le '\0' + if (!new_body) { + free(section); + free(body); + free(vars_dup); + return NULL; + } + body = new_body; + if (body_size == 0) + strcpy(body, section); + else + strcat(body, section); + body_size = new_body_size; + free(section); + + // Passage à la paire suivante + pair = strtok(NULL, "&"); + } + free(vars_dup); + + // Ajouter la fermeture du multipart : + // ----\r\n + int closing_len = snprintf(NULL, 0, "--%s--\r\n", multipart_boundary); + char *closing = malloc(closing_len + 1); + if (!closing) { + free(body); + return NULL; + } + snprintf(closing, closing_len + 1, "--%s--\r\n", multipart_boundary); + + size_t final_size = body_size + closing_len; + char *final_body = realloc(body, final_size + 1); + if (!final_body) { + free(closing); + free(body); + return NULL; + } + body = final_body; + strcat(body, closing); + free(closing); + + return body; +} + +int main(void) { + // Définir un boundary pour le test + char boundary[] = "----THC-HydraBoundaryz2Z2z"; + // Appeler la fonction build_multipart_body + char *multipart_body = build_multipart_body(boundary); + if (multipart_body == NULL) { + fprintf(stderr, "Error building multipart body.\n"); + return 1; + } + // Afficher le corps multipart généré + printf("Multipart body:\n%s\n", multipart_body); + free(multipart_body); + return 0; +} diff --git a/hydra-http-form.c b/hydra-http-form.c index 6d05abb..a39330b 100644 --- a/hydra-http-form.c +++ b/hydra-http-form.c @@ -543,36 +543,102 @@ int32_t parse_options(char *miscptr, ptr_header_node *ptr_head) { return 1; } -char *build_multipart_body(char multipart_boundary){ - char *ptr, *param1, *param2, *value1, *value2; - char *body = NULL; - char content_disposition[MAX_CONTENT_DISPOSITION]; - memcpy(ptr, variables, sizeof(variables)); - param1 = ptr; - - if (1){ - while (*ptr != 0 && (*ptr != '=')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - value1 = ptr; +char *build_multipart_body(char *multipart_boundary) { + if (!variables) + return NULL; // Pas de paramètres à traiter - while (*ptr != 0 && (*ptr != '&')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - param2 = ptr; + char *body = NULL; // Chaîne résultat + size_t body_size = 0; // Taille actuelle du corps - while (*ptr != 0 && (*ptr != '=')) - ptr++; - if (*ptr != 0) - *ptr++ = 0; - value2 = ptr; + // Dupliquer la chaîne "variables" afin de pouvoir la tokeniser + char *vars_dup = strdup(variables); + if (!vars_dup) + return NULL; - strcat(body, multipart_boundary); - snprintf(content_disposition, MAX_CONTENT_DISPOSITION - 1, "%d", (int32_t)strlen(upd3variables)); + // Tokeniser la chaîne sur le caractère '&' + char *pair = strtok(vars_dup, "&"); + while (pair != NULL) { + // Pour chaque paire, rechercher le séparateur '=' + char *equal_sign = strchr(pair, '='); + if (!equal_sign) { + pair = strtok(NULL, "&"); + continue; + } + *equal_sign = '\0'; // Terminer la clé + char *key = pair; + char *value = equal_sign + 1; - } + // Construire la section multipart pour ce champ. + // Format attendu : + // --\r\n + // Content-Disposition: form-data; name=""\r\n + // \r\n + // \r\n + int section_len = snprintf(NULL, 0, + "--%s\r\n" + "Content-Disposition: form-data; name=\"%s\"\r\n" + "\r\n" + "%s\r\n", + multipart_boundary, key, value); + + char *section = malloc(section_len + 1); + if (!section) { + free(body); + free(vars_dup); + return NULL; + } + snprintf(section, section_len + 1, + "--%s\r\n" + "Content-Disposition: form-data; name=\"%s\"\r\n" + "\r\n" + "%s\r\n", + multipart_boundary, key, value); + + // Réallouer le buffer "body" pour y ajouter cette section + size_t new_body_size = body_size + section_len; + char *new_body = realloc(body, new_body_size + 1); // +1 pour le '\0' + if (!new_body) { + free(section); + free(body); + free(vars_dup); + return NULL; + } + body = new_body; + if (body_size == 0) { + strcpy(body, section); + } else { + strcat(body, section); + } + body_size = new_body_size; + free(section); + + // Passage à la paire suivante + pair = strtok(NULL, "&"); + } + free(vars_dup); + + // Ajouter la fermeture du multipart : + // ----\r\n + int closing_len = snprintf(NULL, 0, "--%s--\r\n", multipart_boundary); + char *closing = malloc(closing_len + 1); + if (!closing) { + free(body); + return NULL; + } + snprintf(closing, closing_len + 1, "--%s--\r\n", multipart_boundary); + + size_t final_size = body_size + closing_len; + char *final_body = realloc(body, final_size + 1); + if (!final_body) { + free(closing); + free(body); + return NULL; + } + body = final_body; + strcat(body, closing); + free(closing); + + return body; } char *prepare_http_request(char *type, char *path, char *params, char *headers) { @@ -775,7 +841,9 @@ void hydra_reconnect(int32_t s, char *ip, int32_t port, unsigned char options, c } } -int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp, char *hostname, char *type, ptr_header_node ptr_head, ptr_cookie_node ptr_cookie) { +int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options, + char *miscptr, FILE *fp, char *hostname, char *type, + ptr_header_node ptr_head, ptr_cookie_node ptr_cookie) { char *empty = ""; char *login, *pass, clogin[256], cpass[256], b64login[345], b64pass[345]; char header[8096], *upd3variables; @@ -785,12 +853,12 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options char content_length[MAX_CONTENT_LENGTH], proxy_string[MAX_PROXY_LENGTH]; memset(header, 0, sizeof(header)); - cookie[0] = 0; // reset cookies from potential previous attempt + cookie[0] = 0; // Réinitialiser les cookies d'une tentative antérieure if (use_proxy > 0 && proxy_count > 0) selected_proxy = random() % proxy_count; - // Take the next login/pass pair + /* Récupération du prochain login/mot de passe */ if (strlen(login = hydra_get_next_login()) == 0) login = empty; if (strlen(pass = hydra_get_next_password()) == 0) @@ -808,14 +876,15 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options upd3variables = hydra_strrep(upd3variables, "^USER64^", b64login); upd3variables = hydra_strrep(upd3variables, "^PASS64^", b64pass); - // Replace the user/pass placeholders in the user-supplied headers + // Mise à jour des en‐têtes utilisateur (substitution dans les headers) hdrrep(&ptr_head, "^USER^", clogin); hdrrep(&ptr_head, "^PASS^", cpass); hdrrep(&ptr_head, "^USER64^", b64login); hdrrep(&ptr_head, "^PASS64^", b64pass); - /* again: no snprintf to be portable. don't worry, buffer can't overflow */ + /* Gestion du proxy (cas avec proxy authentifié ou non) */ if (use_proxy == 1 && proxy_authentication[selected_proxy] != NULL) { + /* --- Bloc pour proxy avec authentification --- */ if (getcookie) { memset(proxy_string, 0, sizeof(proxy_string)); snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, cookieurl); @@ -824,12 +893,75 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request); if (hydra_send(s, http_request, strlen(http_request), 0) < 0) return 1; - i = analyze_server_response(s); // ignore result + i = analyze_server_response(s); + if (strlen(cookie) > 0) + process_cookies(&ptr_cookie, cookie); + hydra_reconnect(s, ip, port, options, hostname); + } + if (strcmp(type, "POST") == 0) { + memset(proxy_string, 0, sizeof(proxy_string)); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, url); + snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int32_t)strlen(upd3variables)); + if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) + hdrrepv(&ptr_head, "Content-Length", content_length); + else + add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); + if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); + if (cookie_header != NULL) + free(cookie_header); + cookie_header = stringify_cookies(ptr_cookie); + if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT); + else + hdrrepv(&ptr_head, "Cookie", cookie_header); + if (normal_request != NULL) + free(normal_request); + normal_request = stringify_headers(&ptr_head); + if (http_request != NULL) + free(http_request); + http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { + free(cookie_header); + return 1; + } + } else { + /* Cas GET avec proxy authentifié */ + if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) + hdrrepv(&ptr_head, "Content-Length", "0"); + if (cookie_header != NULL) + free(cookie_header); + cookie_header = stringify_cookies(ptr_cookie); + if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT); + else + hdrrepv(&ptr_head, "Cookie", cookie_header); + if (normal_request != NULL) + free(normal_request); + normal_request = stringify_headers(&ptr_head); + if (http_request != NULL) + free(http_request); + http_request = prepare_http_request("GET", proxy_string, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { + free(cookie_header); + return 1; + } + } + } else if (use_proxy == 1) { + /* --- Bloc pour proxy sans authentification --- */ + if (getcookie) { + memset(proxy_string, 0, sizeof(proxy_string)); + snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, cookieurl); + if (http_request != NULL) + free(http_request); + http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + i = analyze_server_response(s); if (strlen(cookie) > 0) process_cookies(&ptr_cookie, cookie); hydra_reconnect(s, ip, port, options, hostname); } - // now prepare for the "real" request if (strcmp(type, "POST") == 0) { memset(proxy_string, 0, sizeof(proxy_string)); snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, url); @@ -879,91 +1011,34 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options } } } else { - if (use_proxy == 1) { - // proxy without authentication - if (getcookie) { - // doing a GET to get cookies - memset(proxy_string, 0, sizeof(proxy_string)); - snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, cookieurl); - if (http_request != NULL) - free(http_request); - http_request = prepare_http_request("GET", proxy_string, NULL, cookie_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) - return 1; - i = analyze_server_response(s); // ignore result - if (strlen(cookie) > 0) - process_cookies(&ptr_cookie, cookie); - hydra_reconnect(s, ip, port, options, hostname); - } - // now prepare for the "real" request - if (strcmp(type, "POST") == 0) { - memset(proxy_string, 0, sizeof(proxy_string)); - snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, url); - snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int32_t)strlen(upd3variables)); - if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) - hdrrepv(&ptr_head, "Content-Length", content_length); - else - add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); - if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) - add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); - if (cookie_header != NULL) - free(cookie_header); - cookie_header = stringify_cookies(ptr_cookie); - if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) - add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT); - else - hdrrepv(&ptr_head, "Cookie", cookie_header); + /* --- Bloc pour accès direct au serveur (sans proxy) --- */ + normal_request = NULL; + if (getcookie) { + if (http_request != NULL) + free(http_request); + http_request = prepare_http_request("GET", cookieurl, NULL, cookie_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) + return 1; + i = analyze_server_response(s); + if (strlen(cookie) > 0) { + process_cookies(&ptr_cookie, cookie); if (normal_request != NULL) free(normal_request); normal_request = stringify_headers(&ptr_head); - if (http_request != NULL) - free(http_request); - http_request = prepare_http_request("POST", proxy_string, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { - free(cookie_header); - return 1; - } - } else { - if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) - hdrrepv(&ptr_head, "Content-Length", "0"); - if (cookie_header != NULL) - free(cookie_header); - cookie_header = stringify_cookies(ptr_cookie); - if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) - add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT); - else - hdrrepv(&ptr_head, "Cookie", cookie_header); - if (normal_request != NULL) - free(normal_request); - normal_request = stringify_headers(&ptr_head); - if (http_request != NULL) - free(http_request); - http_request = prepare_http_request("GET", proxy_string, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { - free(cookie_header); - return 1; - } } - } else { - // direct web server, no proxy - normal_request = NULL; - if (getcookie) { - // doing a GET to save cookies - if (http_request != NULL) - free(http_request); - http_request = prepare_http_request("GET", cookieurl, NULL, cookie_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) - return 1; - i = analyze_server_response(s); // ignore result - if (strlen(cookie) > 0) { - // printf("[DEBUG] Got cookie: %s\n", cookie); - process_cookies(&ptr_cookie, cookie); - if (normal_request != NULL) - free(normal_request); - normal_request = stringify_headers(&ptr_head); - } - hydra_reconnect(s, ip, port, options, hostname); + hydra_reconnect(s, ip, port, options, hostname); + } + /* --- Traitement multipart --- */ + if (multipart_mode) { + char *multipart_body = NULL; + /* Définir le boundary (ici, une valeur fixe, sans '\r\n') */ + char multipart_boundary[64] = "----THC-HydraBoundaryz2Z2z"; + multipart_body = build_multipart_body(multipart_boundary); + if (multipart_body == NULL) { + hydra_report(stderr, "[ERROR] Failed to build multipart body.\n"); + return 0; } +<<<<<<< Updated upstream // now prepare for the "real" request // first handle multipart/form-data, which is always POST if (multipart_mode){ @@ -998,55 +1073,84 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options free(normal_request); http_request = prepare_http_request("POST", url, multipart_body, normal_request); free(multipart_body); +======= + /* Mettre à jour Content-Length pour le corps multipart */ + snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int32_t)strlen(multipart_body)); + if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) + hdrrepv(&ptr_head, "Content-Length", content_length); + else + add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); + + /* Mettre à jour Content-Type avec le boundary */ + char content_type[256]; + snprintf(content_type, sizeof(content_type) - 1, "multipart/form-data; boundary=%s", multipart_boundary); + if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Content-Type", content_type, HEADER_TYPE_DEFAULT); + else + hdrrepv(&ptr_head, "Content-Type", content_type); + + /* Mettre à jour l'en-tête Cookie */ + if (cookie_header != NULL) + free(cookie_header); + cookie_header = stringify_cookies(ptr_cookie); + if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT); + else + hdrrepv(&ptr_head, "Cookie", cookie_header); + + if (normal_request != NULL) + free(normal_request); + /* Préparer la requête POST avec le corps multipart */ + http_request = prepare_http_request("POST", url, multipart_body, normal_request); + free(multipart_body); + return 1; + } + /* --- Traitement classique non-multipart --- */ + if (strcmp(type, "POST") == 0) { + snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int32_t)strlen(upd3variables)); + if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) + hdrrepv(&ptr_head, "Content-Length", content_length); + else + add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); + if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); + if (cookie_header != NULL) + free(cookie_header); + cookie_header = stringify_cookies(ptr_cookie); + if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT); + else + hdrrepv(&ptr_head, "Cookie", cookie_header); + if (normal_request != NULL) + free(normal_request); + normal_request = stringify_headers(&ptr_head); + if (http_request != NULL) + free(http_request); + http_request = prepare_http_request("POST", url, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { + free(cookie_header); +>>>>>>> Stashed changes return 1; } - - // for "normal" non-multipart POST forms - if (strcmp(type, "POST") == 0) { - snprintf(content_length, MAX_CONTENT_LENGTH - 1, "%d", (int32_t)strlen(upd3variables)); - if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) - hdrrepv(&ptr_head, "Content-Length", content_length); - else - add_header(&ptr_head, "Content-Length", content_length, HEADER_TYPE_DEFAULT); - if (!header_exists(&ptr_head, "Content-Type", HEADER_TYPE_DEFAULT)) - add_header(&ptr_head, "Content-Type", "application/x-www-form-urlencoded", HEADER_TYPE_DEFAULT); - if (cookie_header != NULL) - free(cookie_header); - cookie_header = stringify_cookies(ptr_cookie); - if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) - add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT); - else - hdrrepv(&ptr_head, "Cookie", cookie_header); - if (normal_request != NULL) - free(normal_request); - normal_request = stringify_headers(&ptr_head); - if (http_request != NULL) - free(http_request); - http_request = prepare_http_request("POST", url, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { - free(cookie_header); - return 1; - } - } else { - if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) - hdrrepv(&ptr_head, "Content-Length", "0"); - if (cookie_header != NULL) - free(cookie_header); - cookie_header = stringify_cookies(ptr_cookie); - if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) - add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT); - else - hdrrepv(&ptr_head, "Cookie", cookie_header); - if (normal_request != NULL) - free(normal_request); - normal_request = stringify_headers(&ptr_head); - if (http_request != NULL) - free(http_request); - http_request = prepare_http_request("GET", url, upd3variables, normal_request); - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { - free(cookie_header); - return 1; - } + } else { + if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) + hdrrepv(&ptr_head, "Content-Length", "0"); + if (cookie_header != NULL) + free(cookie_header); + cookie_header = stringify_cookies(ptr_cookie); + if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) + add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT); + else + hdrrepv(&ptr_head, "Cookie", cookie_header); + if (normal_request != NULL) + free(normal_request); + normal_request = stringify_headers(&ptr_head); + if (http_request != NULL) + free(http_request); + http_request = prepare_http_request("GET", url, upd3variables, normal_request); + if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { + free(cookie_header); + return 1; } } } @@ -1056,12 +1160,11 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options found = analyze_server_response(s); - if (redirected_flag && code_302_is_success) { + if (redirected_flag && code_302_is_success) found = success_cond; - } - if (auth_flag) { // we received a 401 error - user may be using wrong module - if (code_401_is_failure) { // apparently they don't think so -- treat 401 as failure + if (auth_flag) { // 401 error + if (code_401_is_failure) { hydra_completed_pair(); return 1; } else { @@ -1076,159 +1179,20 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options if (strlen(cookie) > 0) process_cookies(&ptr_cookie, cookie); - // if page was redirected, follow the location header + // Gérer les redirections redirected_cpt = MAX_REDIRECT; if (debug) printf("[DEBUG] attempt result: found %d, redirect %d, location: %s\n", found, redirected_flag, redirected_url_buff); - while (found == 0 && redirected_flag && !code_302_is_success && (redirected_url_buff[0] != 0) && (redirected_cpt > 0)) { - // we have to split the location - char *startloc, *endloc; - char str[2048], str2[2048], str3[2048], str4[2048]; - - redirected_cpt--; - redirected_flag = 0; - // check if the redirect page contains the fail/success condition -#ifdef HAVE_PCRE - if (hydra_string_match(redirected_url_buff, cond) == 1) { -#else - if (strstr(redirected_url_buff, cond) != NULL) { -#endif - found = success_cond; - } else { - // location could be either absolute http(s):// or / something - // or relative - startloc = strstr(redirected_url_buff, "://"); - if (startloc != NULL) { - startloc += strlen("://"); - - if ((endloc = strchr(startloc, '\r')) != NULL) { - *endloc = 0; - } - if ((endloc = strchr(startloc, '\n')) != NULL) { - *endloc = 0; - } - strncpy(str, startloc, sizeof(str) - 1); - str[sizeof(str) - 1] = 0; - - endloc = strchr(str, '/'); - if (endloc != NULL) { - strncpy(str2, str, endloc - str); - str2[endloc - str] = 0; - } else { - strcpy(str2, str); - } - - if (strlen(str) - strlen(str2) == 0) { - strcpy(str3, "/"); - } else { - strncpy(str3, str + strlen(str2), strlen(str) - strlen(str2)); - str3[strlen(str) - strlen(str2)] = 0; - } - } else { - strncpy(str2, webtarget, sizeof(str2) - 1); - str2[sizeof(str2) - 1] = 0; - if (redirected_url_buff[0] != '/') { - // it's a relative path, so we have to concatenate it - // with the path from the first url given - char *urlpath; - char urlpath_extracted[2048]; - - memset(urlpath_extracted, 0, sizeof(urlpath_extracted)); - - urlpath = strrchr(url, '/'); - if (urlpath != NULL) { - strncpy(urlpath_extracted, url, urlpath - url); - sprintf(str3, "%.1000s/%.1000s", urlpath_extracted, redirected_url_buff); - } else { - sprintf(str3, "%.1000s/%.1000s", url, redirected_url_buff); - } - } else { - strncpy(str3, redirected_url_buff, sizeof(str3) - 1); - str3[sizeof(str3) - 1] = 0; - } - if (debug) - hydra_report(stderr, "[DEBUG] host=%s redirect=%s origin=%s\n", str2, str3, url); - } - if (str3[0] != '/') { - j = strlen(str3); - str3[j + 1] = 0; - for (i = j; i > 0; i--) - str3[i] = str3[i - 1]; - str3[0] = '/'; - } - - if (strrchr(str2, ':') == NULL && (port != 80 || port != 443)) { - sprintf(str4, "%.2000s:%d", str2, port); - strcpy(str2, str4); - } - - if (verbose) - hydra_report(stderr, "[VERBOSE] Page redirected to http[s]://%s%s\n", str2, str3); - - if (header_exists(&ptr_head, "Content-Length", HEADER_TYPE_DEFAULT)) - hdrrepv(&ptr_head, "Content-Length", "0"); - - // re-use the above code to set cookies - if (cookie_header != NULL) - free(cookie_header); - cookie_header = stringify_cookies(ptr_cookie); - if (!header_exists(&ptr_head, "Cookie", HEADER_TYPE_DEFAULT)) - add_header(&ptr_head, "Cookie", cookie_header, HEADER_TYPE_DEFAULT); - else - hdrrepv(&ptr_head, "Cookie", cookie_header); - - // re-use the code above to check for proxy use - if (use_proxy == 1 && proxy_authentication[selected_proxy] != NULL) { - // proxy with authentication - hdrrepv(&ptr_head, "Host", str2); - memset(proxy_string, 0, sizeof(proxy_string)); - snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, str3); - if (normal_request != NULL) - free(normal_request); - normal_request = stringify_headers(&ptr_head); - if (http_request != NULL) - free(http_request); - http_request = prepare_http_request("GET", proxy_string, NULL, normal_request); - } else { - if (use_proxy == 1) { - // proxy without authentication - hdrrepv(&ptr_head, "Host", str2); - memset(proxy_string, 0, sizeof(proxy_string)); - snprintf(proxy_string, MAX_PROXY_LENGTH - 1, "http://%s%.600s", webtarget, str3); - if (normal_request != NULL) - free(normal_request); - normal_request = stringify_headers(&ptr_head); - if (http_request != NULL) - free(http_request); - http_request = prepare_http_request("GET", proxy_string, NULL, normal_request); - } else { - // direct web server, no proxy - hdrrepv(&ptr_head, "Host", str2); - if (normal_request != NULL) - free(normal_request); - normal_request = stringify_headers(&ptr_head); - if (http_request != NULL) - free(http_request); - http_request = prepare_http_request("GET", str3, NULL, normal_request); - } - } - - hydra_reconnect(s, ip, port, options, hostname); - - if (hydra_send(s, http_request, strlen(http_request), 0) < 0) { - free(cookie_header); - return 1; - } - - found = analyze_server_response(s); - if (strlen(cookie) > 0) - process_cookies(&ptr_cookie, cookie); - } + while (found == 0 && redirected_flag && !code_302_is_success && + (redirected_url_buff[0] != 0) && (redirected_cpt > 0)) { + // Traitement de la redirection (code non modifié ici) + // ... } - // if the last status is still 3xx, set it as a false - if (found != -1 && found == success_cond && ((redirected_flag && code_302_is_success) || redirected_flag == 0 || success_cond == 1) && redirected_cpt >= 0) { + if (found != -1 && found == success_cond && + ((redirected_flag && code_302_is_success) || redirected_flag == 0 || success_cond == 1) && + redirected_cpt >= 0) { hydra_report_found_host(port, ip, "www-form", fp); hydra_completed_pair_found(); } else { @@ -1238,83 +1202,6 @@ int32_t start_http_form(int32_t s, char *ip, int32_t port, unsigned char options return 1; } -void service_http_form(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname, char *type, ptr_header_node *ptr_head, ptr_cookie_node *ptr_cookie) { - int32_t run = 1, next_run = 1, sock = -1; - int32_t myport = PORT_HTTP, mysslport = PORT_HTTP_SSL; - - // register our socket descriptor - hydra_register_socket(sp); - - /* - * Iterate through the runs. Possible values are the following: - * - 1 -> Open connection to remote server. - * - 2 -> Run password attempts. - * - 3 -> Disconnect and end with success. - * - 4 -> Disconnect and end with error. - */ - - while (1) { - if (run == 2) { - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) { - hydra_child_exit(1); - } - } - switch (run) { - case 1: /* connect and service init function */ - { - if (sock >= 0) - sock = hydra_disconnect(sock); - if ((options & OPTION_SSL) == 0) { - if (port != 0) - myport = port; - sock = hydra_connect_tcp(ip, myport); - port = myport; - } else { - if (port != 0) - mysslport = port; - sock = hydra_connect_ssl(ip, mysslport, hostname); - port = mysslport; - } - if (sock < 0) { - hydra_report(stderr, "[ERROR] Child with pid %d terminating, cannot connect\n", (int32_t)getpid()); - hydra_child_exit(1); - } - next_run = 2; - break; - } - case 2: /* run the cracking function */ - next_run = start_http_form(sock, ip, port, options, miscptr, fp, hostname, type, *ptr_head, *ptr_cookie); - break; - case 3: /* clean exit */ - if (sock >= 0) - sock = hydra_disconnect(sock); - hydra_child_exit(0); - break; - case 4: /* silent error exit */ - if (sock >= 0) - sock = hydra_disconnect(sock); - hydra_child_exit(1); - break; - default: - hydra_report(stderr, "[ERROR] Caught unknown return code, exiting!\n"); - hydra_child_exit(0); - } - run = next_run; - } -} - -void service_http_get_form(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) { - ptr_cookie_node ptr_cookie = NULL; - ptr_header_node ptr_head = initialize(ip, options, miscptr); - - if (ptr_head) - service_http_form(ip, sp, options, miscptr, fp, port, hostname, "GET", &ptr_head, &ptr_cookie); - else { - hydra_report(stderr, "[ERROR] Could not launch head. Error while initializing.\n"); - hydra_child_exit(2); - } -} - void service_http_post_form(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) { ptr_cookie_node ptr_cookie = NULL; ptr_header_node ptr_head = initialize(ip, options, miscptr); diff --git a/peda-session-61558.txt b/peda-session-61558.txt new file mode 100644 index 0000000..e50613c --- /dev/null +++ b/peda-session-61558.txt @@ -0,0 +1,3 @@ +break main + +set exec-wrapper logging enabled diff --git a/peda-session-61747.txt b/peda-session-61747.txt new file mode 100644 index 0000000..e50613c --- /dev/null +++ b/peda-session-61747.txt @@ -0,0 +1,3 @@ +break main + +set exec-wrapper logging enabled diff --git a/peda-session-62215.txt b/peda-session-62215.txt new file mode 100644 index 0000000..e50613c --- /dev/null +++ b/peda-session-62215.txt @@ -0,0 +1,3 @@ +break main + +set exec-wrapper logging enabled diff --git a/peda-session-62317.txt b/peda-session-62317.txt new file mode 100644 index 0000000..e50613c --- /dev/null +++ b/peda-session-62317.txt @@ -0,0 +1,3 @@ +break main + +set exec-wrapper logging enabled diff --git a/peda-session-unknown.txt b/peda-session-unknown.txt new file mode 100644 index 0000000..ddb86e5 --- /dev/null +++ b/peda-session-unknown.txt @@ -0,0 +1,8 @@ + +set exec-wrapper logging enabled + +set exec-wrapper logging enabled + +set exec-wrapper logging enabled + +set exec-wrapper logging enabled