fix: Optimize the code

This commit is contained in:
Nicholas.Ni 2021-07-05 23:25:46 +08:00
commit a218726dbc
2 changed files with 159 additions and 107 deletions

2
.gitignore vendored
View file

@ -14,3 +14,5 @@ pw-inspector
pw-inspector.exe pw-inspector.exe
hydra.restore hydra.restore
*~ *~
.vscode/
build/

View file

@ -9,11 +9,22 @@ char *http_buf = NULL;
#define END_CONDITION_MAX_LEN 100 #define END_CONDITION_MAX_LEN 100
static char end_condition[END_CONDITION_MAX_LEN]; static char end_condition[END_CONDITION_MAX_LEN];
int end_condition_type = -1; int end_condition_type = -1;
int match_status_code = 0;
#define MAX_STATUS_CODE_SIZE 10
int match_status_code[MAX_STATUS_CODE_SIZE];
int32_t webport; int32_t webport;
int32_t http_auth_mechanism = AUTH_UNASSIGNED; int32_t http_auth_mechanism = AUTH_UNASSIGNED;
void freeMemory(void **ptr) {
if (ptr != NULL && *ptr != NULL) {
free(*ptr);
*ptr = NULL;
}
}
#define freeM(p) freeMemory((void **)(&(p)))
int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp, char *type, ptr_header_node ptr_head) { int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp, char *type, ptr_header_node ptr_head) {
char *empty = ""; char *empty = "";
char *login, *pass, *buffer, buffer2[500]; char *login, *pass, *buffer, buffer2[500];
@ -34,7 +45,7 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
buffer_size = strlen(header) + 500; buffer_size = strlen(header) + 500;
if (!(buffer = malloc(buffer_size))) { if (!(buffer = malloc(buffer_size))) {
free(header); freeM(header);
return 3; return 3;
} }
@ -86,8 +97,8 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
fooptr = buffer2; fooptr = buffer2;
result = sasl_digest_md5(fooptr, login, pass, buffer, miscptr, type, webtarget, webport, header); result = sasl_digest_md5(fooptr, login, pass, buffer, miscptr, type, webtarget, webport, header);
if (result == NULL) { if (result == NULL) {
free(buffer); frefreeM(buffer);
free(header); freeM(header);
return 3; return 3;
} }
@ -129,21 +140,21 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
} }
if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
free(buffer); freeM(buffer);
free(header); freeM(header);
return 1; return 1;
} }
// receive challenge // receive challenge
if (http_buf != NULL) if (http_buf != NULL)
free(http_buf); freeM(http_buf);
http_buf = hydra_receive_line(s); http_buf = hydra_receive_line(s);
if (http_buf == NULL) { if (http_buf == NULL) {
if (verbose) if (verbose)
hydra_report(stderr, "[ERROR] Server did not answer\n"); hydra_report(stderr, "[ERROR] Server did not answer\n");
free(buffer); freeM(buffer);
free(header); freeM(header);
return 3; return 3;
} }
@ -165,8 +176,7 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
// recover challenge // recover challenge
from64tobits((char *)buf1, pos); from64tobits((char *)buf1, pos);
free(http_buf); freeM(http_buf);
http_buf = NULL;
// Send response // Send response
buildAuthResponse((tSmbNtlmAuthChallenge *)buf1, (tSmbNtlmAuthResponse *)buf2, 0, login, pass, NULL, NULL); buildAuthResponse((tSmbNtlmAuthChallenge *)buf1, (tSmbNtlmAuthResponse *)buf2, 0, login, pass, NULL, NULL);
@ -198,13 +208,13 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
} }
if (hydra_send(s, buffer, strlen(buffer), 0) < 0) { if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
free(buffer); freeM(buffer);
free(header); freeM(header);
return 1; return 1;
} }
if (http_buf != NULL) if (http_buf != NULL)
free(http_buf); freeM(http_buf);
http_buf = hydra_receive_line(s); http_buf = hydra_receive_line(s);
complete_line = 0; complete_line = 0;
tmpreplybuf[0] = 0; tmpreplybuf[0] = 0;
@ -215,20 +225,20 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
if (tmpreplybuf[0] == 0 && strstr(http_buf, "HTTP/1.") != NULL) { if (tmpreplybuf[0] == 0 && strstr(http_buf, "HTTP/1.") != NULL) {
strncpy(tmpreplybuf, http_buf, sizeof(tmpreplybuf) - 1); strncpy(tmpreplybuf, http_buf, sizeof(tmpreplybuf) - 1);
tmpreplybuf[sizeof(tmpreplybuf) - 1] = 0; tmpreplybuf[sizeof(tmpreplybuf) - 1] = 0;
free(http_buf); freeM(http_buf);
http_buf = hydra_receive_line(s); http_buf = hydra_receive_line(s);
} else if (tmpreplybuf[0] != 0) { } else if (tmpreplybuf[0] != 0) {
complete_line = 1; complete_line = 1;
if ((tmpreplybufptr = malloc(strlen(tmpreplybuf) + strlen(http_buf) + 1)) != NULL) { if ((tmpreplybufptr = malloc(strlen(tmpreplybuf) + strlen(http_buf) + 1)) != NULL) {
strcpy(tmpreplybufptr, tmpreplybuf); strcpy(tmpreplybufptr, tmpreplybuf);
strcat(tmpreplybufptr, http_buf); strcat(tmpreplybufptr, http_buf);
free(http_buf); freeM(http_buf);
http_buf = tmpreplybufptr; http_buf = tmpreplybufptr;
if (debug) if (debug)
printf("http_buf now: %s\n", http_buf); printf("http_buf now: %s\n", http_buf);
} }
} else { } else {
free(http_buf); freeM(http_buf);
http_buf = hydra_receive_line(s); http_buf = hydra_receive_line(s);
} }
} }
@ -238,8 +248,8 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
if (http_buf == NULL) { if (http_buf == NULL) {
if (verbose) if (verbose)
hydra_report(stderr, "[ERROR] Server did not answer\n"); hydra_report(stderr, "[ERROR] Server did not answer\n");
free(buffer); freeM(buffer);
free(header); freeM(header);
return 3; return 3;
} }
@ -249,21 +259,19 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
ptr = ((char *)strchr(http_buf, ' ')); ptr = ((char *)strchr(http_buf, ' '));
if (ptr != NULL) if (ptr != NULL)
ptr++; ptr++;
// check status // check status
if (match_status_code != 0) { if (match_status_code != NULL) {
char *status_code; for (int i = 0; match_status_code[i]; i++) {
memset(status_code, 0, 3); if (match_status_code[i] == atoi(ptr)) {
if (end_condition_type == -1) {
if (debug)
hydra_report(stderr, "Status code condition %d match.\n", match_status_code[i]);
hydra_report_found_host(port, ip, "www", fp);
hydra_completed_pair_found();
for (int i = 0; i < 3; i++) { goto finish;
*(status_code + i) = *(ptr + i); }
}
if (match_status_code == atoi(status_code)) {
if (end_condition == -1) {
if (debug)
hydra_report(stderr, "Status code condition %d match.\n", status_code);
hydra_report_found_host(port, ip, "www", fp);
hydra_completed_pair_found();
} }
} }
} }
@ -284,8 +292,7 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
hydra_completed_pair_found(); hydra_completed_pair_found();
} }
if (http_buf != NULL) { if (http_buf != NULL) {
free(http_buf); freeM(http_buf);
http_buf = NULL;
} }
} else { } else {
if (ptr != NULL && *ptr != '4') if (ptr != NULL && *ptr != '4')
@ -310,8 +317,8 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
if (find_auth) { if (find_auth) {
// free(http_buf); // free(http_buf);
// http_buf = NULL; // http_buf = NULL;
free(buffer); freeM(buffer);
free(header); freeM(header);
return 1; return 1;
} }
} }
@ -319,9 +326,9 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
} }
// free(http_buf); // free(http_buf);
// http_buf = NULL; // http_buf = NULL;
finish:
free(buffer); freeM(buffer);
free(header); freeM(header);
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
return 3; return 3;
@ -447,88 +454,131 @@ int32_t service_http_init(char *ip, int32_t sp, unsigned char options, char *mis
/*POU CODE */ /*POU CODE */
char *misc = (char *)malloc(strlen(miscptr));
memset(misc, '\0', strlen(miscptr));
strcpy(misc, miscptr);
char *delim = ":"; char *delim = ":";
strtok(miscptr, delim); char *p = NULL;
char *p; char *match_text_start = NULL;
memset(match_status_code, '\0', MAX_STATUS_CODE_SIZE);
while ((p = strtok(NULL, delim))) { #if defined __APPLE__ || __linux__ || __unix__
if (strstr(p, "F=") != NULL || strstr(p, "S=") != NULL) { while ((p = strtok_r(NULL, delim, &misc))) {
char *match_text_start = strstr(p, "F="); #endif
if (match_text_start == NULL)
match_text_start = strstr(p, "S=");
if (match_text_start != NULL) { #ifdef _WIN32
if (match_text_start[0] == 'F') while ((p = strtok_s(NULL, delim, &misc))) {
end_condition_type = 0; #endif
else
end_condition_type = 1;
int condition_len = strlen(match_text_start); if (strstr(p, "r=") != NULL || strstr(p, "R=") != NULL) {
memset(end_condition, 0, END_CONDITION_MAX_LEN); if (strlen(p) < 3) {
if (condition_len >= END_CONDITION_MAX_LEN) { hydra_report(stderr, "Invalid status code, eg: 200 or 200|400.");
hydra_report(stderr, "Condition string cannot be bigger than %u.", END_CONDITION_MAX_LEN); free(misc);
misc = NULL;
return -1; return -1;
} }
// copy condition witout starting string (F= or S= 2char)
strncpy(end_condition, match_text_start + 2, condition_len - 2);
if (debug)
hydra_report(stderr, "End condition is %s, mod is %d\n", end_condition, end_condition_type);
if (*(match_text_start - 1) == ' ') char tmp;
match_text_start--; int value, n;
memset(match_text_start, '\0', condition_len); int pos = 0;
if (debug)
hydra_report(stderr, "Modificated options:%s\n", miscptr); p += 2;
} else {
if (debug) while (p) {
hydra_report(stderr, "Condition not found\n"); n = sscanf(p, "%3d%c", &value, &tmp);
if ((n != 1 && tmp != '|') || value > 1000) {
hydra_report(stderr, "Invalid status code, eg: 200 or 200|400.");
free(misc);
return -1;
}
match_status_code[pos++] = value;
if (pos > MAX_STATUS_CODE_SIZE) {
hydra_report(stderr, "Match up to %d status codes.", MAX_STATUS_CODE_SIZE);
free(misc);
return -1;
}
if (n == 1) {
break;
}
p = strchr(p, '|');
if (p) {
++p;
}
}
}
if (strstr(p, "F=") != NULL || strstr(p, "S=") != NULL) {
int size = 0;
if (misc != NULL) {
size += strlen(misc) + 1;
}
size += strlen(p);
match_text_start = (char *)malloc(size);
memset(match_text_start, '\0', strlen(match_text_start));
strcat(match_text_start, p);
if (misc != NULL) {
strcat(match_text_start, ":");
strcat(match_text_start, misc);
}
break;
} }
} }
if (strstr(p, "c=") != NULL || strstr(p, 'C=') != NULL) { if (match_text_start != NULL) {
if (strlen(p) != 2 + 3) { if (match_text_start[0] == 'F')
hydra_report(stderr, "Invalid status code, eg: 200."); end_condition_type = 0;
else
end_condition_type = 1;
int condition_len = strlen(match_text_start);
memset(end_condition, 0, END_CONDITION_MAX_LEN);
if (condition_len >= END_CONDITION_MAX_LEN) {
hydra_report(stderr, "Condition string cannot be bigger than %u.", END_CONDITION_MAX_LEN);
free(misc);
free(match_text_start);
return -1; return -1;
} }
char *status_code; // copy condition witout starting string (F= or S= 2char)
memset(status_code, 0, 3); strncpy(end_condition, match_text_start + 2, condition_len - 2);
if (debug)
hydra_report(stderr, "End condition is %s, mod is %d\n", end_condition, end_condition_type);
strncpy(status_code, p + 2, 3); free(match_text_start);
match_text_start = NULL;
for (int i = 0; i < strlen(status_code); i++) { if (debug)
if (!isdigit(*(status_code + i))) { hydra_report(stderr, "Modificated options:%s\n", miscptr);
hydra_report(stderr, "Invalid status code, eg: 200");
return -1;
}
}
match_status_code = atoi(status_code);
if (debug) {
hydra_report(stdout, "Find match reply status code: %d", match_status_code);
}
} }
}
return 0;
}
void usage_http(const char *service) { return 0;
printf("Module %s requires the page to authenticate.\n" }
"The following parameters are optional:\n"
" (a|A)=auth-type specify authentication mechanism to use: BASIC, " void usage_http(const char *service) {
"NTLM or MD5\n" printf("Module %s requires the page to authenticate.\n"
" (h|H)=My-Hdr\\: foo to send a user defined HTTP header with each " "The following parameters are optional:\n"
"request\n" " (a|A)=auth-type specify authentication mechanism to use: BASIC, "
" (c|C)=check for status code in the HTTP reply. If the reply status code\n" "NTLM or MD5\n"
" matches it, it is judged as successful \n" " (h|H)=My-Hdr\\: foo to send a user defined HTTP header with each "
" (F|S)=check for text in the HTTP reply. S= means if this text is " "request\n"
"found, a\n" " (r|R)=check for status code in the HTTP reply. If the reply status code\n"
" valid account has been found, F= means if this string is " " matches it, it is judged as successful \n"
"present the\n" " (F|S)=check for text in the HTTP reply. S= means if this text is "
" combination is invalid. Note: this must be the last option " "found, a\n"
"supplied.\n" " valid account has been found, F= means if this string is "
"For example: \"/secret\" or \"http://bla.com/foo/bar:H=Cookie\\: " "present the\n"
"sessid=aaaa\" or \"https://test.com:8080/members:A=NTLM\"\n\n", " combination is invalid. Note: this must be the last option "
service); "supplied.\n"
} "For example: \"/secret\" or \"http://bla.com/foo/bar:H=Cookie\\: "
"sessid=aaaa\" or \"https://test.com:8080/members:A=NTLM\"\n\n",
service);
}