Add ability to export decrypted SSL/DTLS PDUs

svn path=/trunk/; revision=50001
This commit is contained in:
Pascal Quantin 2013-06-18 01:13:07 +00:00
parent 3d1115c2bd
commit 458dcb7ea2
7 changed files with 138 additions and 33 deletions

View File

@ -28,6 +28,8 @@
#include <glib.h>
#include <epan/packet.h>
#include <epan/asn1.h>
#include <epan/tap.h>
#include <epan/exported_pdu.h>
#include "packet-ber.h"
#include "packet-credssp.h"
@ -41,6 +43,8 @@
#define TS_SMARTCARD_CREDS 2
static gint creds_type;
static gint exported_pdu_tap = -1;
/* Initialize the protocol and registered fields */
static int proto_credssp = -1;
@ -97,15 +101,27 @@ dissect_credssp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
offset = get_ber_length(tvb, offset, NULL, NULL);
offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
if((ber_class == BER_CLASS_CON) && (tag == 0)) {
offset = get_ber_length(tvb, offset, NULL, NULL);
offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
if((ber_class == BER_CLASS_UNI) && (tag == BER_UNI_TAG_INTEGER)) {
offset = get_ber_length(tvb, offset, &length, NULL);
if((length == 1) && (tvb_get_guint8(tvb, offset) == 2)) {
dissect_credssp(tvb, pinfo, parent_tree);
return TRUE;
}
}
offset = get_ber_length(tvb, offset, NULL, NULL);
offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
if((ber_class == BER_CLASS_UNI) && (tag == BER_UNI_TAG_INTEGER)) {
offset = get_ber_length(tvb, offset, &length, NULL);
if((length == 1) && (tvb_get_guint8(tvb, offset) == 2)) {
if (have_tap_listener(exported_pdu_tap)) {
exp_pdu_data_t *exp_pdu_data;
exp_pdu_data = load_export_pdu_tags(pinfo, "credssp", -1,
(EXP_PDU_TAG_IP_SRC_BIT | EXP_PDU_TAG_IP_DST_BIT | EXP_PDU_TAG_SRC_PORT_BIT |
EXP_PDU_TAG_DST_PORT_BIT | EXP_PDU_TAG_ORIG_FNO_BIT));
exp_pdu_data->tvb_length = tvb_length(tvb);
exp_pdu_data->pdu_tvb = tvb;
tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
}
dissect_credssp(tvb, pinfo, parent_tree);
return TRUE;
}
}
}
}
}
@ -159,6 +175,6 @@ void proto_register_credssp(void) {
void proto_reg_handoff_credssp(void) {
heur_dissector_add("ssl", dissect_credssp_heur, proto_credssp);
exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7);
}

View File

@ -36,6 +36,8 @@
#include <glib.h>
#include <epan/packet.h>
#include <epan/asn1.h>
#include <epan/tap.h>
#include <epan/exported_pdu.h>
#include "packet-ber.h"
#include "packet-credssp.h"
@ -49,6 +51,8 @@
#define TS_SMARTCARD_CREDS 2
static gint creds_type;
static gint exported_pdu_tap = -1;
/* Initialize the protocol and registered fields */
static int proto_credssp = -1;
@ -84,7 +88,7 @@ static int hf_credssp_authInfo = -1; /* T_authInfo */
static int hf_credssp_pubKeyAuth = -1; /* OCTET_STRING */
/*--- End of included file: packet-credssp-hf.c ---*/
#line 54 "../../asn1/credssp/packet-credssp-template.c"
#line 58 "../../asn1/credssp/packet-credssp-template.c"
/* Initialize the subtree pointers */
static gint ett_credssp = -1;
@ -100,7 +104,7 @@ static gint ett_credssp_TSCredentials = -1;
static gint ett_credssp_TSRequest = -1;
/*--- End of included file: packet-credssp-ett.c ---*/
#line 58 "../../asn1/credssp/packet-credssp-template.c"
#line 62 "../../asn1/credssp/packet-credssp-template.c"
/*--- Included file: packet-credssp-fn.c ---*/
@ -328,7 +332,7 @@ static void dissect_TSRequest_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, pro
/*--- End of included file: packet-credssp-fn.c ---*/
#line 60 "../../asn1/credssp/packet-credssp-template.c"
#line 64 "../../asn1/credssp/packet-credssp-template.c"
/*
* Dissect CredSSP PDUs
@ -369,15 +373,27 @@ dissect_credssp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
offset = get_ber_length(tvb, offset, NULL, NULL);
offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
if((ber_class == BER_CLASS_CON) && (tag == 0)) {
offset = get_ber_length(tvb, offset, NULL, NULL);
offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
if((ber_class == BER_CLASS_UNI) && (tag == BER_UNI_TAG_INTEGER)) {
offset = get_ber_length(tvb, offset, &length, NULL);
if((length == 1) && (tvb_get_guint8(tvb, offset) == 2)) {
dissect_credssp(tvb, pinfo, parent_tree);
return TRUE;
}
}
offset = get_ber_length(tvb, offset, NULL, NULL);
offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
if((ber_class == BER_CLASS_UNI) && (tag == BER_UNI_TAG_INTEGER)) {
offset = get_ber_length(tvb, offset, &length, NULL);
if((length == 1) && (tvb_get_guint8(tvb, offset) == 2)) {
if (have_tap_listener(exported_pdu_tap)) {
exp_pdu_data_t *exp_pdu_data;
exp_pdu_data = load_export_pdu_tags(pinfo, "credssp", -1,
(EXP_PDU_TAG_IP_SRC_BIT | EXP_PDU_TAG_IP_DST_BIT | EXP_PDU_TAG_SRC_PORT_BIT |
EXP_PDU_TAG_DST_PORT_BIT | EXP_PDU_TAG_ORIG_FNO_BIT));
exp_pdu_data->tvb_length = tvb_length(tvb);
exp_pdu_data->pdu_tvb = tvb;
tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
}
dissect_credssp(tvb, pinfo, parent_tree);
return TRUE;
}
}
}
}
}
@ -492,7 +508,7 @@ void proto_register_credssp(void) {
"OCTET_STRING", HFILL }},
/*--- End of included file: packet-credssp-hfarr.c ---*/
#line 135 "../../asn1/credssp/packet-credssp-template.c"
#line 151 "../../asn1/credssp/packet-credssp-template.c"
};
/* List of subtrees */
@ -510,7 +526,7 @@ void proto_register_credssp(void) {
&ett_credssp_TSRequest,
/*--- End of included file: packet-credssp-ettarr.c ---*/
#line 141 "../../asn1/credssp/packet-credssp-template.c"
#line 157 "../../asn1/credssp/packet-credssp-template.c"
};
@ -532,6 +548,6 @@ void proto_register_credssp(void) {
void proto_reg_handoff_credssp(void) {
heur_dissector_add("ssl", dissect_credssp_heur, proto_credssp);
exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7);
}

View File

@ -65,6 +65,7 @@
#include <wsutil/file_util.h>
#include <epan/uat.h>
#include <epan/sctpppids.h>
#include <epan/exported_pdu.h>
void proto_register_dtls(void);
@ -85,6 +86,7 @@ static proto_tree *top_tree;
/* Initialize the protocol and registered fields */
static gint dtls_tap = -1;
static gint exported_pdu_tap = -1;
static gint proto_dtls = -1;
static gint hf_dtls_record = -1;
static gint hf_dtls_record_content_type = -1;
@ -998,9 +1000,6 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo,
/* show on info column what we are decoding */
col_append_str(pinfo->cinfo, COL_INFO, "Application Data");
if (!dtls_record_tree)
break;
/* we need dissector information when the selected packet is shown.
* ssl session pointer is NULL at that time, so we can't access
* info cached there*/
@ -1036,6 +1035,19 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo,
ssl_debug_printf("dissect_dtls_record found association %p\n", (void *)association);
ssl_print_data("decrypted app data",appl_data->plain_data.data, appl_data->plain_data.data_len);
if (have_tap_listener(exported_pdu_tap)) {
exp_pdu_data_t *exp_pdu_data;
exp_pdu_data = load_export_pdu_tags(pinfo, dissector_handle_get_dissector_name(association->handle), -1,
(EXP_PDU_TAG_IP_SRC_BIT | EXP_PDU_TAG_IP_DST_BIT | EXP_PDU_TAG_SRC_PORT_BIT |
EXP_PDU_TAG_DST_PORT_BIT | EXP_PDU_TAG_ORIG_FNO_BIT));
exp_pdu_data->tvb_length = tvb_length(next_tvb);
exp_pdu_data->pdu_tvb = next_tvb;
tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
}
dissected = call_dissector_only(association->handle, next_tvb, pinfo, top_tree, NULL);
}
else {
@ -3564,6 +3576,7 @@ proto_reg_handoff_dtls(void)
/* add now dissector to default ports.*/
dtls_parse_uat();
dtls_parse_old_keys();
exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7);
if (initialized == FALSE) {
heur_dissector_add("udp", dissect_dtls_heur, proto_dtls);

View File

@ -31,6 +31,8 @@
#include <epan/conversation.h>
#include <epan/expert.h>
#include <epan/tap.h>
#include <epan/exported_pdu.h>
#include <packet-tcp.h>
/* Initialize the protocol and registered fields */
@ -51,6 +53,8 @@ static int hf_reload_framing_time = -1;
static dissector_handle_t reload_handle;
static gint exported_pdu_tap = -1;
/* Structure containing transaction specific information */
typedef struct _reload_frame_t {
guint32 data_frame;
@ -106,7 +110,7 @@ get_reload_framing_message_length(packet_info *pinfo _U_, tvbuff_t *tvb, int off
static int
dissect_reload_framing_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
dissect_reload_framing_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean from_dtls)
{
proto_item *ti;
proto_tree *reload_framing_tree;
@ -167,6 +171,19 @@ dissect_reload_framing_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
return 0;
}
if (from_dtls && have_tap_listener(exported_pdu_tap)) {
exp_pdu_data_t *exp_pdu_data;
exp_pdu_data = load_export_pdu_tags(pinfo, "reload-framing", -1,
(EXP_PDU_TAG_IP_SRC_BIT | EXP_PDU_TAG_IP_DST_BIT | EXP_PDU_TAG_SRC_PORT_BIT |
EXP_PDU_TAG_DST_PORT_BIT | EXP_PDU_TAG_ORIG_FNO_BIT));
exp_pdu_data->tvb_length = effective_length;
exp_pdu_data->pdu_tvb = tvb;
tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
}
/* The message seems to be a valid RELOAD framing message! */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "RELOAD Frame");
@ -430,13 +447,13 @@ dissect_reload_framing_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
static int
dissect_reload_framing_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
return dissect_reload_framing_message(tvb, pinfo, tree);
return dissect_reload_framing_message(tvb, pinfo, tree, FALSE);
}
static void
dissect_reload_framing_message_no_return(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
dissect_reload_framing_message(tvb, pinfo, tree);
dissect_reload_framing_message(tvb, pinfo, tree, FALSE);
}
static void
@ -455,7 +472,20 @@ dissect_reload_framing_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static gboolean
dissect_reload_framing_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
if (dissect_reload_framing_message(tvb, pinfo, tree) == 0) {
if (dissect_reload_framing_message(tvb, pinfo, tree, FALSE) == 0) {
/*
* It wasn't a valid RELOAD message, and wasn't
* dissected as such.
*/
return FALSE;
}
return TRUE;
}
static gboolean
dissect_reload_framing_heur_dtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
if (dissect_reload_framing_message(tvb, pinfo, tree, TRUE) == 0) {
/*
* It wasn't a valid RELOAD message, and wasn't
* dissected as such.
@ -575,7 +605,9 @@ proto_reg_handoff_reload_framing(void)
heur_dissector_add("udp", dissect_reload_framing_heur, proto_reload_framing);
heur_dissector_add("tcp", dissect_reload_framing_heur, proto_reload_framing);
heur_dissector_add("dtls", dissect_reload_framing_heur, proto_reload_framing);
heur_dissector_add("dtls", dissect_reload_framing_heur_dtls, proto_reload_framing);
exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7);
}
/*

View File

@ -110,6 +110,7 @@
#include "packet-ssl-utils.h"
#include <wsutil/file_util.h>
#include <epan/uat.h>
#include <epan/exported_pdu.h>
static ssldecrypt_assoc_t *sslkeylist_uats = NULL;
static guint nssldecrypt = 0;
@ -128,6 +129,7 @@ gboolean ssl_ignore_mac_failed = FALSE;
/* Initialize the protocol and registered fields */
static gint ssl_tap = -1;
static gint exported_pdu_tap = -1;
static gint proto_ssl = -1;
static gint hf_ssl_record = -1;
static gint hf_ssl_record_content_type = -1;
@ -1387,6 +1389,18 @@ process_ssl_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo,
if (dissector_try_heuristic(ssl_heur_subdissector_list, next_tvb,
pinfo, proto_tree_get_root(tree), NULL)) {
} else {
if (have_tap_listener(exported_pdu_tap)) {
exp_pdu_data_t *exp_pdu_data;
exp_pdu_data = load_export_pdu_tags(pinfo, dissector_handle_get_dissector_name(association->handle), -1,
(EXP_PDU_TAG_IP_SRC_BIT | EXP_PDU_TAG_IP_DST_BIT | EXP_PDU_TAG_SRC_PORT_BIT |
EXP_PDU_TAG_DST_PORT_BIT | EXP_PDU_TAG_ORIG_FNO_BIT));
exp_pdu_data->tvb_length = tvb_length(next_tvb);
exp_pdu_data->pdu_tvb = next_tvb;
tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
}
call_dissector(association->handle, next_tvb, pinfo, proto_tree_get_root(tree));
}
}
@ -6000,6 +6014,7 @@ proto_reg_handoff_ssl(void)
/* parse key list */
ssl_parse_uat();
ssl_parse_old_keys();
exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7);
}
void

View File

@ -1972,6 +1972,16 @@ find_dissector(const char *name)
return (dissector_handle_t)g_hash_table_lookup(registered_dissectors, name);
}
/* Get a dissector name from handle. */
const char *
dissector_handle_get_dissector_name(const dissector_handle_t handle)
{
if (handle == NULL) {
return NULL;
}
return handle->name;
}
/* Create an anonymous handle for a dissector. */
dissector_handle_t
create_dissector_handle(dissector_t dissector, const int proto)

View File

@ -321,6 +321,9 @@ WS_DLL_PUBLIC int dissector_handle_get_protocol_index(const dissector_handle_t h
/* Find a dissector by name. */
WS_DLL_PUBLIC dissector_handle_t find_dissector(const char *name);
/* Get a dissector name from handle. */
WS_DLL_PUBLIC const char *dissector_handle_get_dissector_name(const dissector_handle_t handle);
/* Create an anonymous handle for a dissector. */
WS_DLL_PUBLIC dissector_handle_t create_dissector_handle(dissector_t dissector,
const int proto);