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"
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
50static int DetectFtpbounceALMatch(DetectEngineThreadCtx *,
51 Flow *, uint8_t, void *, void *,
52 const Signature *, const SigMatchCtx *);
53
54static int DetectFtpbounceSetup(DetectEngineCtx *, Signature *, const char *);
55static 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{
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 = DetectBufferTypeGetByName("ftp:request_complete:generic");
71}
72
73/**
74 * \brief This function is used to match ftpbounce attacks
75 *
76 * \param payload Payload of the PORT command
77 * \param payload_len Length of the payload
78 * \param ip_orig IP source to check the ftpbounce condition
79 * \param offset offset to the arguments of the PORT command
80 *
81 * \retval 1 if ftpbounce detected, 0 if not
82 */
83static int DetectFtpbounceMatchArgs(
84 uint8_t *payload, uint32_t payload_len, uint32_t ip_orig, uint32_t offset)
85{
86 SCEnter();
87 SCLogDebug("Checking ftpbounce condition");
88 char *c = NULL;
89 uint32_t i = 0;
90 int octet = 0;
91 int octet_ascii_len = 0;
92 int noctet = 0;
93 uint32_t ip = 0;
94 /* PrintRawDataFp(stdout, payload, payload_len); */
95
96 if (payload_len < 7) {
97 /* we need at least a different ip address
98 * in the format 1,2,3,4,x,y where x,y is the port
99 * in two byte representation so let's look at
100 * least for the IP octets in comma separated */
101 return 0;
102 }
103
104 if (offset + 7 >= payload_len)
105 return 0;
106
107 c =(char*) payload;
108 if (c == NULL) {
109 SCLogDebug("No payload to check");
110 return 0;
111 }
112
113 i = offset;
114 /* Search for the first IP octect(Skips "PORT ") */
115 while (i < payload_len && !isdigit((unsigned char)c[i])) i++;
116
117 for (;i < payload_len && octet_ascii_len < 4 ;i++) {
118 if (isdigit((unsigned char)c[i])) {
119 octet =(c[i] - '0') + octet * 10;
120 octet_ascii_len++;
121 } else {
122 if (octet > 256) {
123 SCLogDebug("Octet not in ip format");
124 return 0;
125 }
126
127 if (isspace((unsigned char)c[i]))
128 while (i < payload_len && isspace((unsigned char)c[i]) ) i++;
129
130 if (i < payload_len && c[i] == ',') { /* we have an octet */
131 noctet++;
132 octet_ascii_len = 0;
133 ip =(ip << 8) + octet;
134 octet = 0;
135 } else {
136 SCLogDebug("Unrecognized character '%c'", c[i]);
137 return 0;
138 }
139 if (noctet == 4) {
140 /* Different IP than src, ftp bounce scan */
141 ip = SCNtohl(ip);
142
143 if (ip != ip_orig) {
144 SCLogDebug("Different ip, so Matched ip:%d <-> ip_orig:%d",
145 ip, ip_orig);
146 return 1;
147 }
148 SCLogDebug("Same ip, so no match here");
149 return 0;
150 }
151 }
152 }
153 SCLogDebug("No match");
154 return 0;
155}
156
157/**
158 * \brief This function is used to check matches from the FTP App Layer Parser
159 *
160 * \param t pointer to thread vars
161 * \param det_ctx pointer to the pattern matcher thread
162 * \param p pointer to the current packet
163 * \param m pointer to the sigmatch but we don't use it since ftpbounce
164 * has no options
165 * \retval 0 no match
166 * \retval 1 match
167 */
168static int DetectFtpbounceALMatch(DetectEngineThreadCtx *det_ctx,
169 Flow *f, uint8_t flags,
170 void *state, void *txv,
171 const Signature *s, const SigMatchCtx *m)
172{
173 SCEnter();
174
175 FtpState *ftp_state = (FtpState *)state;
176 if (ftp_state == NULL) {
177 SCLogDebug("no ftp state, no match");
178 SCReturnInt(0);
179 }
180
181 int ret = 0;
182 if (ftp_state->command == FTP_COMMAND_PORT) {
183 ret = DetectFtpbounceMatchArgs(ftp_state->port_line,
184 ftp_state->port_line_len, f->src.address.address_un_data32[0],
185 ftp_state->arg_offset);
186 }
187
188 SCReturnInt(ret);
189}
190
191/**
192 * \brief this function is used to add the parsed ftpbounce
193 *
194 * \param de_ctx pointer to the Detection Engine Context
195 * \param s pointer to the Current Signature
196 * \param m pointer to the Current SigMatch
197 * \param ftpbouncestr pointer to the user provided ftpbounce options
198 * currently there are no options.
199 *
200 * \retval 0 on Success
201 * \retval -1 on Failure
202 */
203int DetectFtpbounceSetup(DetectEngineCtx *de_ctx, Signature *s, const char *ftpbouncestr)
204{
205 SCEnter();
206
208 return -1;
209
210 /* We don't need to allocate any data for ftpbounce here.
211 *
212 * TODO: As a suggestion, maybe we can add a flag in the flow
213 * to set the stream as "bounce detected" for fast Match.
214 * When you do a ftp bounce attack you usually use the same
215 * communication control stream to "setup" various destinations
216 * without breaking the connection, so I guess we can make it a bit faster
217 * with a flow flag set lookup in the Match function.
218 */
219
220 if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_FTPBOUNCE, NULL, g_ftp_request_list_id) ==
221 NULL) {
222 return -1;
223 }
224 SCReturnInt(0);
225}
@ ALPROTO_FTP
uint8_t flags
Definition decode-gre.h:0
Data structures and function prototypes for keeping state for the detection engine.
int DetectBufferTypeGetByName(const char *name)
void DetectFtpbounceRegister(void)
Registration function for ftpbounce: keyword.
int SCDetectSignatureSetAppProto(Signature *s, AppProto alproto)
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
SigTableElmt * sigmatch_table
#define SIGMATCH_NOOPT
Definition detect.h:1651
SCMutex m
Definition flow-hash.h:6
DetectEngineCtx * de_ctx
uint16_t payload_len
main detection engine ctx
Definition detect.h:932
uint32_t address_un_data32[4]
Definition flow.h:320
union FlowAddress_::@128 address
Flow data structure.
Definition flow.h:356
FlowAddress src
Definition flow.h:359
FtpRequestCommandArgOfs arg_offset
uint32_t port_line_len
FtpRequestCommand command
uint8_t * port_line
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition detect.h:351
const char * url
Definition detect.h:1462
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
uint16_t flags
Definition detect.h:1450
const char * desc
Definition detect.h:1461
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition detect.h:1424
const char * name
Definition detect.h:1459
Signature container.
Definition detect.h:668
#define SCNtohl(x)
#define SCEnter(...)
Definition util-debug.h:277
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnInt(x)
Definition util-debug.h:281
uint64_t offset