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