Coverage Report

Created: 2026-09-28 07:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata8/src/detect-dce-iface.c
Line
Count
Source
1
/* Copyright (C) 2007-2022 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17
18
/**
19
 * \file
20
 *
21
 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
22
 *
23
 * Implements dce_iface keyword.
24
 */
25
26
#include "suricata-common.h"
27
28
#include "detect.h"
29
#include "detect-parse.h"
30
31
#include "detect-engine.h"
32
#include "detect-engine-mpm.h"
33
#include "detect-engine-state.h"
34
#include "detect-engine-build.h"
35
#include "detect-dce-iface.h"
36
37
#include "flow.h"
38
#include "flow-var.h"
39
#include "flow-util.h"
40
41
#include "app-layer.h"
42
#include "queue.h"
43
#include "stream-tcp-reassemble.h"
44
45
#include "util-debug.h"
46
#include "util-unittest.h"
47
#include "util-unittest-helper.h"
48
#include "stream-tcp.h"
49
50
#include "rust.h"
51
52
39
#define PARSE_REGEX "^\\s*([0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12})(?:\\s*,\\s*(<|>|=|!)([0-9]{1,5}))?(?:\\s*,\\s*(any_frag))?\\s*$"
53
54
static DetectParseRegex parse_regex;
55
56
static int DetectDceIfaceMatchRust(DetectEngineThreadCtx *det_ctx,
57
        Flow *f, uint8_t flags, void *state, void *txv,
58
        const Signature *s, const SigMatchCtx *m);
59
static int DetectDceIfaceSetup(DetectEngineCtx *, Signature *, const char *);
60
static void DetectDceIfaceFree(DetectEngineCtx *, void *);
61
static int g_dce_generic_list_id = 0;
62
63
/**
64
 * \brief Registers the keyword handlers for the "dce_iface" keyword.
65
 */
66
void DetectDceIfaceRegister(void)
67
39
{
68
39
    sigmatch_table[DETECT_DCE_IFACE].name = "dcerpc.iface";
69
39
    sigmatch_table[DETECT_DCE_IFACE].alias = "dce_iface";
70
39
    sigmatch_table[DETECT_DCE_IFACE].AppLayerTxMatch = DetectDceIfaceMatchRust;
71
39
    sigmatch_table[DETECT_DCE_IFACE].Setup = DetectDceIfaceSetup;
72
39
    sigmatch_table[DETECT_DCE_IFACE].Free = DetectDceIfaceFree;
73
39
    sigmatch_table[DETECT_DCE_IFACE].desc =
74
39
            "match on the value of the interface UUID in a DCERPC header";
75
39
    sigmatch_table[DETECT_DCE_IFACE].url = "/rules/dcerpc-keywords.html#dcerpc-iface";
76
39
    DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
77
78
39
    g_dce_generic_list_id = DetectBufferTypeRegister("dce_generic");
79
80
39
    DetectAppLayerInspectEngineRegister("dce_generic", ALPROTO_DCERPC, SIG_FLAG_TOSERVER, 0,
81
39
            DetectEngineInspectGenericList, NULL);
82
39
    DetectAppLayerInspectEngineRegister(
83
39
            "dce_generic", ALPROTO_SMB, SIG_FLAG_TOSERVER, 0, DetectEngineInspectGenericList, NULL);
84
85
39
    DetectAppLayerInspectEngineRegister("dce_generic", ALPROTO_DCERPC, SIG_FLAG_TOCLIENT, 0,
86
39
            DetectEngineInspectGenericList, NULL);
87
39
    DetectAppLayerInspectEngineRegister(
88
39
            "dce_generic", ALPROTO_SMB, SIG_FLAG_TOCLIENT, 0, DetectEngineInspectGenericList, NULL);
89
39
}
90
91
/**
92
 * \brief App layer match function for the "dce_iface" keyword.
93
 *
94
 * \param t       Pointer to the ThreadVars instance.
95
 * \param det_ctx Pointer to the DetectEngineThreadCtx.
96
 * \param f       Pointer to the flow.
97
 * \param flags   Pointer to the flags indicating the flow direction.
98
 * \param state   Pointer to the app layer state data.
99
 * \param s       Pointer to the Signature instance.
100
 * \param m       Pointer to the SigMatch.
101
 *
102
 * \retval 1 On Match.
103
 * \retval 0 On no match.
104
 */
105
static int DetectDceIfaceMatchRust(DetectEngineThreadCtx *det_ctx,
106
        Flow *f, uint8_t flags, void *state, void *txv,
107
        const Signature *s, const SigMatchCtx *m)
108
0
{
109
0
    SCEnter();
110
111
0
    if (f->alproto == ALPROTO_DCERPC) {
112
        // TODO check if state is NULL
113
0
        return SCDcerpcIfaceMatch(txv, state, (void *)m);
114
0
    }
115
116
0
    int ret = 0;
117
118
0
    if (SCSmbTxGetDceIface(f->alstate, txv, (void *)m) != 1) {
119
0
        SCLogDebug("SCSmbTxGetDceIface: didn't match");
120
0
    } else {
121
0
        SCLogDebug("SCSmbTxGetDceIface: matched!");
122
0
        ret = 1;
123
        // TODO validate frag
124
0
    }
125
0
    SCReturnInt(ret);
126
0
}
127
128
/**
129
 * \brief Creates a SigMatch for the "dce_iface" keyword being sent as argument,
130
 *        and appends it to the Signature(s).
131
 *
132
 * \param de_ctx Pointer to the detection engine context.
133
 * \param s      Pointer to signature for the current Signature being parsed
134
 *               from the rules.
135
 * \param arg    Pointer to the string holding the keyword value.
136
 *
137
 * \retval 0 on success, -1 on failure.
138
 */
139
140
static int DetectDceIfaceSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
141
1.69k
{
142
1.69k
    SCEnter();
143
144
1.69k
    if (SCDetectSignatureSetAppProto(s, ALPROTO_DCERPC) < 0)
145
6
        return -1;
146
147
1.68k
    void *did = SCDcerpcIfaceParse(arg);
148
1.68k
    if (did == NULL) {
149
356
        SCLogError("Error parsing dce_iface option in "
150
356
                   "signature");
151
356
        return -1;
152
356
    }
153
154
1.32k
    if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_DCE_IFACE, did, g_dce_generic_list_id) == NULL) {
155
0
        DetectDceIfaceFree(de_ctx, did);
156
0
        return -1;
157
0
    }
158
1.32k
    return 0;
159
1.32k
}
160
161
static void DetectDceIfaceFree(DetectEngineCtx *de_ctx, void *ptr)
162
1.32k
{
163
1.32k
    SCEnter();
164
1.32k
    if (ptr != NULL) {
165
1.32k
        SCDcerpcIfaceFree(ptr);
166
1.32k
    }
167
1.32k
    SCReturn;
168
1.32k
}