diff options
author | Evan Huus <eapache@gmail.com> | 2014-06-29 08:50:21 -0400 |
---|---|---|
committer | Evan Huus <eapache@gmail.com> | 2014-06-30 21:10:11 +0000 |
commit | f1ff6635a8356e0832350fd806cc3810132b2102 (patch) | |
tree | 841a11722aafad604f40f97be880be559b020c38 /epan | |
parent | 60d0faf9c9bee0defc42d7ad633ae46a8008bd6c (diff) |
Warn about unencrypted HTTP traffic over port 443
At the suggestion of Toralf Förster. This includes an expert info, as well as
making SSL a new-style dissector and rejecting traffic that looks like
unencrypted text.
Change-Id: Ib09ea0d97952330f092590ff3fc6488807cdbb81
Reviewed-on: https://code.wireshark.org/review/2693
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Reviewed-by: Evan Huus <eapache@gmail.com>
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-http.c | 18 | ||||
-rw-r--r-- | epan/dissectors/packet-ssl.c | 27 |
2 files changed, 36 insertions, 9 deletions
diff --git a/epan/dissectors/packet-http.c b/epan/dissectors/packet-http.c index 2cf673c122..056e79a2da 100644 --- a/epan/dissectors/packet-http.c +++ b/epan/dissectors/packet-http.c @@ -135,6 +135,8 @@ static gint ett_http_header_item = -1; static expert_field ei_http_chat = EI_INIT; static expert_field ei_http_chunked_and_length = EI_INIT; static expert_field ei_http_subdissector_failed = EI_INIT; +static expert_field ei_http_ssl_port = EI_INIT; + static dissector_handle_t http_handle; @@ -700,7 +702,7 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo, const guchar *linep, *lineend; int orig_offset; int first_linelen, linelen; - gboolean is_request_or_reply; + gboolean is_request_or_reply, is_ssl = FALSE; gboolean saw_req_resp_or_header; guchar c; http_type_t http_type; @@ -780,6 +782,8 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo, } } + proto_get_frame_protocols(pinfo->layers, NULL, NULL, NULL, NULL, &is_ssl); + stat_info = wmem_new(wmem_packet_scope(), http_info_value_t); stat_info->framenum = pinfo->fd->num; stat_info->response_code = 0; @@ -974,8 +978,6 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo, col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", format_text(firstline, first_linelen)); else col_set_str(pinfo->cinfo, COL_INFO, "Continuation"); - - first_loop = FALSE; } if ((tree) && (http_tree == NULL)) { @@ -983,6 +985,13 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo, http_tree = proto_item_add_subtree(ti, ett_http); } + if (first_loop && !is_ssl && pinfo->ptype == PT_TCP && + (pinfo->srcport == 443 || pinfo->destport == 443)) { + expert_add_info(pinfo, ti, &ei_http_ssl_port); + } + + first_loop = FALSE; + /* * Process this line. */ @@ -1027,10 +1036,8 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo, if (tree && stat_info->http_host && stat_info->request_uri) { proto_item *e_ti; - gboolean is_ssl = FALSE; gchar *uri; - proto_get_frame_protocols(pinfo->layers, NULL, NULL, NULL, NULL, &is_ssl); uri = wmem_strdup_printf(wmem_packet_scope(), "%s://%s%s", is_ssl ? "https" : "http", g_strstrip(wmem_strdup(wmem_packet_scope(), stat_info->http_host)), stat_info->request_uri); @@ -3058,6 +3065,7 @@ proto_register_http(void) { &ei_http_chat, { "http.chat", PI_SEQUENCE, PI_CHAT, "Formatted text", EXPFILL }}, { &ei_http_chunked_and_length, { "http.chunkd_and_length", PI_MALFORMED, PI_WARN, "It is incorrect to specify a content-length header and chunked encoding together.", EXPFILL }}, { &ei_http_subdissector_failed, { "http.subdissector_failed", PI_MALFORMED, PI_NOTE, "HTTP body subdissector failed, trying heuristic subdissector", EXPFILL }}, + { &ei_http_ssl_port, { "http.ssl_port", PI_SECURITY, PI_WARN, "Unencrypted HTTP protocol detected over encrypted port, could indicate a dangerous misconfiguration.", EXPFILL }}, }; /* UAT for header fields */ diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c index 3c82774908..ce0105667a 100644 --- a/epan/dissectors/packet-ssl.c +++ b/epan/dissectors/packet-ssl.c @@ -612,8 +612,8 @@ static gint ssl_looks_like_valid_pct_handshake(tvbuff_t *tvb, /* * Code to actually dissect the packets */ -static void -dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +static int +dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { conversation_t *conversation; @@ -634,6 +634,23 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) ssl_session = NULL; + if (tvb_captured_length(tvb) > 4) { + const guint8 *tmp = tvb_get_ptr(tvb, 0, 4); + if (g_ascii_isprint(tmp[0]) && + g_ascii_isprint(tmp[1]) && + g_ascii_isprint(tmp[2]) && + g_ascii_isprint(tmp[3])) { + /* it is extremely unlikely that real SSL traffic starts with four + * printable ascii characters; this looks like it's unencrypted + * text, so assume it's not ours (SSL does have some unencrypted + * text fields in certain packets, but you'd have to get very + * unlucky with TCP fragmentation to have one of those fields at the + * beginning of a TCP payload at the beginning of the capture where + * reassembly hasn't started yet) */ + return 0; + } + } + ssl_debug_printf("\ndissect_ssl enter frame #%u (%s)\n", pinfo->fd->num, (pinfo->fd->flags.visited)?"already visited":"first time"); /* Track the version using conversations to reduce the @@ -798,7 +815,7 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) ssl_debug_printf(" need_desegmentation: offset = %d, reported_length_remaining = %d\n", offset, tvb_reported_length_remaining(tvb, offset)); tap_queue_packet(ssl_tap, pinfo, GINT_TO_POINTER(proto_ssl)); - return; + return tvb_captured_length(tvb); } /* set up for next record in frame, if any */ @@ -810,6 +827,8 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) ssl_debug_flush(); tap_queue_packet(ssl_tap, pinfo, GINT_TO_POINTER(proto_ssl)); + + return tvb_captured_length(tvb); } static gint @@ -4943,7 +4962,7 @@ proto_register_ssl(void) /* heuristic dissectors for any premable e.g. CredSSP before RDP */ register_heur_dissector_list("ssl", &ssl_heur_subdissector_list); - register_dissector("ssl", dissect_ssl, proto_ssl); + new_register_dissector("ssl", dissect_ssl, proto_ssl); ssl_handle = find_dissector("ssl"); ssl_associations = g_tree_new(ssl_association_cmp); |