suricata
detect-ftpbounce.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 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 Pablo Rincon <pablo.rincon.crespo@gmail.com>
22  *
23  * ftpbounce keyword, part of the detection engine.
24  */
25 
26 #include "suricata-common.h"
27 #include "decode.h"
28 #include "detect.h"
29 #include "detect-parse.h"
30 #include "detect-engine.h"
31 #include "detect-engine-mpm.h"
32 #include "detect-engine-state.h"
33 #include "detect-content.h"
34 #include "detect-engine-build.h"
35 
36 #include "app-layer.h"
37 #include "app-layer-parser.h"
38 #include "app-layer-ftp.h"
39 #include "util-unittest-helper.h"
40 #include "util-debug.h"
41 #include "flow.h"
42 #include "flow-var.h"
43 #include "flow-util.h"
44 #include "threads.h"
45 #include "detect-ftpbounce.h"
46 #include "stream-tcp.h"
47 #include "util-byte.h"
48 
49 static int DetectFtpbounceALMatch(DetectEngineThreadCtx *,
50  Flow *, uint8_t, void *, void *,
51  const Signature *, const SigMatchCtx *);
52 
53 static int DetectFtpbounceSetup(DetectEngineCtx *, Signature *, const char *);
54 static int g_ftp_request_list_id = 0;
55 
56 /**
57  * \brief Registration function for ftpbounce: keyword
58  * \todo add support for no_stream and stream_only
59  */
61 {
62  sigmatch_table[DETECT_FTPBOUNCE].name = "ftpbounce";
63  sigmatch_table[DETECT_FTPBOUNCE].desc = "detect FTP bounce attacks";
64  sigmatch_table[DETECT_FTPBOUNCE].Setup = DetectFtpbounceSetup;
65  sigmatch_table[DETECT_FTPBOUNCE].AppLayerTxMatch = DetectFtpbounceALMatch;
66  sigmatch_table[DETECT_FTPBOUNCE].url = "/rules/ftp-keywords.html#ftpbounce";
68 
69  g_ftp_request_list_id = DetectBufferTypeGetByName("ftp:request_complete:generic");
70 }
71 
72 /**
73  * \brief This function is used to match ftpbounce attacks
74  *
75  * \param payload Payload of the PORT command
76  * \param payload_len Length of the payload
77  * \param ip_orig IP source to check the ftpbounce condition
78  * \param offset offset to the arguments of the PORT command
79  *
80  * \retval 1 if ftpbounce detected, 0 if not
81  */
82 static int DetectFtpbounceMatchArgs(
83  uint8_t *payload, uint32_t payload_len, uint32_t ip_orig, uint32_t offset)
84 {
85  SCEnter();
86  SCLogDebug("Checking ftpbounce condition");
87  char *c = NULL;
88  uint32_t i = 0;
89  int octet = 0;
90  int octet_ascii_len = 0;
91  int noctet = 0;
92  uint32_t ip = 0;
93  /* PrintRawDataFp(stdout, payload, payload_len); */
94 
95  if (payload_len < 7) {
96  /* we need at least a different ip address
97  * in the format 1,2,3,4,x,y where x,y is the port
98  * in two byte representation so let's look at
99  * least for the IP octets in comma separated */
100  return 0;
101  }
102 
103  if (offset + 7 >= payload_len)
104  return 0;
105 
106  c =(char*) payload;
107  if (c == NULL) {
108  SCLogDebug("No payload to check");
109  return 0;
110  }
111 
112  i = offset;
113  /* Search for the first IP octect(Skips "PORT ") */
114  while (i < payload_len && !isdigit((unsigned char)c[i])) i++;
115 
116  for (;i < payload_len && octet_ascii_len < 4 ;i++) {
117  if (isdigit((unsigned char)c[i])) {
118  octet =(c[i] - '0') + octet * 10;
119  octet_ascii_len++;
120  } else {
121  if (octet > 256) {
122  SCLogDebug("Octet not in ip format");
123  return 0;
124  }
125 
126  if (isspace((unsigned char)c[i]))
127  while (i < payload_len && isspace((unsigned char)c[i]) ) i++;
128 
129  if (i < payload_len && c[i] == ',') { /* we have an octet */
130  noctet++;
131  octet_ascii_len = 0;
132  ip =(ip << 8) + octet;
133  octet = 0;
134  } else {
135  SCLogDebug("Unrecognized character '%c'", c[i]);
136  return 0;
137  }
138  if (noctet == 4) {
139  /* Different IP than src, ftp bounce scan */
140  ip = SCNtohl(ip);
141 
142  if (ip != ip_orig) {
143  SCLogDebug("Different ip, so Matched ip:%d <-> ip_orig:%d",
144  ip, ip_orig);
145  return 1;
146  }
147  SCLogDebug("Same ip, so no match here");
148  return 0;
149  }
150  }
151  }
152  SCLogDebug("No match");
153  return 0;
154 }
155 
156 /**
157  * \brief This function is used to check matches from the FTP App Layer Parser
158  *
159  * \param t pointer to thread vars
160  * \param det_ctx pointer to the pattern matcher thread
161  * \param p pointer to the current packet
162  * \param m pointer to the sigmatch but we don't use it since ftpbounce
163  * has no options
164  * \retval 0 no match
165  * \retval 1 match
166  */
167 static int DetectFtpbounceALMatch(DetectEngineThreadCtx *det_ctx,
168  Flow *f, uint8_t flags,
169  void *state, void *txv,
170  const Signature *s, const SigMatchCtx *m)
171 {
172  SCEnter();
173 
174  FtpState *ftp_state = (FtpState *)state;
175  if (ftp_state == NULL) {
176  SCLogDebug("no ftp state, no match");
177  SCReturnInt(0);
178  }
179 
180  int ret = 0;
181  if (ftp_state->command == FTP_COMMAND_PORT) {
182  ret = DetectFtpbounceMatchArgs(ftp_state->port_line,
183  ftp_state->port_line_len, f->src.address.address_un_data32[0],
184  ftp_state->arg_offset);
185  }
186 
187  SCReturnInt(ret);
188 }
189 
190 /**
191  * \brief this function is used to add the parsed ftpbounce
192  *
193  * \param de_ctx pointer to the Detection Engine Context
194  * \param s pointer to the Current Signature
195  * \param m pointer to the Current SigMatch
196  * \param ftpbouncestr pointer to the user provided ftpbounce options
197  * currently there are no options.
198  *
199  * \retval 0 on Success
200  * \retval -1 on Failure
201  */
202 int DetectFtpbounceSetup(DetectEngineCtx *de_ctx, Signature *s, const char *ftpbouncestr)
203 {
204  SCEnter();
205 
207  return -1;
208 
209  /* We don't need to allocate any data for ftpbounce here.
210  *
211  * TODO: As a suggestion, maybe we can add a flag in the flow
212  * to set the stream as "bounce detected" for fast Match.
213  * When you do a ftp bounce attack you usually use the same
214  * communication control stream to "setup" various destinations
215  * without breaking the connection, so I guess we can make it a bit faster
216  * with a flow flag set lookup in the Match function.
217  */
218 
219  if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_FTPBOUNCE, NULL, g_ftp_request_list_id) ==
220  NULL) {
221  return -1;
222  }
223  SCReturnInt(0);
224 }
util-byte.h
SigTableElmt_::url
const char * url
Definition: detect.h:1545
detect-content.h
detect-engine.h
SIGMATCH_NOOPT
#define SIGMATCH_NOOPT
Definition: detect-engine-register.h:308
SigTableElmt_::desc
const char * desc
Definition: detect.h:1544
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:78
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
flow-util.h
SigTableElmt_::name
const char * name
Definition: detect.h:1542
stream-tcp.h
SigTableElmt_::flags
uint32_t flags
Definition: detect.h:1533
FlowAddress_::address_un_data32
uint32_t address_un_data32[4]
Definition: flow.h:323
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
DETECT_FTPBOUNCE
@ DETECT_FTPBOUNCE
Definition: detect-engine-register.h:115
FtpState_::command
FtpRequestCommand command
Definition: app-layer-ftp.h:100
threads.h
Flow_
Flow data structure.
Definition: flow.h:359
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:995
detect-ftpbounce.h
SigTableElmt_::AppLayerTxMatch
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1507
ALPROTO_FTP
@ ALPROTO_FTP
Definition: app-layer-protos.h:37
m
SCMutex m
Definition: flow-hash.h:6
SCDetectSignatureSetAppProto
int SCDetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:2613
app-layer-ftp.h
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1524
util-unittest-helper.h
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1452
FtpState_
Definition: app-layer-ftp.h:90
decode.h
util-debug.h
FtpState_::port_line
uint8_t * port_line
Definition: app-layer-ftp.h:104
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:22
DetectEngineThreadCtx_
Definition: detect.h:1316
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
detect-engine-mpm.h
SCSigMatchAppendSMToList
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:424
detect.h
app-layer-parser.h
detect-engine-build.h
FtpState_::arg_offset
FtpRequestCommandArgOfs arg_offset
Definition: app-layer-ftp.h:101
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
DetectFtpbounceRegister
void DetectFtpbounceRegister(void)
Registration function for ftpbounce: keyword.
Definition: detect-ftpbounce.c:60
Flow_::src
FlowAddress src
Definition: flow.h:362
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:355
flags
uint8_t flags
Definition: decode-gre.h:0
suricata-common.h
FtpState_::port_line_len
uint32_t port_line_len
Definition: app-layer-ftp.h:102
SCNtohl
#define SCNtohl(x)
Definition: suricata-common.h:435
detect-parse.h
Signature_
Signature container.
Definition: detect.h:692
payload_len
uint16_t payload_len
Definition: stream-tcp-private.h:1
FlowAddress_::address
union FlowAddress_::@125 address
SIGMATCH_SUPPORT_FIREWALL
#define SIGMATCH_SUPPORT_FIREWALL
Definition: detect-engine-register.h:336
flow.h
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:288
flow-var.h
app-layer.h
f
Flow f
Definition: fuzz_dataset.c:32