⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smb_andx_decode.c

📁 入侵检测SNORT.最近更新的基于网络检测的IDS.希望能给大家带来方便.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * smb_andx_decode.c * * Copyright (C) 2004-2008 Sourcefire,Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as * published by the Free Software Foundation.  You may not use, modify or * distribute this program under any other version of the GNU General * Public License. * * 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. * * Description: * * This performs the decoding of SMB AndX commands. * * NOTES: * - 08.12.04:  Initial Development.  SAS * */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdlib.h>#ifdef HAVE_WCHAR_H#include <wchar.h>#endif#include <string.h>#include "debug.h"#include "bounds.h"#include "snort_dcerpc.h"#include "smb_structs.h"#include "smb_andx_structs.h"#include "smb_andx_decode.h"#include "dcerpc_util.h"#include "dcerpc.h"#define FIELD_ACCT_NAME 0#define FIELD_PRIM_DOMAIN 1#define SESS_AUTH_FIELD(i) ((i == FIELD_ACCT_NAME) ? "AccountName" : ((i == FIELD_PRIM_DOMAIN) ? "PrimaryDomain"  : "Unknown"))#define FIELD_NATIVE_OS 0#define FIELD_NATIVE_LANMAN 1#define SESS_NATIVE_FIELD(i) ((i == FIELD_NATIVE_OS) ? "NativeOS" : ((i == FIELD_NATIVE_LANMAN) ? "NativeLanMan" : "Unknown"))/* Externs */extern DCERPC         *_dcerpc;extern SFSnortPacket  *_dcerpc_pkt;extern u_int8_t        _disable_smb_fragmentation;extern u_int16_t       _max_frag_size;extern u_int8_t *dce_reassembly_buf;extern u_int16_t dce_reassembly_buf_size;extern SFSnortPacket *real_dce_mock_pkt;extern u_int8_t        _debug_print;extern int _reassemble_increment;static int GetSMBStringLength(u_int8_t *data, u_int16_t data_size, int unicode);#ifdef DEBUG_DCERPC_PRINTstatic void PrintSMBString(char *pre, u_int8_t *str, u_int16_t str_len, int unicode);#endif/* smb_data is guaranteed to be at least an SMB_WRITEX_REQ length away from writeX * if it's farther it's because there was padding */void ReassembleSMBWriteX(u_int8_t *smb_hdr, u_int16_t smb_hdr_len){    SMB_WRITEX_REQ *write_andx;    int pkt_len;    int status;    u_int16_t data_len = 0;    DCERPC_Buffer *buf = &_dcerpc->smb_seg_buf;    pkt_len = sizeof(NBT_HDR) + smb_hdr_len + buf->len;    /* Make sure we have room to fit into reassembly buffer */    if (pkt_len > dce_reassembly_buf_size)    {        DEBUG_WRAP(DebugMessage(DEBUG_DCERPC, "Reassembled SMB packet greater "                                "than %d bytes, skipping.", dce_reassembly_buf_size););        /* just shorten it - don't want to lose all of         * this information */        buf->len = dce_reassembly_buf_size - (pkt_len - buf->len);    }    /* Copy headers into buffer */    /* SMB Header */    status = SafeMemcpy(dce_reassembly_buf, _dcerpc_pkt->payload, sizeof(NBT_HDR) + smb_hdr_len,                        dce_reassembly_buf, dce_reassembly_buf + dce_reassembly_buf_size);    if (status != SAFEMEM_SUCCESS)    {        DEBUG_WRAP(DebugMessage(DEBUG_DCERPC, "SMB header too big: %u, "                                "skipping SMB reassembly.", dce_reassembly_buf_size););        DCERPC_BufferFreeData(buf);        return;    }    write_andx = (SMB_WRITEX_REQ *)((u_int8_t *)dce_reassembly_buf + sizeof(NBT_HDR) + sizeof(SMB_HDR));    write_andx->remaining = smb_htons(buf->len);    write_andx->dataLength = smb_htons(buf->len);    write_andx->dataOffset = smb_htons(smb_hdr_len);    write_andx->andXCommand = 0xFF;    write_andx->andXOffset = 0x0000;    data_len = sizeof(NBT_HDR) + smb_hdr_len;        status = SafeMemcpy(dce_reassembly_buf + data_len, buf->data, buf->len,                        dce_reassembly_buf + data_len, dce_reassembly_buf + dce_reassembly_buf_size);    if (status != SAFEMEM_SUCCESS)    {        DEBUG_WRAP(DebugMessage(DEBUG_DCERPC, "SMB fragments too big: %u, "                                "skipping SMB reassembly.", dce_reassembly_buf_size););        DCERPC_BufferFreeData(buf);        return;    }    data_len += buf->len;    /* create pseudo packet */    real_dce_mock_pkt = DCERPC_SetPseudoPacket(_dcerpc_pkt, dce_reassembly_buf, data_len);    if (real_dce_mock_pkt == NULL)    {        DCERPC_BufferFreeData(buf);        return;    }    if (_debug_print)    {        PrintBuffer("SMB desegmented",                    (u_int8_t *)dce_reassembly_buf, data_len);    }}/* IPC$ has to occur at the end of this path - path_len should include null termination */static int IsIPC(u_int8_t *path, int path_len, u_int32_t isUnicode){    const u_int8_t ipc[] = {'I', 'P', 'C', '$', '\0'};    const u_int16_t ipc_len = 5;    const u_int8_t unicode_ipc[] = {'I', '\0', 'P', '\0', 'C', '\0', '$', '\0', '\0', '\0'};    const u_int16_t unicode_ipc_len = 10;    if (isUnicode)    {        if (path_len < unicode_ipc_len)            return 0;        /* go to end of path then back up the length of the          * unicode_ipc string */        path = (path + path_len) - unicode_ipc_len;        if (memcmp(path, unicode_ipc, unicode_ipc_len) == 0)            return 1;    }    else    {        if (path_len < ipc_len)            return 0;        /* go to end of path and back up the length of the         * ipc string */        path = (path + path_len) - ipc_len;        if (memcmp(path, ipc, ipc_len) == 0)            return 1;    }            return 0;}/* returns -1 if not null terminated  * returns -2 for other error * otherwise returns length of null terminated string * including null terminating bytes */static int GetSMBStringLength(u_int8_t *data, u_int16_t data_size, int unicode){    u_int16_t size_left;    if (data == NULL)        return -2;    size_left = data_size;    if (unicode)    {        while (size_left >= sizeof(uni_char_t))        {            size_left -= sizeof(uni_char_t);            if (*((uni_char_t *)data) == 0x0000)            {                return (int)(data_size - size_left);            }            data += sizeof(uni_char_t);        }    }    else    {        while (size_left >= sizeof(char))        {            size_left -= sizeof(char);            if (*((char *)data) == 0x00)            {                return (int)(data_size - size_left);            }            data += sizeof(char);        }    }    return -1;}#ifdef DEBUG_DCERPC_PRINTstatic void PrintSMBString(char *pre, u_int8_t *str, u_int16_t str_len, int unicode){    if (pre == NULL || str == NULL || str_len == 0)        return;    printf("%s", pre);    if (unicode)    {        int i = 0;        while (i < str_len)        {            printf("%c", str[i]);            i += sizeof(uni_char_t);        }    }    else    {        printf("%.*s", str_len, str);    }    printf("\n");}#endifint SkipBytes(u_int8_t *data, u_int16_t size){    u_int16_t i = 0;    while ( i < size && *data != 0 )    {        data++;        i++;    }    return i;}int SkipBytesWide(u_int8_t *data, u_int16_t size){    u_int16_t i = 0;    /* Check against size-1 in case someone is screwing with us and giving         us an odd number of bytes for 2-byte Unicode.  */    while ( i < (size - 1) && *data != 0 )    {        data += 2;        i += 2;    }    return i;}int ProcessSMBTreeConnXReq(SMB_HDR *smbHdr, u_int8_t *data, u_int16_t size, u_int16_t total_size){    SMB_TREE_CONNECTX_REQ *treeConnX;    u_int16_t byteCount;    u_int8_t *tree_data;    u_int16_t tree_data_len;    u_int8_t *passwd_ptr;    u_int16_t passwd_len;    u_int8_t *path_ptr;    int path_len;    u_int8_t *service_ptr;    int service_len;    int is_ipc;    if ( size <= sizeof(SMB_TREE_CONNECTX_REQ) )    {        return 0;    }    treeConnX = (SMB_TREE_CONNECTX_REQ *)data;        size -= sizeof(SMB_TREE_CONNECTX_REQ);    tree_data = data + sizeof(SMB_TREE_CONNECTX_REQ);    byteCount = smb_ntohs(treeConnX->byteCount);    tree_data_len = byteCount;    passwd_len = smb_ntohs(treeConnX->passwdLen);    /* Sanity check */    if ( byteCount > size || passwd_len >= byteCount)        return 0;    passwd_ptr = tree_data;    tree_data += passwd_len;    tree_data_len -= passwd_len;    /* Get path */    path_len = GetSMBStringLength(tree_data, tree_data_len, HAS_UNICODE_STRINGS(smbHdr));    if (path_len == -1 || path_len == tree_data_len)        return 0;    path_ptr = tree_data;    is_ipc = IsIPC(tree_data, path_len, HAS_UNICODE_STRINGS(smbHdr));    if (is_ipc && _dcerpc->smb_state == STATE_START)    {        _dcerpc->smb_state = STATE_GOT_TREE_CONNECT;    }    tree_data += path_len;    tree_data_len -= path_len;    /* Service field is ALWAYS ascii */    service_len = GetSMBStringLength(tree_data, tree_data_len, 0);    if (service_len == -1)        return 0;    service_ptr = tree_data;    /* there shouldn't be any more data */    if (tree_data + service_len != tree_data + tree_data_len)        return 0;#ifdef DEBUG_DCERPC_PRINT    /* Password data      * it seems like the password length has to be an odd number     * This passwd will always be ASCII -- equiv of     * CaseInsensitivePasswd field from SessSetupAndX message */    if (passwd_len > 0)        printf("Password: %02.*X\n", passwd_len, passwd_ptr);    if (path_len > 0)        PrintSMBString("Path: ", path_ptr, path_len, HAS_UNICODE_STRINGS(smbHdr));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -