diff options
author | Graeme Lunt <graeme.lunt@smhs.co.uk> | 2011-09-30 15:21:16 +0000 |
---|---|---|
committer | Graeme Lunt <graeme.lunt@smhs.co.uk> | 2011-09-30 15:21:16 +0000 |
commit | 779206012c76b7e8ba6e69239ce9fb653ada3150 (patch) | |
tree | 0b106c207b583bf2793678d0ad4c667139e9e024 | |
parent | 89b307973a3b9820f94cca837ad65dc8196e286f (diff) |
Microsoft Credential Security Support Provider (CredSSP) support.
Used by direct approach RDP for NTLMSSP authentication under SSL.
svn path=/trunk/; revision=39196
-rw-r--r-- | asn1/credssp/CredSSP.asn | 46 | ||||
-rw-r--r-- | asn1/credssp/Makefile.am | 26 | ||||
-rw-r--r-- | asn1/credssp/Makefile.common | 50 | ||||
-rw-r--r-- | asn1/credssp/Makefile.nmake | 29 | ||||
-rw-r--r-- | asn1/credssp/credssp.cnf | 57 | ||||
-rw-r--r-- | asn1/credssp/packet-credssp-template.c | 166 | ||||
-rw-r--r-- | asn1/credssp/packet-credssp-template.h | 34 | ||||
-rw-r--r-- | configure.in | 1 | ||||
-rw-r--r-- | epan/CMakeLists.txt | 1 | ||||
-rw-r--r-- | epan/dissectors/Makefile.common | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-credssp.c | 539 | ||||
-rw-r--r-- | epan/dissectors/packet-credssp.h | 47 | ||||
-rw-r--r-- | epan/dissectors/packet-ntlmssp.c | 19 | ||||
-rw-r--r-- | epan/dissectors/packet-ssl.c | 10 |
14 files changed, 1024 insertions, 2 deletions
diff --git a/asn1/credssp/CredSSP.asn b/asn1/credssp/CredSSP.asn new file mode 100644 index 0000000000..61e34c2193 --- /dev/null +++ b/asn1/credssp/CredSSP.asn @@ -0,0 +1,46 @@ +-- $Id$ +-- +-- Derived from http://download.microsoft.com/download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/%5BMS-CSSP%5D.pdf + +CredSSP DEFINITIONS EXPLICIT TAGS ::= + +BEGIN + +NegoData ::= SEQUENCE OF SEQUENCE { + negoToken [0] OCTET STRING +} + +TSPasswordCreds ::= SEQUENCE { + domainName [0] OCTET STRING, + userName [1] OCTET STRING, + password [2] OCTET STRING +} + +TSCspDataDetail ::= SEQUENCE { + keySpec [0] INTEGER, + cardName [1] OCTET STRING OPTIONAL, + readerName [2] OCTET STRING OPTIONAL, + containerName [3] OCTET STRING OPTIONAL, + cspName [4] OCTET STRING OPTIONAL +} + +TSSmartCardCreds ::= SEQUENCE { + pin [0] OCTET STRING, + cspData [1] TSCspDataDetail, + userHint [2] OCTET STRING OPTIONAL, + domainHint [3] OCTET STRING OPTIONAL +} + +TSCredentials ::= SEQUENCE { + credType [0] INTEGER, + credentials [1] OCTET STRING +} + +TSRequest ::= SEQUENCE { + version [0] INTEGER, + negoTokens [1] NegoData OPTIONAL, + authInfo [2] OCTET STRING OPTIONAL, + pubKeyAuth [3] OCTET STRING OPTIONAL +} + +END diff --git a/asn1/credssp/Makefile.am b/asn1/credssp/Makefile.am new file mode 100644 index 0000000000..462af31e88 --- /dev/null +++ b/asn1/credssp/Makefile.am @@ -0,0 +1,26 @@ +# $Id$ +# +# +# Wireshark - Network traffic analyzer +# By Gerald Combs <gerald@wireshark.org> +# Copyright 1998 Gerald Combs +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +include ../Makefile.preinc +include Makefile.common +include ../Makefile.inc + diff --git a/asn1/credssp/Makefile.common b/asn1/credssp/Makefile.common new file mode 100644 index 0000000000..24ead6d71f --- /dev/null +++ b/asn1/credssp/Makefile.common @@ -0,0 +1,50 @@ +# $Id$ +# +# +# Wireshark - Network traffic analyzer +# By Gerald Combs <gerald@wireshark.org> +# Copyright 1998 Gerald Combs +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +PROTOCOL_NAME=credssp + +DISSECTOR_FILES=packet-$(PROTOCOL_NAME).c \ + packet-$(PROTOCOL_NAME).h + + +EXPORT_FILES = $(PROTOCOL_NAME)-exp.cnf + +EXT_ASN_FILE_LIST = + +ASN_FILE_LIST = CredSSP.asn + +# The packet-$(PROTOCOL_NAME)-template.h and $(PROTOCOL_NAME).asn +# files do not exist for all protocols: Please add/remove as required. +EXTRA_DIST = \ + Makefile.nmake \ + $(ASN_FILE_LIST) \ + packet-$(PROTOCOL_NAME)-template.c \ + packet-$(PROTOCOL_NAME)-template.h \ + $(PROTOCOL_NAME).cnf + +SRC_FILES = \ + $(EXTRA_DIST) \ + $(EXT_ASN_FILE_LIST) + +A2W_FLAGS= -b -e -C + +EXTRA_CNF= diff --git a/asn1/credssp/Makefile.nmake b/asn1/credssp/Makefile.nmake new file mode 100644 index 0000000000..5a32997c60 --- /dev/null +++ b/asn1/credssp/Makefile.nmake @@ -0,0 +1,29 @@ +## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake +# +# $Id$ +# +# +# Wireshark - Network traffic analyzer +# By Gerald Combs <gerald@wireshark.org> +# Copyright 1998 Gerald Combs +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +include ../../config.nmake +include ../Makefile.preinc.nmake +include Makefile.common +include ../Makefile.inc.nmake + diff --git a/asn1/credssp/credssp.cnf b/asn1/credssp/credssp.cnf new file mode 100644 index 0000000000..b53c7a663e --- /dev/null +++ b/asn1/credssp/credssp.cnf @@ -0,0 +1,57 @@ +# credssp.cnf +# Credential Security Support Provider (CredSSP) conformance file +# $Id$ + +#.PDU +TSRequest + +#.FN_PARS TSRequest/authInfo VAL_PTR = &auth_tvb + +#.FN_BODY TSRequest/authInfo + tvbuff_t *auth_tvb = NULL; + tvbuff_t *decr_tvb = NULL; + + %(DEFAULT_BODY)s + + if(decr_tvb != NULL) + offset = dissect_credssp_TSCredentials(FALSE, decr_tvb, 0, actx, tree, hf_credssp_TSCredentials); + + +#.FN_PARS TSCredentials/credType VAL_PTR = &creds_type +#.FN_PARS TSCredentials/credentials VAL_PTR = &creds_tvb + +#.FN_BODY TSCredentials/credentials + tvbuff_t *creds_tvb = NULL; + tvbuff_t *decr_tvb = NULL; + + %(DEFAULT_BODY)s + + if((decr_tvb != NULL) && + ((creds_type == TS_PASSWORD_CREDS) || (creds_type == TS_SMARTCARD_CREDS))) { + + switch(creds_type) { + case TS_PASSWORD_CREDS: + offset = dissect_credssp_TSPasswordCreds(FALSE, decr_tvb, 0, actx, tree, hf_credssp_TSPasswordCreds); + break; + case TS_SMARTCARD_CREDS: + offset = dissect_credssp_TSSmartCardCreds(FALSE, decr_tvb, 0, actx, tree, hf_credssp_TSSmartCardCreds); + break; + } + } + + +#.FN_PARS NegoData/_item/negoToken VAL_PTR = &token_tvb + +#.FN_BODY NegoData/_item/negoToken + tvbuff_t *token_tvb = NULL; + + %(DEFAULT_BODY)s + + if(token_tvb != NULL) + dissector_try_heuristic(credssp_heur_subdissector_list, + token_tvb, actx->pinfo, proto_tree_get_root(tree)); + + +#.END + + diff --git a/asn1/credssp/packet-credssp-template.c b/asn1/credssp/packet-credssp-template.c new file mode 100644 index 0000000000..aa57e2c16e --- /dev/null +++ b/asn1/credssp/packet-credssp-template.c @@ -0,0 +1,166 @@ +/* packet-credssp.c + * Routines for CredSSP (Credential Security Support Provider) packet dissection + * Graeme Lunt 2011 + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glib.h> +#include <epan/packet.h> +#include <epan/asn1.h> + +#include "packet-ber.h" +#include "packet-credssp.h" + + +#define PNAME "Credential Security Support Provider" +#define PSNAME "CredSSP" +#define PFNAME "credssp" + +#define TS_PASSWORD_CREDS 1 +#define TS_SMARTCARD_CREDS 2 +static gint creds_type; + +/* Initialize the protocol and registered fields */ +static int proto_credssp = -1; + +/* List of dissectors to call for negoToken data */ +static heur_dissector_list_t credssp_heur_subdissector_list; + +static int hf_credssp_TSPasswordCreds = -1; /* TSPasswordCreds */ +static int hf_credssp_TSSmartCardCreds = -1; /* TSSmartCardCreds */ +static int hf_credssp_TSCredentials = -1; /* TSCredentials */ +#include "packet-credssp-hf.c" + +/* Initialize the subtree pointers */ +static gint ett_credssp = -1; +#include "packet-credssp-ett.c" + +#include "packet-credssp-fn.c" + +/* +* Dissect CredSSP PDUs +*/ +static void +dissect_credssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) +{ + proto_item *item=NULL; + proto_tree *tree=NULL; + + if(parent_tree){ + item = proto_tree_add_item(parent_tree, proto_credssp, tvb, 0, -1, ENC_NA); + tree = proto_item_add_subtree(item, ett_credssp); + } + col_set_str(pinfo->cinfo, COL_PROTOCOL, "CredSSP"); + col_clear(pinfo->cinfo, COL_INFO); + + creds_type = -1; + dissect_TSRequest_PDU(tvb, pinfo, tree); +} + +static gboolean +dissect_credssp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) +{ + asn1_ctx_t asn1_ctx; + int offset = 0; + gint8 class; + gboolean pc; + gint32 tag; + guint32 length; + + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + + /* Look for SEQUENCE, CONTEXT 0, and INTEGER 2 */ + if(tvb_length(tvb) > 7) { + offset = get_ber_identifier(tvb, offset, &class, &pc, &tag); + if((class == BER_CLASS_UNI) && (tag == BER_UNI_TAG_SEQUENCE) && (pc == TRUE)) { + offset = get_ber_length(tvb, offset, NULL, NULL); + offset = get_ber_identifier(tvb, offset, &class, &pc, &tag); + if((class == BER_CLASS_CON) && (tag == 0)) { + offset = get_ber_length(tvb, offset, NULL, NULL); + offset = get_ber_identifier(tvb, offset, &class, &pc, &tag); + if((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; + } + } + } + } + } + return FALSE; +} + + +/*--- proto_register_credssp -------------------------------------------*/ +void proto_register_credssp(void) { + + /* List of fields */ + static hf_register_info hf[] = + { + { &hf_credssp_TSPasswordCreds, + { "TSPasswordCreds", "credssp.TSPasswordCreds", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_credssp_TSSmartCardCreds, + { "TSSmartCardCreds", "credssp.TSSmartCardCreds", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_credssp_TSCredentials, + { "TSCredentials", "credssp.TSCredentials", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, +#include "packet-credssp-hfarr.c" + }; + + /* List of subtrees */ + static gint *ett[] = { + &ett_credssp, +#include "packet-credssp-ettarr.c" + }; + + + /* Register protocol */ + proto_credssp = proto_register_protocol(PNAME, PSNAME, PFNAME); + register_dissector("credssp", dissect_credssp, proto_credssp); + + /* Register fields and subtrees */ + proto_register_field_array(proto_credssp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + /* heuristic dissectors for any premable e.g. CredSSP before RDP */ + register_heur_dissector_list("credssp", &credssp_heur_subdissector_list); + +} + + +/*--- proto_reg_handoff_credssp --- */ +void proto_reg_handoff_credssp(void) { + + heur_dissector_add("ssl", dissect_credssp_heur, proto_credssp); + +} + diff --git a/asn1/credssp/packet-credssp-template.h b/asn1/credssp/packet-credssp-template.h new file mode 100644 index 0000000000..8fe243a180 --- /dev/null +++ b/asn1/credssp/packet-credssp-template.h @@ -0,0 +1,34 @@ +/* packet-credssp.h + * Routines for CredSSP (Credential Security Support Provider) packet dissection + * Graeme Lunt 2011 + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef PACKET_CREDSSP_H +#define PACKET_CREDSSP_H + +#include "packet-credssp-val.h" + +void proto_reg_handoff_credssp(void); +void proto_register_credssp(void); + +#endif /* PACKET_CREDSSP_H */ diff --git a/configure.in b/configure.in index 5873294e4c..f261fb8267 100644 --- a/configure.in +++ b/configure.in @@ -1899,6 +1899,7 @@ AC_OUTPUT( asn1/cmp/Makefile asn1/crmf/Makefile asn1/cms/Makefile + asn1/credssp/Makefile asn1/dap/Makefile asn1/disp/Makefile asn1/dop/Makefile diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index ad3061752f..de7620eaee 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -190,6 +190,7 @@ set(ASN1_DISSECTOR_SRC dissectors/packet-cmip.c dissectors/packet-cmp.c dissectors/packet-cms.c + dissectors/packet-credssp.c dissectors/packet-crmf.c dissectors/packet-dap.c dissectors/packet-disp.c diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common index f813b978ae..8875229ce1 100644 --- a/epan/dissectors/Makefile.common +++ b/epan/dissectors/Makefile.common @@ -103,6 +103,7 @@ ASN1_DISSECTOR_SRC = \ packet-cmp.c \ packet-cms.c \ packet-coap.c \ + packet-credssp.c \ packet-crmf.c \ packet-dap.c \ packet-disp.c \ diff --git a/epan/dissectors/packet-credssp.c b/epan/dissectors/packet-credssp.c new file mode 100644 index 0000000000..af561fb00f --- /dev/null +++ b/epan/dissectors/packet-credssp.c @@ -0,0 +1,539 @@ +/* Do not modify this file. */ +/* It is created automatically by the ASN.1 to Wireshark dissector compiler */ +/* packet-credssp.c */ +/* ../../tools/asn2wrs.py -b -e -C -p credssp -c ./credssp.cnf -s ./packet-credssp-template -D . CredSSP.asn */ + +/* Input file: packet-credssp-template.c */ + +#line 1 "../../asn1/credssp/packet-credssp-template.c" +/* packet-credssp.c + * Routines for CredSSP (Credential Security Support Provider) packet dissection + * Graeme Lunt 2011 + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glib.h> +#include <epan/packet.h> +#include <epan/asn1.h> + +#include "packet-ber.h" +#include "packet-credssp.h" + + +#define PNAME "Credential Security Support Provider" +#define PSNAME "CredSSP" +#define PFNAME "credssp" + +#define TS_PASSWORD_CREDS 1 +#define TS_SMARTCARD_CREDS 2 +static gint creds_type; + +/* Initialize the protocol and registered fields */ +static int proto_credssp = -1; + +/* List of dissectors to call for negoToken data */ +static heur_dissector_list_t credssp_heur_subdissector_list; + +static int hf_credssp_TSPasswordCreds = -1; /* TSPasswordCreds */ +static int hf_credssp_TSSmartCardCreds = -1; /* TSSmartCardCreds */ +static int hf_credssp_TSCredentials = -1; /* TSCredentials */ + +/*--- Included file: packet-credssp-hf.c ---*/ +#line 1 "../../asn1/credssp/packet-credssp-hf.c" +static int hf_credssp_TSRequest_PDU = -1; /* TSRequest */ +static int hf_credssp_NegoData_item = -1; /* NegoData_item */ +static int hf_credssp_negoToken = -1; /* T_negoToken */ +static int hf_credssp_domainName = -1; /* OCTET_STRING */ +static int hf_credssp_userName = -1; /* OCTET_STRING */ +static int hf_credssp_password = -1; /* OCTET_STRING */ +static int hf_credssp_keySpec = -1; /* INTEGER */ +static int hf_credssp_cardName = -1; /* OCTET_STRING */ +static int hf_credssp_readerName = -1; /* OCTET_STRING */ +static int hf_credssp_containerName = -1; /* OCTET_STRING */ +static int hf_credssp_cspName = -1; /* OCTET_STRING */ +static int hf_credssp_pin = -1; /* OCTET_STRING */ +static int hf_credssp_cspData = -1; /* TSCspDataDetail */ +static int hf_credssp_userHint = -1; /* OCTET_STRING */ +static int hf_credssp_domainHint = -1; /* OCTET_STRING */ +static int hf_credssp_credType = -1; /* T_credType */ +static int hf_credssp_credentials = -1; /* T_credentials */ +static int hf_credssp_version = -1; /* INTEGER */ +static int hf_credssp_negoTokens = -1; /* NegoData */ +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 56 "../../asn1/credssp/packet-credssp-template.c" + +/* Initialize the subtree pointers */ +static gint ett_credssp = -1; + +/*--- Included file: packet-credssp-ett.c ---*/ +#line 1 "../../asn1/credssp/packet-credssp-ett.c" +static gint ett_credssp_NegoData = -1; +static gint ett_credssp_NegoData_item = -1; +static gint ett_credssp_TSPasswordCreds = -1; +static gint ett_credssp_TSCspDataDetail = -1; +static gint ett_credssp_TSSmartCardCreds = -1; +static gint ett_credssp_TSCredentials = -1; +static gint ett_credssp_TSRequest = -1; + +/*--- End of included file: packet-credssp-ett.c ---*/ +#line 60 "../../asn1/credssp/packet-credssp-template.c" + + +/*--- Included file: packet-credssp-fn.c ---*/ +#line 1 "../../asn1/credssp/packet-credssp-fn.c" + + +static int +dissect_credssp_T_negoToken(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { +#line 46 "../../asn1/credssp/credssp.cnf" + tvbuff_t *token_tvb = NULL; + + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, + &token_tvb); + + + if(token_tvb != NULL) + dissector_try_heuristic(credssp_heur_subdissector_list, + token_tvb, actx->pinfo, proto_tree_get_root(tree)); + + + + + return offset; +} + + +static const ber_sequence_t NegoData_item_sequence[] = { + { &hf_credssp_negoToken , BER_CLASS_CON, 0, 0, dissect_credssp_T_negoToken }, + { NULL, 0, 0, 0, NULL } +}; + +static int +dissect_credssp_NegoData_item(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, + NegoData_item_sequence, hf_index, ett_credssp_NegoData_item); + + return offset; +} + + +static const ber_sequence_t NegoData_sequence_of[1] = { + { &hf_credssp_NegoData_item, BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_credssp_NegoData_item }, +}; + +static int +dissect_credssp_NegoData(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset, + NegoData_sequence_of, hf_index, ett_credssp_NegoData); + + return offset; +} + + + +static int +dissect_credssp_OCTET_STRING(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, + NULL); + + return offset; +} + + +static const ber_sequence_t TSPasswordCreds_sequence[] = { + { &hf_credssp_domainName , BER_CLASS_CON, 0, 0, dissect_credssp_OCTET_STRING }, + { &hf_credssp_userName , BER_CLASS_CON, 1, 0, dissect_credssp_OCTET_STRING }, + { &hf_credssp_password , BER_CLASS_CON, 2, 0, dissect_credssp_OCTET_STRING }, + { NULL, 0, 0, 0, NULL } +}; + +static int +dissect_credssp_TSPasswordCreds(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, + TSPasswordCreds_sequence, hf_index, ett_credssp_TSPasswordCreds); + + return offset; +} + + + +static int +dissect_credssp_INTEGER(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index, + NULL); + + return offset; +} + + +static const ber_sequence_t TSCspDataDetail_sequence[] = { + { &hf_credssp_keySpec , BER_CLASS_CON, 0, 0, dissect_credssp_INTEGER }, + { &hf_credssp_cardName , BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL, dissect_credssp_OCTET_STRING }, + { &hf_credssp_readerName , BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL, dissect_credssp_OCTET_STRING }, + { &hf_credssp_containerName, BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL, dissect_credssp_OCTET_STRING }, + { &hf_credssp_cspName , BER_CLASS_CON, 4, BER_FLAGS_OPTIONAL, dissect_credssp_OCTET_STRING }, + { NULL, 0, 0, 0, NULL } +}; + +static int +dissect_credssp_TSCspDataDetail(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, + TSCspDataDetail_sequence, hf_index, ett_credssp_TSCspDataDetail); + + return offset; +} + + +static const ber_sequence_t TSSmartCardCreds_sequence[] = { + { &hf_credssp_pin , BER_CLASS_CON, 0, 0, dissect_credssp_OCTET_STRING }, + { &hf_credssp_cspData , BER_CLASS_CON, 1, 0, dissect_credssp_TSCspDataDetail }, + { &hf_credssp_userHint , BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL, dissect_credssp_OCTET_STRING }, + { &hf_credssp_domainHint , BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL, dissect_credssp_OCTET_STRING }, + { NULL, 0, 0, 0, NULL } +}; + +static int +dissect_credssp_TSSmartCardCreds(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, + TSSmartCardCreds_sequence, hf_index, ett_credssp_TSSmartCardCreds); + + return offset; +} + + + +static int +dissect_credssp_T_credType(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index, + &creds_type); + + return offset; +} + + + +static int +dissect_credssp_T_credentials(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { +#line 24 "../../asn1/credssp/credssp.cnf" + tvbuff_t *creds_tvb = NULL; + tvbuff_t *decr_tvb = NULL; + + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, + &creds_tvb); + + + if((decr_tvb != NULL) && + ((creds_type == TS_PASSWORD_CREDS) || (creds_type == TS_SMARTCARD_CREDS))) { + + switch(creds_type) { + case TS_PASSWORD_CREDS: + offset = dissect_credssp_TSPasswordCreds(FALSE, decr_tvb, 0, actx, tree, hf_credssp_TSPasswordCreds); + break; + case TS_SMARTCARD_CREDS: + offset = dissect_credssp_TSSmartCardCreds(FALSE, decr_tvb, 0, actx, tree, hf_credssp_TSSmartCardCreds); + break; + } + } + + + + + return offset; +} + + +static const ber_sequence_t TSCredentials_sequence[] = { + { &hf_credssp_credType , BER_CLASS_CON, 0, 0, dissect_credssp_T_credType }, + { &hf_credssp_credentials , BER_CLASS_CON, 1, 0, dissect_credssp_T_credentials }, + { NULL, 0, 0, 0, NULL } +}; + +static int +dissect_credssp_TSCredentials(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, + TSCredentials_sequence, hf_index, ett_credssp_TSCredentials); + + return offset; +} + + + +static int +dissect_credssp_T_authInfo(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { +#line 11 "../../asn1/credssp/credssp.cnf" + tvbuff_t *auth_tvb = NULL; + tvbuff_t *decr_tvb = NULL; + + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, + &auth_tvb); + + + if(decr_tvb != NULL) + offset = dissect_credssp_TSCredentials(FALSE, decr_tvb, 0, actx, tree, hf_credssp_TSCredentials); + + + + + return offset; +} + + +static const ber_sequence_t TSRequest_sequence[] = { + { &hf_credssp_version , BER_CLASS_CON, 0, 0, dissect_credssp_INTEGER }, + { &hf_credssp_negoTokens , BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL, dissect_credssp_NegoData }, + { &hf_credssp_authInfo , BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL, dissect_credssp_T_authInfo }, + { &hf_credssp_pubKeyAuth , BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL, dissect_credssp_OCTET_STRING }, + { NULL, 0, 0, 0, NULL } +}; + +static int +dissect_credssp_TSRequest(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { + offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, + TSRequest_sequence, hf_index, ett_credssp_TSRequest); + + return offset; +} + +/*--- PDUs ---*/ + +static void dissect_TSRequest_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) { + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + dissect_credssp_TSRequest(FALSE, tvb, 0, &asn1_ctx, tree, hf_credssp_TSRequest_PDU); +} + + +/*--- End of included file: packet-credssp-fn.c ---*/ +#line 62 "../../asn1/credssp/packet-credssp-template.c" + +/* +* Dissect CredSSP PDUs +*/ +static void +dissect_credssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) +{ + proto_item *item=NULL; + proto_tree *tree=NULL; + + if(parent_tree){ + item = proto_tree_add_item(parent_tree, proto_credssp, tvb, 0, -1, ENC_NA); + tree = proto_item_add_subtree(item, ett_credssp); + } + col_set_str(pinfo->cinfo, COL_PROTOCOL, "CredSSP"); + col_clear(pinfo->cinfo, COL_INFO); + + creds_type = -1; + dissect_TSRequest_PDU(tvb, pinfo, tree); +} + +static gboolean +dissect_credssp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) +{ + asn1_ctx_t asn1_ctx; + int offset = 0; + gint8 class; + gboolean pc; + gint32 tag; + guint32 length; + + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + + /* Look for SEQUENCE, CONTEXT 0, and INTEGER 2 */ + if(tvb_length(tvb) > 7) { + offset = get_ber_identifier(tvb, offset, &class, &pc, &tag); + if((class == BER_CLASS_UNI) && (tag == BER_UNI_TAG_SEQUENCE) && (pc == TRUE)) { + offset = get_ber_length(tvb, offset, NULL, NULL); + offset = get_ber_identifier(tvb, offset, &class, &pc, &tag); + if((class == BER_CLASS_CON) && (tag == 0)) { + offset = get_ber_length(tvb, offset, NULL, NULL); + offset = get_ber_identifier(tvb, offset, &class, &pc, &tag); + if((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; + } + } + } + } + } + return FALSE; +} + + +/*--- proto_register_credssp -------------------------------------------*/ +void proto_register_credssp(void) { + + /* List of fields */ + static hf_register_info hf[] = + { + { &hf_credssp_TSPasswordCreds, + { "TSPasswordCreds", "credssp.TSPasswordCreds", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_credssp_TSSmartCardCreds, + { "TSSmartCardCreds", "credssp.TSSmartCardCreds", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_credssp_TSCredentials, + { "TSCredentials", "credssp.TSCredentials", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + +/*--- Included file: packet-credssp-hfarr.c ---*/ +#line 1 "../../asn1/credssp/packet-credssp-hfarr.c" + { &hf_credssp_TSRequest_PDU, + { "TSRequest", "credssp.TSRequest", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_credssp_NegoData_item, + { "NegoData item", "credssp.NegoData_item", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_credssp_negoToken, + { "negoToken", "credssp.negoToken", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_credssp_domainName, + { "domainName", "credssp.domainName", + FT_BYTES, BASE_NONE, NULL, 0, + "OCTET_STRING", HFILL }}, + { &hf_credssp_userName, + { "userName", "credssp.userName", + FT_BYTES, BASE_NONE, NULL, 0, + "OCTET_STRING", HFILL }}, + { &hf_credssp_password, + { "password", "credssp.password", + FT_BYTES, BASE_NONE, NULL, 0, + "OCTET_STRING", HFILL }}, + { &hf_credssp_keySpec, + { "keySpec", "credssp.keySpec", + FT_INT32, BASE_DEC, NULL, 0, + "INTEGER", HFILL }}, + { &hf_credssp_cardName, + { "cardName", "credssp.cardName", + FT_BYTES, BASE_NONE, NULL, 0, + "OCTET_STRING", HFILL }}, + { &hf_credssp_readerName, + { "readerName", "credssp.readerName", + FT_BYTES, BASE_NONE, NULL, 0, + "OCTET_STRING", HFILL }}, + { &hf_credssp_containerName, + { "containerName", "credssp.containerName", + FT_BYTES, BASE_NONE, NULL, 0, + "OCTET_STRING", HFILL }}, + { &hf_credssp_cspName, + { "cspName", "credssp.cspName", + FT_BYTES, BASE_NONE, NULL, 0, + "OCTET_STRING", HFILL }}, + { &hf_credssp_pin, + { "pin", "credssp.pin", + FT_BYTES, BASE_NONE, NULL, 0, + "OCTET_STRING", HFILL }}, + { &hf_credssp_cspData, + { "cspData", "credssp.cspData", + FT_NONE, BASE_NONE, NULL, 0, + "TSCspDataDetail", HFILL }}, + { &hf_credssp_userHint, + { "userHint", "credssp.userHint", + FT_BYTES, BASE_NONE, NULL, 0, + "OCTET_STRING", HFILL }}, + { &hf_credssp_domainHint, + { "domainHint", "credssp.domainHint", + FT_BYTES, BASE_NONE, NULL, 0, + "OCTET_STRING", HFILL }}, + { &hf_credssp_credType, + { "credType", "credssp.credType", + FT_INT32, BASE_DEC, NULL, 0, + NULL, HFILL }}, + { &hf_credssp_credentials, + { "credentials", "credssp.credentials", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_credssp_version, + { "version", "credssp.version", + FT_INT32, BASE_DEC, NULL, 0, + "INTEGER", HFILL }}, + { &hf_credssp_negoTokens, + { "negoTokens", "credssp.negoTokens", + FT_UINT32, BASE_DEC, NULL, 0, + "NegoData", HFILL }}, + { &hf_credssp_authInfo, + { "authInfo", "credssp.authInfo", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_credssp_pubKeyAuth, + { "pubKeyAuth", "credssp.pubKeyAuth", + FT_BYTES, BASE_NONE, NULL, 0, + "OCTET_STRING", HFILL }}, + +/*--- End of included file: packet-credssp-hfarr.c ---*/ +#line 137 "../../asn1/credssp/packet-credssp-template.c" + }; + + /* List of subtrees */ + static gint *ett[] = { + &ett_credssp, + +/*--- Included file: packet-credssp-ettarr.c ---*/ +#line 1 "../../asn1/credssp/packet-credssp-ettarr.c" + &ett_credssp_NegoData, + &ett_credssp_NegoData_item, + &ett_credssp_TSPasswordCreds, + &ett_credssp_TSCspDataDetail, + &ett_credssp_TSSmartCardCreds, + &ett_credssp_TSCredentials, + &ett_credssp_TSRequest, + +/*--- End of included file: packet-credssp-ettarr.c ---*/ +#line 143 "../../asn1/credssp/packet-credssp-template.c" + }; + + + /* Register protocol */ + proto_credssp = proto_register_protocol(PNAME, PSNAME, PFNAME); + register_dissector("credssp", dissect_credssp, proto_credssp); + + /* Register fields and subtrees */ + proto_register_field_array(proto_credssp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + /* heuristic dissectors for any premable e.g. CredSSP before RDP */ + register_heur_dissector_list("credssp", &credssp_heur_subdissector_list); + +} + + +/*--- proto_reg_handoff_credssp --- */ +void proto_reg_handoff_credssp(void) { + + heur_dissector_add("ssl", dissect_credssp_heur, proto_credssp); + +} + diff --git a/epan/dissectors/packet-credssp.h b/epan/dissectors/packet-credssp.h new file mode 100644 index 0000000000..fb76a234b1 --- /dev/null +++ b/epan/dissectors/packet-credssp.h @@ -0,0 +1,47 @@ +/* Do not modify this file. */ +/* It is created automatically by the ASN.1 to Wireshark dissector compiler */ +/* packet-credssp.h */ +/* ../../tools/asn2wrs.py -b -e -C -p credssp -c ./credssp.cnf -s ./packet-credssp-template -D . CredSSP.asn */ + +/* Input file: packet-credssp-template.h */ + +#line 1 "../../asn1/credssp/packet-credssp-template.h" +/* packet-credssp.h + * Routines for CredSSP (Credential Security Support Provider) packet dissection + * Graeme Lunt 2011 + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef PACKET_CREDSSP_H +#define PACKET_CREDSSP_H + + +/*--- Included file: packet-credssp-val.h ---*/ +#line 1 "../../asn1/credssp/packet-credssp-val.h" + +/*--- End of included file: packet-credssp-val.h ---*/ +#line 30 "../../asn1/credssp/packet-credssp-template.h" + +void proto_reg_handoff_credssp(void); +void proto_register_credssp(void); + +#endif /* PACKET_CREDSSP_H */ diff --git a/epan/dissectors/packet-ntlmssp.c b/epan/dissectors/packet-ntlmssp.c index 7188c70015..f75c8d1578 100644 --- a/epan/dissectors/packet-ntlmssp.c +++ b/epan/dissectors/packet-ntlmssp.c @@ -1750,7 +1750,7 @@ dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset, data_start = MIN(data_start, item_start); data_end = MAX(data_end, item_end); - col_append_fstr(pinfo->cinfo, COL_INFO, ", User: %s\\%s", + col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "User: %s\\%s", ntlmssph->domain_name, ntlmssph->acct_name); /* hostname */ @@ -2164,7 +2164,7 @@ dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) ntlmssph->type = tvb_get_letohl (tvb, offset); offset += 4; - col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", + col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ","%s", val_to_str(ntlmssph->type, ntlmssp_message_types, "Unknown message type")); @@ -2204,6 +2204,18 @@ dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /*tap_queue_packet(ntlmssp_tap, pinfo, ntlmssph);*/ } +static gboolean +dissect_ntlmssp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) +{ + + if(tvb_memeql(tvb, 0, "NTLMSSP", 8) == 0) { + + dissect_ntlmssp(tvb, pinfo, parent_tree); + return TRUE; + } + + return FALSE; +} /* @@ -3021,6 +3033,9 @@ proto_reg_handoff_ntlmssp(void) DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP, &ntlmssp_seal_fns); ntlmssp_tap = register_tap("ntlmssp"); + + heur_dissector_add("credssp", dissect_ntlmssp_heur, proto_ntlmssp); + } /* diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c index 3d38f0ed7a..e637e29a64 100644 --- a/epan/dissectors/packet-ssl.c +++ b/epan/dissectors/packet-ssl.c @@ -315,6 +315,9 @@ static gchar* ssl_keys_list = NULL; static gchar* ssl_psk = NULL; static gchar* ssl_keylog_filename = NULL; +/* List of dissectors to call for SSL data */ +static heur_dissector_list_t ssl_heur_subdissector_list; + #if defined(SSL_DECRYPT_DEBUG) || defined(HAVE_LIBGNUTLS) static gchar* ssl_debug_file_name = NULL; #endif @@ -1242,7 +1245,12 @@ process_ssl_payload(tvbuff_t *tvb, volatile int offset, packet_info *pinfo, if (association && association->handle) { ssl_debug_printf("dissect_ssl3_record found association %p\n", (void *)association); + + if (dissector_try_heuristic(ssl_heur_subdissector_list, next_tvb, + pinfo, proto_tree_get_root(tree))) { + } else { call_dissector(association->handle, next_tvb, pinfo, proto_tree_get_root(tree)); + } } } @@ -5052,6 +5060,8 @@ proto_register_ssl(void) #endif } + /* 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); ssl_handle = find_dissector("ssl"); |