aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols
diff options
context:
space:
mode:
authorLuca Deri <deri@ntop.org>2024-10-31 21:20:26 +0100
committerLuca Deri <deri@ntop.org>2024-10-31 21:20:46 +0100
commit412ca8700fc53da705c6aa386c736a400279a614 (patch)
tree39ada41ae2b12ea7abf4e1243a4ae5f73d8bf3c3 /src/lib/protocols
parentbcc1874e581de9d59514248a27f525cb56a0ec31 (diff)
Added HTTP credentials extraction
Diffstat (limited to 'src/lib/protocols')
-rw-r--r--src/lib/protocols/http.c74
1 files changed, 66 insertions, 8 deletions
diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c
index cb146fcc0..1c468165c 100644
--- a/src/lib/protocols/http.c
+++ b/src/lib/protocols/http.c
@@ -108,7 +108,7 @@ static void ndpi_analyze_content_signature(struct ndpi_detection_module_struct *
- ndpi_search_portable_executable
- ndpi_search_shellscript
*/
-
+
if((flow->initial_binary_bytes_len >= 2) && (flow->initial_binary_bytes[0] == 0x4D) && (flow->initial_binary_bytes[1] == 0x5A))
set_risk = 1, msg = "Found DOS/Windows Exe"; /* Win executable */
else if((flow->initial_binary_bytes_len >= 4) && (flow->initial_binary_bytes[0] == 0x7F) && (flow->initial_binary_bytes[1] == 'E')
@@ -224,12 +224,11 @@ static void ndpi_validate_http_content(struct ndpi_detection_module_struct *ndpi
len = packet->payload_packet_len - (double_ret - packet->payload);
- if(ndpi_strnstr((const char *)packet->content_line.ptr, "text/", packet->content_line.len)
+ if(flow->http.is_form
+ || ndpi_strnstr((const char *)packet->content_line.ptr, "text/", packet->content_line.len)
|| ndpi_strnstr((const char *)packet->content_line.ptr, "/json", packet->content_line.len)
- || ndpi_strnstr((const char *)packet->content_line.ptr, "x-www-form-urlencoded", packet->content_line.len)
) {
/* This is supposed to be a human-readeable text file */
-
packet->http_check_content = 1;
if(len >= 8 /* 4 chars for \r\n\r\n and at least 4 charts for content guess */) {
@@ -462,6 +461,7 @@ static void setHttpUserAgent(struct ndpi_flow_struct *flow, char *ua) {
else if(!strcmp(ua, "Windows NT 6.2")) ua = "Windows 8";
else if(!strcmp(ua, "Windows NT 6.3")) ua = "Windows 8.1";
else if(!strcmp(ua, "Windows NT 10.0")) ua = "Windows 10";
+ else if(!strcmp(ua, "Windows NT 11.0")) ua = "Windows 11";
/* Good reference for future implementations:
* https://github.com/ua-parser/uap-core/blob/master/regexes.yaml */
@@ -641,6 +641,42 @@ static void ndpi_http_parse_subprotocol(struct ndpi_detection_module_struct *ndp
flow->http.user_agent && strstr(flow->http.user_agent, "Valve/Steam HTTP Client")) {
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_STEAM, master_protocol, NDPI_CONFIDENCE_DPI);
}
+
+
+ if(flow->http.request_header_observed) {
+ if(flow->http.first_payload_after_header_observed == 0) {
+ /* Skip the last part of the HTTP request */
+ flow->http.first_payload_after_header_observed = 1;
+ } else if(flow->http.is_form && (packet->payload_packet_len > 0)) {
+ /* Response payload */
+ char *dup = ndpi_strndup((const char *)packet->payload, packet->payload_packet_len);
+
+ if(dup) {
+ char *key, *value, *tmp;
+
+ key = strtok_r(dup, "=", &tmp);
+
+ while((key != NULL)
+ && ((flow->http.username == NULL) || (flow->http.password == NULL))) {
+ value = strtok_r(NULL, "&", &tmp);
+
+ if(!value)
+ break;
+
+ if((strcmp(key, "user") == 0) || (strcmp(key, "username") == 0)) {
+ if(!flow->http.username) flow->http.username = ndpi_strdup(value);
+ } else if((strcmp(key, "pwd") == 0) || (strcmp(key, "password") == 0)) {
+ if(!flow->http.password) flow->http.password = ndpi_strdup(value);
+ ndpi_set_risk(flow, NDPI_CLEAR_TEXT_CREDENTIALS, "Found password");
+ }
+
+ key = strtok_r(NULL, "=", &tmp);
+ }
+
+ ndpi_free(dup);
+ }
+ }
+ }
}
/* ************************************************************* */
@@ -986,13 +1022,32 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
}
if(packet->authorization_line.ptr != NULL) {
+ const char *a = NULL, *b = NULL;
+
NDPI_LOG_DBG2(ndpi_struct, "Authorization line found %.*s\n",
packet->authorization_line.len, packet->authorization_line.ptr);
- if(ndpi_strncasestr((const char*)packet->authorization_line.ptr,
- "Basic", packet->authorization_line.len)
- || ndpi_strncasestr((const char*)packet->authorization_line.ptr,
- "Digest", packet->authorization_line.len)) {
+ if((a = ndpi_strncasestr((const char*)packet->authorization_line.ptr,
+ "Basic", packet->authorization_line.len))
+ || (b = ndpi_strncasestr((const char*)packet->authorization_line.ptr,
+ "Digest", packet->authorization_line.len))) {
+ size_t content_len;
+ u_int len = b ? 7 : 6;
+ u_char *content = ndpi_base64_decode((const u_char*)&packet->authorization_line.ptr[len],
+ packet->authorization_line.len - len, &content_len);
+
+ if(content != NULL) {
+ char *double_dot = strchr((char*)content, ':');
+
+ if(double_dot) {
+ double_dot[0] = '\0';
+ flow->http.username = ndpi_strdup((char*)content);
+ flow->http.password = ndpi_strdup(&double_dot[1]);
+ }
+
+ ndpi_free(content);
+ }
+
ndpi_set_risk(flow, NDPI_CLEAR_TEXT_CREDENTIALS,
"Found credentials in HTTP Auth Line");
}
@@ -1013,6 +1068,9 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
packet->content_line.len);
flow->http.request_content_type[packet->content_line.len] = '\0';
}
+
+ if(ndpi_strnstr(flow->http.request_content_type, "x-www-form-urlencoded", packet->content_line.len))
+ flow->http.is_form = 1;
}
} else {
/* Response */