summaryrefslogtreecommitdiffstats
path: root/contrib/impcap/smb_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/impcap/smb_parser.c')
-rw-r--r--contrib/impcap/smb_parser.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/contrib/impcap/smb_parser.c b/contrib/impcap/smb_parser.c
new file mode 100644
index 0000000..e673cd3
--- /dev/null
+++ b/contrib/impcap/smb_parser.c
@@ -0,0 +1,145 @@
+/* smb_parser.c
+ *
+ * This file contains functions to parse SMB (version 2 and 3) headers.
+ *
+ * File begun on 2018-11-13
+ *
+ * Created by:
+ * - Théo Bertin (theo.bertin@advens.fr)
+ *
+ * With:
+ * - François Bernard (francois.bernard@isen.yncrea.fr)
+ * - Tianyu Geng (tianyu.geng@isen.yncrea.fr)
+ *
+ * This file is part of rsyslog.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * -or-
+ * see COPYING.ASL20 in the source distribution
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "config.h"
+#include "parsers.h"
+
+/* SMB2 opCodes */
+#define SMB2_NEGOTIATE 0x00
+#define SMB2_SESSIONSET 0x01
+#define SMB2_SESSIONLOGOFF 0x02
+#define SMB2_TREECONNECT 0x03
+#define SMB2_TREEDISCONNECT 0x04
+#define SMB2_CREATE 0x05
+#define SMB2_CLOSE 0x06
+#define SMB2_FLUSH 0x07
+#define SMB2_READ 0x08
+#define SMB2_WRITE 0x09
+#define SMB2_LOCK 0x0a
+#define SMB2_IOCTL 0x0b
+#define SMB2_CANCEL 0x0c
+#define SMB2_KEEPALIVE 0x0d
+#define SMB2_FIND 0x0e
+#define SMB2_NOTIFY 0x0f
+#define SMB2_GETINFO 0x10
+#define SMB2_SETINFO 0x11
+#define SMB2_BREAK 0x12
+
+struct smb_header_s {
+ uint32_t version;
+ uint16_t headerLength;
+ uint16_t padding1;
+ uint32_t ntStatus;
+ uint16_t opCode;
+ uint16_t padding2;
+ uint32_t flags;
+ uint32_t chainOffset;
+ uint32_t comSeqNumber[2];
+ uint32_t processID;
+ uint32_t treeID;
+ uint32_t userID[2];
+ uint32_t signature[4];
+};
+
+typedef struct smb_header_s smb_header_t;
+
+static char flagCodes[5] = "RPCS";
+
+/*
+ * This function parses the bytes in the received packet to extract SMB2 metadata.
+ *
+ * its parameters are:
+ * - a pointer on the list of bytes representing the packet
+ * the beginning of the header will be checked by the function
+ * - the size of the list passed as first parameter
+ * - a pointer on a json_object, containing all the metadata recovered so far
+ * this is also where SMB2 metadata will be added
+ *
+ * This function returns a structure containing the data unprocessed by this parser
+ * or the ones after (as a list of bytes), and the length of this data.
+*/
+data_ret_t *smb_parse(const uchar *packet, int pktSize, struct json_object *jparent) {
+ DBGPRINTF("smb_parse\n");
+ DBGPRINTF("packet size %d\n", pktSize);
+
+ int pktSizeCpy = pktSize;
+ const uchar *packetCpy = packet;
+
+ while (pktSizeCpy > 0) {
+ /* don't check packetCpy[0] to include SMB version byte at the beginning */
+ if (packetCpy[1] == 'S') {
+ if (packetCpy[2] == 'M') {
+ if (packetCpy[3] == 'B') {
+ break;
+ }
+ }
+ }
+ packetCpy++, pktSizeCpy--;
+ }
+
+ if ((int)pktSizeCpy < 64) {
+ DBGPRINTF("SMB packet too small : %d\n", pktSizeCpy);
+ RETURN_DATA_AFTER(0)
+ }
+
+ /* Union to prevent cast from uchar to smb_header_t */
+ union {
+ const uchar *pck;
+ smb_header_t *hdr;
+ } smb_header_to_char;
+
+ smb_header_to_char.pck = packetCpy;
+ smb_header_t *smb_header = smb_header_to_char.hdr;
+
+ char flags[5] = {0};
+ uint64_t seqNum, userID;
+ uint8_t version;
+
+ version = (smb_header->version == 0xFF) ? 1 : 2;
+ seqNum = smb_header->comSeqNumber[0] | smb_header->comSeqNumber[1] << 16;
+ userID = smb_header->userID[0] | smb_header->userID[1] << 16;
+
+ uint8_t i, pos = 0;
+ for (i = 0; i < 4; ++i) {
+ if (smb_header->flags & (0x01 << i))
+ flags[pos++] = flagCodes[i];
+ }
+
+ json_object_object_add(jparent, "SMB_version", json_object_new_int(version));
+ json_object_object_add(jparent, "SMB_NTstatus", json_object_new_int64(smb_header->ntStatus));
+ json_object_object_add(jparent, "SMB_operation", json_object_new_int(smb_header->opCode));
+ json_object_object_add(jparent, "SMB_flags", json_object_new_string(flags));
+ json_object_object_add(jparent, "SMB_seqNumber", json_object_new_int64(seqNum));
+ json_object_object_add(jparent, "SMB_processID", json_object_new_int64(smb_header->processID));
+ json_object_object_add(jparent, "SMB_treeID", json_object_new_int64(smb_header->treeID));
+ json_object_object_add(jparent, "SMB_userID", json_object_new_int64(userID));
+
+ RETURN_DATA_AFTER(0)
+}