suricata
app-layer-smb.c
Go to the documentation of this file.
1 /* Copyright (C) 2017-2021 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  * SMB protocol handling
22  */
23 
24 #include "suricata-common.h"
25 #include "suricata.h"
26 
27 #include "app-layer-protos.h"
28 #include "app-layer-detect-proto.h"
29 #include "app-layer-parser.h"
30 
31 #include "util-unittest.h"
32 
33 #include "rust.h"
34 #include "app-layer-smb.h"
35 #include "util-misc.h"
36 
37 
39 static SuricataFileContext sfc = { &sbcfg };
40 
41 #ifdef UNITTESTS
42 static void SMBParserRegisterTests(void);
43 #endif
44 
46 {
47  rs_smb_init(&sfc);
48  rs_smb_register_parser();
49 
50 #ifdef UNITTESTS
51  AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_SMB, SMBParserRegisterTests);
52 #endif
53 }
54 
55 #ifdef UNITTESTS
56 #include "stream-tcp.h"
57 #include "util-unittest-helper.h"
58 
59 /** \test multi transactions and cleanup */
60 static int SMBParserTxCleanupTest(void)
61 {
62  uint64_t ret[4];
65 
66  StreamTcpInitConfig(true);
67  TcpSession ssn;
68  memset(&ssn, 0, sizeof(ssn));
69 
70  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 445);
71  FAIL_IF_NULL(f);
72  f->protoctx = &ssn;
73  f->proto = IPPROTO_TCP;
74  f->alproto = ALPROTO_SMB;
76 
77  char req_str[] ="\x00\x00\x00\x79\xfe\x53\x4d\x42\x40\x00\x01\x00\x00\x00\x00\x00" \
78  "\x05\x00\xe0\x1e\x10\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00" \
79  "\x00\x00\x00\x00\x00\x00\x00\x00\x10\x72\xd2\x9f\x36\xc2\x08\x14" \
80  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
81  "\x00\x00\x00\x00\x39\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00" \
82  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00" \
83  "\x00\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" \
84  "\x78\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
85  req_str[28] = 0x01;
86  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_SMB,
87  STREAM_TOSERVER | STREAM_START, (uint8_t *)req_str, sizeof(req_str));
88  FAIL_IF_NOT(r == 0);
89  req_str[28]++;
91  STREAM_TOSERVER, (uint8_t *)req_str, sizeof(req_str));
92  FAIL_IF_NOT(r == 0);
93  req_str[28]++;
95  STREAM_TOSERVER, (uint8_t *)req_str, sizeof(req_str));
96  FAIL_IF_NOT(r == 0);
97  req_str[28]++;
99  STREAM_TOSERVER, (uint8_t *)req_str, sizeof(req_str));
100  FAIL_IF_NOT(r == 0);
101  req_str[28]++;
103  STREAM_TOSERVER, (uint8_t *)req_str, sizeof(req_str));
104  FAIL_IF_NOT(r == 0);
105  req_str[28]++;
107  STREAM_TOSERVER, (uint8_t *)req_str, sizeof(req_str));
108  FAIL_IF_NOT(r == 0);
109  req_str[28]++;
111  STREAM_TOSERVER, (uint8_t *)req_str, sizeof(req_str));
112  FAIL_IF_NOT(r == 0);
113  req_str[28]++;
115  STREAM_TOSERVER, (uint8_t *)req_str, sizeof(req_str));
116  FAIL_IF_NOT(r == 0);
117  req_str[28]++;
118 
119  AppLayerParserTransactionsCleanup(f, STREAM_TOSERVER);
120  UTHAppLayerParserStateGetIds(f->alparser, &ret[0], &ret[1], &ret[2], &ret[3]);
121  FAIL_IF_NOT(ret[0] == 0); // inspect_id[0]
122  FAIL_IF_NOT(ret[1] == 0); // inspect_id[1]
123  FAIL_IF_NOT(ret[2] == 0); // log_id
124  FAIL_IF_NOT(ret[3] == 0); // min_id
125 
126  char resp_str[] = "\x00\x00\x00\x98\xfe\x53\x4d\x42\x40\x00\x01\x00\x00\x00\x00\x00" \
127  "\x05\x00\x21\x00\x11\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00" \
128  "\x00\x00\x00\x00\x00\x00\x00\x00\x10\x72\xd2\x9f\x36\xc2\x08\x14" \
129  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
130  "\x00\x00\x00\x00\x59\x00\x00\x00\x01\x00\x00\x00\x48\x38\x40\xb3" \
131  "\x0f\xa8\xd3\x01\x84\x9a\x2b\x46\xf7\xa8\xd3\x01\x48\x38\x40\xb3" \
132  "\x0f\xa8\xd3\x01\x48\x38\x40\xb3\x0f\xa8\xd3\x01\x00\x00\x00\x00" \
133  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00" \
134  "\x00\x00\x00\x00\x9e\x8f\xb8\x91\x00\x00\x00\x00\x01\x5b\x11\xbb" \
135  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
136 
137  resp_str[28] = 0x01;
139  STREAM_TOCLIENT | STREAM_START, (uint8_t *)resp_str, sizeof(resp_str));
140  FAIL_IF_NOT(r == 0);
141  resp_str[28] = 0x04;
143  STREAM_TOCLIENT, (uint8_t *)resp_str, sizeof(resp_str));
144  FAIL_IF_NOT(r == 0);
145  resp_str[28] = 0x05;
147  STREAM_TOCLIENT, (uint8_t *)resp_str, sizeof(resp_str));
148  FAIL_IF_NOT(r == 0);
149  resp_str[28] = 0x06;
151  STREAM_TOCLIENT, (uint8_t *)resp_str, sizeof(resp_str));
152  FAIL_IF_NOT(r == 0);
153  resp_str[28] = 0x08;
155  STREAM_TOCLIENT, (uint8_t *)resp_str, sizeof(resp_str));
156  FAIL_IF_NOT(r == 0);
157  resp_str[28] = 0x02;
159  STREAM_TOCLIENT, (uint8_t *)resp_str, sizeof(resp_str));
160  FAIL_IF_NOT(r == 0);
161  resp_str[28] = 0x07;
163  STREAM_TOCLIENT, (uint8_t *)resp_str, sizeof(resp_str));
164  FAIL_IF_NOT(r == 0);
165  AppLayerParserTransactionsCleanup(f, STREAM_TOCLIENT);
166 
167  UTHAppLayerParserStateGetIds(f->alparser, &ret[0], &ret[1], &ret[2], &ret[3]);
168  FAIL_IF_NOT(ret[0] == 2); // inspect_id[0]
169  FAIL_IF_NOT(ret[1] == 2); // inspect_id[1]
170  FAIL_IF_NOT(ret[2] == 2); // log_id
171  FAIL_IF_NOT(ret[3] == 2); // min_id
172 
173  resp_str[28] = 0x03;
175  STREAM_TOCLIENT, (uint8_t *)resp_str, sizeof(resp_str));
176  FAIL_IF_NOT(r == 0);
177  AppLayerParserTransactionsCleanup(f, STREAM_TOCLIENT);
178 
179  UTHAppLayerParserStateGetIds(f->alparser, &ret[0], &ret[1], &ret[2], &ret[3]);
180  FAIL_IF_NOT(ret[0] == 8); // inspect_id[0]
181  FAIL_IF_NOT(ret[1] == 8); // inspect_id[1]
182  FAIL_IF_NOT(ret[2] == 8); // log_id
183  FAIL_IF_NOT(ret[3] == 8); // min_id
184 
185  req_str[28] = 0x09;
187  STREAM_TOSERVER | STREAM_EOF, (uint8_t *)req_str, sizeof(req_str));
188  FAIL_IF_NOT(r == 0);
189  AppLayerParserTransactionsCleanup(f, STREAM_TOSERVER);
190 
191  UTHAppLayerParserStateGetIds(f->alparser, &ret[0], &ret[1], &ret[2], &ret[3]);
192  FAIL_IF_NOT(ret[0] == 8); // inspect_id[0] not updated by ..Cleanup() until full tx is done
193  FAIL_IF_NOT(ret[1] == 8); // inspect_id[1]
194  FAIL_IF_NOT(ret[2] == 8); // log_id
195  FAIL_IF_NOT(ret[3] == 8); // min_id
196 
197  resp_str[28] = 0x09;
199  STREAM_TOCLIENT | STREAM_EOF, (uint8_t *)resp_str, sizeof(resp_str));
200  FAIL_IF_NOT(r == 0);
201  AppLayerParserTransactionsCleanup(f, STREAM_TOCLIENT);
202 
203  UTHAppLayerParserStateGetIds(f->alparser, &ret[0], &ret[1], &ret[2], &ret[3]);
204  FAIL_IF_NOT(ret[0] == 9); // inspect_id[0]
205  FAIL_IF_NOT(ret[1] == 9); // inspect_id[1]
206  FAIL_IF_NOT(ret[2] == 9); // log_id
207  FAIL_IF_NOT(ret[3] == 9); // min_id
208 
210  StreamTcpFreeConfig(true);
211  UTHFreeFlow(f);
212 
213  PASS;
214 }
215 
216 static void SMBParserRegisterTests(void)
217 {
218  UtRegisterTest("SMBParserTxCleanupTest", SMBParserTxCleanupTest);
219 }
220 
221 #endif /* UNITTESTS */
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
RegisterSMBParsers
void RegisterSMBParsers(void)
Definition: app-layer-smb.c:45
stream-tcp.h
AppLayerParserTransactionsCleanup
void AppLayerParserTransactionsCleanup(Flow *f, const uint8_t pkt_dir)
remove obsolete (inspected and logged) transactions
Definition: app-layer-parser.c:879
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
FLOW_SGH_TOCLIENT
#define FLOW_SGH_TOCLIENT
Definition: flow.h:73
Flow_::proto
uint8_t proto
Definition: flow.h:376
STREAMING_BUFFER_CONFIG_INITIALIZER
#define STREAMING_BUFFER_CONFIG_INITIALIZER
Definition: util-streaming-buffer.h:74
Flow_
Flow data structure.
Definition: flow.h:354
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:317
rust.h
Flow_::protoctx
void * protoctx
Definition: flow.h:439
util-unittest.h
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:476
app-layer-detect-proto.h
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:488
UTHBuildFlow
Flow * UTHBuildFlow(int family, const char *src, const char *dst, Port sp, Port dp)
Definition: util-unittest-helper.c:482
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:22
app-layer-parser.h
AppLayerParserRegisterProtocolUnittests
void AppLayerParserRegisterProtocolUnittests(uint8_t ipproto, AppProto alproto, void(*RegisterUnittests)(void))
Definition: app-layer-parser.c:1801
UTHFreeFlow
void UTHFreeFlow(Flow *flow)
Definition: util-unittest-helper.c:487
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:290
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:859
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1271
suricata-common.h
StreamingBufferConfig_
Definition: util-streaming-buffer.h:65
SuricataFileContext_
Definition: rust-context.h:63
FLOW_SGH_TOSERVER
#define FLOW_SGH_TOSERVER
Definition: flow.h:71
Flow_::flags
uint32_t flags
Definition: flow.h:419
UTHAppLayerParserStateGetIds
void UTHAppLayerParserStateGetIds(void *ptr, uint64_t *i1, uint64_t *i2, uint64_t *log, uint64_t *min)
Definition: app-layer-parser.c:208
app-layer-protos.h
suricata.h
app-layer-smb.h
ALPROTO_SMB
@ ALPROTO_SMB
Definition: app-layer-protos.h:43
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:58
TcpSession_
Definition: stream-tcp-private.h:283
util-misc.h
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:448