|
|
|
@ -47,13 +47,19 @@
|
|
|
|
|
#include "stream-tcp.h"
|
|
|
|
|
#include "util-byte.h"
|
|
|
|
|
|
|
|
|
|
static int DetectFtpbounceALMatch(ThreadVars *, DetectEngineThreadCtx *, Flow *,
|
|
|
|
|
uint8_t, void *, const Signature *, const SigMatchData *);
|
|
|
|
|
static int DetectFtpbounceALMatch(ThreadVars *, DetectEngineThreadCtx *,
|
|
|
|
|
Flow *, uint8_t, void *, void *,
|
|
|
|
|
const Signature *, const SigMatchCtx *);
|
|
|
|
|
|
|
|
|
|
static int DetectFtpbounceSetup(DetectEngineCtx *, Signature *, char *);
|
|
|
|
|
static int DetectFtpbounceMatchArgs(uint8_t *payload, uint16_t payload_len,
|
|
|
|
|
uint32_t ip_orig, uint16_t offset);
|
|
|
|
|
void DetectFtpbounceRegisterTests(void);
|
|
|
|
|
void DetectFtpbounceFree(void *);
|
|
|
|
|
static void DetectFtpbounceRegisterTests(void);
|
|
|
|
|
static int g_ftp_request_list_id = 0;
|
|
|
|
|
|
|
|
|
|
static int InspectFtpRequest(ThreadVars *tv,
|
|
|
|
|
DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
|
|
|
|
|
const Signature *s, const SigMatchData *smd,
|
|
|
|
|
Flow *f, uint8_t flags, void *alstate,
|
|
|
|
|
void *txv, uint64_t tx_id);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Registration function for ftpbounce: keyword
|
|
|
|
@ -63,12 +69,24 @@ void DetectFtpbounceRegister(void)
|
|
|
|
|
{
|
|
|
|
|
sigmatch_table[DETECT_FTPBOUNCE].name = "ftpbounce";
|
|
|
|
|
sigmatch_table[DETECT_FTPBOUNCE].Setup = DetectFtpbounceSetup;
|
|
|
|
|
sigmatch_table[DETECT_FTPBOUNCE].Match = NULL;
|
|
|
|
|
sigmatch_table[DETECT_FTPBOUNCE].AppLayerMatch = DetectFtpbounceALMatch;
|
|
|
|
|
sigmatch_table[DETECT_FTPBOUNCE].Free = NULL;
|
|
|
|
|
sigmatch_table[DETECT_FTPBOUNCE].AppLayerTxMatch = DetectFtpbounceALMatch;
|
|
|
|
|
sigmatch_table[DETECT_FTPBOUNCE].RegisterTests = DetectFtpbounceRegisterTests;
|
|
|
|
|
sigmatch_table[DETECT_FTPBOUNCE].flags = SIGMATCH_NOOPT;
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
g_ftp_request_list_id = DetectBufferTypeRegister("ftp_request");
|
|
|
|
|
|
|
|
|
|
DetectAppLayerInspectEngineRegister("ftp_request",
|
|
|
|
|
ALPROTO_FTP, SIG_FLAG_TOSERVER, InspectFtpRequest);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int InspectFtpRequest(ThreadVars *tv,
|
|
|
|
|
DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
|
|
|
|
|
const Signature *s, const SigMatchData *smd,
|
|
|
|
|
Flow *f, uint8_t flags, void *alstate,
|
|
|
|
|
void *txv, uint64_t tx_id)
|
|
|
|
|
{
|
|
|
|
|
return DetectEngineInspectGenericList(tv, de_ctx, det_ctx, s, smd,
|
|
|
|
|
f, flags, alstate, txv, tx_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -167,18 +185,19 @@ static int DetectFtpbounceMatchArgs(uint8_t *payload, uint16_t payload_len,
|
|
|
|
|
* \retval 1 match
|
|
|
|
|
*/
|
|
|
|
|
static int DetectFtpbounceALMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
|
|
|
|
|
Flow *f, uint8_t flags, void *state, const Signature *s,
|
|
|
|
|
const SigMatchData *m)
|
|
|
|
|
Flow *f, uint8_t flags,
|
|
|
|
|
void *state, void *txv,
|
|
|
|
|
const Signature *s, const SigMatchCtx *m)
|
|
|
|
|
{
|
|
|
|
|
SCEnter();
|
|
|
|
|
FtpState *ftp_state =(FtpState *)state;
|
|
|
|
|
|
|
|
|
|
FtpState *ftp_state = (FtpState *)state;
|
|
|
|
|
if (ftp_state == NULL) {
|
|
|
|
|
SCLogDebug("no ftp state, no match");
|
|
|
|
|
SCReturnInt(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
if (ftp_state->command == FTP_COMMAND_PORT) {
|
|
|
|
|
ret = DetectFtpbounceMatchArgs(ftp_state->port_line,
|
|
|
|
|
ftp_state->port_line_len, f->src.address.address_un_data32[0],
|
|
|
|
@ -206,9 +225,14 @@ int DetectFtpbounceSetup(DetectEngineCtx *de_ctx, Signature *s, char *ftpbounces
|
|
|
|
|
|
|
|
|
|
SigMatch *sm = NULL;
|
|
|
|
|
|
|
|
|
|
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_FTP) {
|
|
|
|
|
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords.");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sm = SigMatchAlloc();
|
|
|
|
|
if (sm == NULL) {
|
|
|
|
|
goto error;;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sm->type = DETECT_FTPBOUNCE;
|
|
|
|
@ -224,22 +248,11 @@ int DetectFtpbounceSetup(DetectEngineCtx *de_ctx, Signature *s, char *ftpbounces
|
|
|
|
|
*/
|
|
|
|
|
sm->ctx = NULL;
|
|
|
|
|
|
|
|
|
|
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_FTP) {
|
|
|
|
|
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords.");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH);
|
|
|
|
|
SigMatchAppendSMToList(s, sm, g_ftp_request_list_id);
|
|
|
|
|
|
|
|
|
|
s->alproto = ALPROTO_FTP;
|
|
|
|
|
s->flags |= SIG_FLAG_APPLAYER;
|
|
|
|
|
SCReturnInt(0);
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
if (sm != NULL) {
|
|
|
|
|
SigMatchFree(sm);
|
|
|
|
|
}
|
|
|
|
|
SCReturnInt(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef UNITTESTS
|
|
|
|
@ -247,20 +260,19 @@ error:
|
|
|
|
|
/**
|
|
|
|
|
* \test DetectFtpbounceTestSetup01 is a test for the Setup ftpbounce
|
|
|
|
|
*/
|
|
|
|
|
int DetectFtpbounceTestSetup01(void)
|
|
|
|
|
static int DetectFtpbounceTestSetup01(void)
|
|
|
|
|
{
|
|
|
|
|
int res = 0;
|
|
|
|
|
DetectEngineCtx *de_ctx = NULL;
|
|
|
|
|
Signature *s = SigAlloc();
|
|
|
|
|
if (s == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
FAIL_IF (s == NULL);
|
|
|
|
|
|
|
|
|
|
/* ftpbounce doesn't accept options so the str is NULL */
|
|
|
|
|
res = !DetectFtpbounceSetup(de_ctx, s, NULL);
|
|
|
|
|
res &= s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL && s->sm_lists[DETECT_SM_LIST_AMATCH]->type & DETECT_FTPBOUNCE;
|
|
|
|
|
FAIL_IF_NOT(DetectFtpbounceSetup(de_ctx, s, NULL) == 0);
|
|
|
|
|
FAIL_IF(s->sm_lists[g_ftp_request_list_id] == NULL);
|
|
|
|
|
FAIL_IF_NOT(s->sm_lists[g_ftp_request_list_id]->type & DETECT_FTPBOUNCE);
|
|
|
|
|
|
|
|
|
|
SigFree(s);
|
|
|
|
|
return res;
|
|
|
|
|
PASS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#include "stream-tcp-reassemble.h"
|
|
|
|
|