mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3788 lines
104 KiB
C
3788 lines
104 KiB
C
/* Copyright (C) 2007-2010 Open Information Security Foundation
|
|
*
|
|
* You can copy, redistribute or modify this Program under the terms of
|
|
* the GNU General Public License version 2 as published by the Free
|
|
* Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* version 2 along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301, USA.
|
|
*/
|
|
|
|
/** \file
|
|
*
|
|
* \author Victor Julien <victor@inliniac.net>
|
|
* \author Pablo Rincon Crespo <pablo.rincon.crespo@gmail.com>
|
|
*
|
|
* Based on detect-engine-uri.c
|
|
*/
|
|
|
|
#include "suricata-common.h"
|
|
#include "suricata.h"
|
|
#include "decode.h"
|
|
|
|
#include "detect.h"
|
|
#include "detect-engine.h"
|
|
#include "detect-parse.h"
|
|
#include "detect-engine-state.h"
|
|
#include "detect-uricontent.h"
|
|
#include "detect-urilen.h"
|
|
#include "detect-pcre.h"
|
|
#include "detect-isdataat.h"
|
|
#include "detect-bytetest.h"
|
|
#include "detect-bytejump.h"
|
|
#include "detect-byte-extract.h"
|
|
|
|
#include "flow-util.h"
|
|
#include "util-spm.h"
|
|
#include "util-debug.h"
|
|
#include "util-print.h"
|
|
#include "flow.h"
|
|
#include "detect-flow.h"
|
|
#include "flow-var.h"
|
|
#include "threads.h"
|
|
#include "flow-alert-sid.h"
|
|
|
|
#include "stream-tcp.h"
|
|
#include "stream.h"
|
|
#include "app-layer-parser.h"
|
|
|
|
#include "util-unittest.h"
|
|
#include "util-unittest-helper.h"
|
|
#include "app-layer.h"
|
|
#include "app-layer-htp.h"
|
|
#include "app-layer-protos.h"
|
|
|
|
/**
|
|
* \brief Run the actual payload match function for uricontent.
|
|
*
|
|
* For accounting the last match in relative matching the
|
|
* det_ctx->payload_offset int is used.
|
|
*
|
|
* \param de_ctx Detection engine context.
|
|
* \param det_ctx Detection engine thread context.
|
|
* \param s Signature to inspect.
|
|
* \param sm SigMatch to inspect.
|
|
* \param payload Ptr to the uricontent payload to inspect.
|
|
* \param payload_len Length of the uricontent payload.
|
|
*
|
|
* \retval 0 no match.
|
|
* \retval 1 match.
|
|
*/
|
|
static int DoInspectPacketUri(DetectEngineCtx *de_ctx,
|
|
DetectEngineThreadCtx *det_ctx,
|
|
Signature *s, SigMatch *sm,
|
|
uint8_t *payload, uint32_t payload_len)
|
|
{
|
|
SCEnter();
|
|
|
|
det_ctx->inspection_recursion_counter++;
|
|
|
|
if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) {
|
|
det_ctx->discontinue_matching = 1;
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
if (sm == NULL) {
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
if (sm->type == DETECT_URICONTENT) {
|
|
if (payload_len == 0) {
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
DetectContentData *ud = NULL;
|
|
ud = (DetectContentData *)sm->ctx;
|
|
SCLogDebug("inspecting content %"PRIu32" payload_len %"PRIu32, ud->id, payload_len);
|
|
|
|
//if (ud->flags & DETECT_CONTENT_URI_MPM && !(ud->flags & DETECT_CONTENT_NEGATED))
|
|
// goto match;
|
|
|
|
/* rule parsers should take care of this */
|
|
#ifdef DEBUG
|
|
BUG_ON(ud->depth != 0 && ud->depth <= ud->offset);
|
|
#endif
|
|
|
|
/* search for our pattern, checking the matches recursively.
|
|
* if we match we look for the next SigMatch as well */
|
|
uint8_t *found = NULL;
|
|
uint32_t offset = 0;
|
|
uint32_t depth = payload_len;
|
|
uint32_t prev_offset = 0; /**< used in recursive searching */
|
|
uint32_t prev_payload_offset = det_ctx->payload_offset;
|
|
|
|
do {
|
|
if (ud->flags & DETECT_CONTENT_DISTANCE ||
|
|
ud->flags & DETECT_CONTENT_WITHIN) {
|
|
SCLogDebug("prev_payload_offset %"PRIu32, prev_payload_offset);
|
|
|
|
offset = prev_payload_offset;
|
|
depth = payload_len;
|
|
|
|
int distance = ud->distance;
|
|
if (ud->flags & DETECT_CONTENT_DISTANCE) {
|
|
if (ud->flags & DETECT_CONTENT_DISTANCE_BE) {
|
|
distance = det_ctx->bj_values[ud->distance];
|
|
}
|
|
|
|
if (distance < 0 && (uint32_t)(abs(distance)) > offset)
|
|
offset = 0;
|
|
else
|
|
offset += distance;
|
|
|
|
SCLogDebug("ud->distance %"PRIi32", offset %"PRIu32", depth %"PRIu32,
|
|
distance, offset, depth);
|
|
}
|
|
|
|
if (ud->flags & DETECT_CONTENT_WITHIN) {
|
|
if (ud->flags & DETECT_CONTENT_WITHIN_BE) {
|
|
if ((int32_t)depth > (int32_t)(prev_payload_offset + det_ctx->bj_values[ud->within] + distance)) {
|
|
depth = prev_payload_offset + det_ctx->bj_values[ud->within] + distance;
|
|
}
|
|
} else {
|
|
if ((int32_t)depth > (int32_t)(prev_payload_offset + ud->within + distance)) {
|
|
depth = prev_payload_offset + ud->within + distance;
|
|
}
|
|
SCLogDebug("ud->within %"PRIi32", prev_payload_offset %"PRIu32", depth %"PRIu32,
|
|
ud->within, prev_payload_offset, depth);
|
|
}
|
|
}
|
|
|
|
if (ud->flags & DETECT_CONTENT_DEPTH_BE) {
|
|
if ((det_ctx->bj_values[ud->depth] + prev_payload_offset) < depth) {
|
|
depth = prev_payload_offset + det_ctx->bj_values[ud->depth];
|
|
}
|
|
} else {
|
|
if (ud->depth != 0) {
|
|
if ((ud->depth + prev_payload_offset) < depth) {
|
|
depth = prev_payload_offset + ud->depth;
|
|
}
|
|
|
|
SCLogDebug("ud->depth %"PRIu32", depth %"PRIu32, ud->depth, depth);
|
|
}
|
|
}
|
|
|
|
if (ud->flags & DETECT_CONTENT_OFFSET_BE) {
|
|
if (det_ctx->bj_values[ud->offset] > offset)
|
|
offset = det_ctx->bj_values[ud->offset];
|
|
} else {
|
|
if (ud->offset > offset) {
|
|
offset = ud->offset;
|
|
SCLogDebug("setting offset %"PRIu32, offset);
|
|
}
|
|
}
|
|
} else { /* implied no relative matches */
|
|
/* set depth */
|
|
if (ud->flags & DETECT_CONTENT_DEPTH_BE) {
|
|
depth = det_ctx->bj_values[ud->depth];
|
|
} else {
|
|
if (ud->depth != 0) {
|
|
depth = ud->depth;
|
|
}
|
|
}
|
|
|
|
/* set offset */
|
|
if (ud->flags & DETECT_CONTENT_OFFSET_BE)
|
|
offset = det_ctx->bj_values[ud->offset];
|
|
else
|
|
offset = ud->offset;
|
|
prev_payload_offset = 0;
|
|
}
|
|
|
|
/* update offset with prev_offset if we're searching for
|
|
* matches after the first occurence. */
|
|
SCLogDebug("offset %"PRIu32", prev_offset %"PRIu32, prev_offset, depth);
|
|
if (prev_offset != 0)
|
|
offset = prev_offset;
|
|
|
|
SCLogDebug("offset %"PRIu32", depth %"PRIu32, offset, depth);
|
|
|
|
if (depth > payload_len)
|
|
depth = payload_len;
|
|
|
|
/* if offset is bigger than depth we can never match on a pattern.
|
|
* We can however, "match" on a negated pattern. */
|
|
if (offset > depth || depth == 0) {
|
|
if (ud->flags & DETECT_CONTENT_NEGATED) {
|
|
goto match;
|
|
} else {
|
|
SCReturnInt(0);
|
|
}
|
|
}
|
|
|
|
uint8_t *spayload = payload + offset;
|
|
uint32_t spayload_len = depth - offset;
|
|
uint32_t match_offset = 0;
|
|
SCLogDebug("spayload_len %"PRIu32, spayload_len);
|
|
#ifdef DEBUG
|
|
BUG_ON(spayload_len > payload_len);
|
|
#endif
|
|
|
|
//PrintRawDataFp(stdout,ud->content,ud->content_len);
|
|
|
|
/* If we got no matches from the mpm, avoid searching (just check if negated) */
|
|
//if (det_ctx->de_have_httpuri == TRUE) {
|
|
/* do the actual search with boyer moore precooked ctx */
|
|
if (ud->flags & DETECT_CONTENT_NOCASE)
|
|
found = BoyerMooreNocase(ud->content, ud->content_len, spayload, spayload_len, ud->bm_ctx->bmGs, ud->bm_ctx->bmBc);
|
|
else
|
|
found = BoyerMoore(ud->content, ud->content_len, spayload, spayload_len, ud->bm_ctx->bmGs, ud->bm_ctx->bmBc);
|
|
//} else {
|
|
// found = NULL;
|
|
//}
|
|
|
|
/* next we evaluate the result in combination with the
|
|
* negation flag. */
|
|
SCLogDebug("found %p ud negated %s", found, ud->flags & DETECT_CONTENT_NEGATED ? "true" : "false");
|
|
|
|
if (found == NULL && !(ud->flags & DETECT_CONTENT_NEGATED)) {
|
|
SCReturnInt(0);
|
|
} else if (found == NULL && ud->flags & DETECT_CONTENT_NEGATED) {
|
|
goto match;
|
|
} else if (found != NULL && ud->flags & DETECT_CONTENT_NEGATED) {
|
|
SCLogDebug("uricontent %"PRIu32" matched at offset %"PRIu32", but negated so no match", ud->id, match_offset);
|
|
det_ctx->discontinue_matching = 1;
|
|
SCReturnInt(0);
|
|
} else {
|
|
match_offset = (uint32_t)((found - payload) + ud->content_len);
|
|
SCLogDebug("uricontent %"PRIu32" matched at offset %"PRIu32"", ud->id, match_offset);
|
|
det_ctx->payload_offset = match_offset;
|
|
|
|
if (!(ud->flags & DETECT_CONTENT_RELATIVE_NEXT)) {
|
|
SCLogDebug("no relative match coming up, so this is a match");
|
|
goto match;
|
|
}
|
|
|
|
/* bail out if we have no next match. Technically this is an
|
|
* error, as the current cd has the DETECT_CONTENT_RELATIVE_NEXT
|
|
* flag set. */
|
|
if (sm->next == NULL) {
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
SCLogDebug("uricontent %"PRIu32, ud->id);
|
|
|
|
/* see if the next payload keywords match. If not, we will
|
|
* search for another occurence of this uricontent and see
|
|
* if the others match then until we run out of matches */
|
|
int r = DoInspectPacketUri(de_ctx,det_ctx,s,sm->next, payload, payload_len);
|
|
if (r == 1) {
|
|
SCReturnInt(1);
|
|
}
|
|
|
|
if (det_ctx->discontinue_matching)
|
|
SCReturnInt(0);
|
|
|
|
/* set the previous match offset to the start of this match + 1 */
|
|
prev_offset = (match_offset - (ud->content_len - 1));
|
|
SCLogDebug("trying to see if there is another match after prev_offset %"PRIu32, prev_offset);
|
|
}
|
|
|
|
} while(1);
|
|
} else if (sm->type == DETECT_PCRE) {
|
|
SCLogDebug("inspecting pcre");
|
|
DetectPcreData *pe = (DetectPcreData *)sm->ctx;
|
|
uint32_t prev_payload_offset = det_ctx->payload_offset;
|
|
uint32_t prev_offset = 0;
|
|
int r = 0;
|
|
|
|
det_ctx->pcre_match_start_offset = 0;
|
|
do {
|
|
r = DetectPcrePayloadMatch(det_ctx, s, sm, NULL, NULL,
|
|
payload, payload_len);
|
|
if (r == 0) {
|
|
det_ctx->discontinue_matching = 1;
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) {
|
|
SCLogDebug("no relative match coming up, so this is a match");
|
|
goto match;
|
|
}
|
|
|
|
/* save it, in case we need to do a pcre match once again */
|
|
prev_offset = det_ctx->pcre_match_start_offset;
|
|
|
|
/* see if the next payload keywords match. If not, we will
|
|
* search for another occurence of this pcre and see
|
|
* if the others match, until we run out of matches */
|
|
r = DoInspectPacketUri(de_ctx, det_ctx, s, sm->next,
|
|
payload, payload_len);
|
|
if (r == 1) {
|
|
SCReturnInt(1);
|
|
}
|
|
|
|
if (det_ctx->discontinue_matching)
|
|
SCReturnInt(0);
|
|
|
|
det_ctx->payload_offset = prev_payload_offset;
|
|
det_ctx->pcre_match_start_offset = prev_offset;
|
|
} while (1);
|
|
} else if (sm->type == DETECT_ISDATAAT) {
|
|
SCLogDebug("inspecting isdataat");
|
|
|
|
DetectIsdataatData *id = (DetectIsdataatData *)sm->ctx;
|
|
if (id->flags & ISDATAAT_RELATIVE) {
|
|
if (det_ctx->payload_offset + id->dataat > payload_len) {
|
|
SCLogDebug("det_ctx->payload_offset + id->dataat %"PRIu32" > %"PRIu32, det_ctx->payload_offset + id->dataat, payload_len);
|
|
if (id->flags & ISDATAAT_NEGATED)
|
|
goto match;
|
|
SCReturnInt(0);
|
|
} else {
|
|
SCLogDebug("relative isdataat match");
|
|
if (id->flags & ISDATAAT_NEGATED)
|
|
SCReturnInt(0);
|
|
goto match;
|
|
}
|
|
} else {
|
|
if (id->dataat < payload_len) {
|
|
SCLogDebug("absolute isdataat match");
|
|
if (id->flags & ISDATAAT_NEGATED)
|
|
SCReturnInt(0);
|
|
goto match;
|
|
} else {
|
|
SCLogDebug("absolute isdataat mismatch, id->isdataat %"PRIu32", payload_len %"PRIu32"", id->dataat,payload_len);
|
|
if (id->flags & ISDATAAT_NEGATED)
|
|
goto match;
|
|
SCReturnInt(0);
|
|
}
|
|
}
|
|
} else if (sm->type == DETECT_AL_URILEN) {
|
|
SCLogDebug("inspecting uri len");
|
|
|
|
int r = 0;
|
|
DetectUrilenData *urilend = (DetectUrilenData *) sm->ctx;
|
|
|
|
switch (urilend->mode) {
|
|
case DETECT_URILEN_EQ:
|
|
if (payload_len == urilend->urilen1)
|
|
r = 1;
|
|
break;
|
|
case DETECT_URILEN_LT:
|
|
if (payload_len < urilend->urilen1)
|
|
r = 1;
|
|
break;
|
|
case DETECT_URILEN_GT:
|
|
if (payload_len > urilend->urilen1)
|
|
r = 1;
|
|
break;
|
|
case DETECT_URILEN_RA:
|
|
if (payload_len > urilend->urilen1 &&
|
|
payload_len < urilend->urilen2)
|
|
r = 1;
|
|
break;
|
|
}
|
|
|
|
if (r == 1) {
|
|
goto match;
|
|
}
|
|
|
|
SCReturnInt(0);
|
|
} else if (sm->type == DETECT_BYTE_EXTRACT) {
|
|
DetectByteExtractData *bed = (DetectByteExtractData *)sm->ctx;
|
|
if (DetectByteExtractDoMatch(det_ctx, sm, s, payload,
|
|
payload_len,
|
|
&det_ctx->bj_values[bed->local_id],
|
|
bed->endian) != 1) {
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
goto match;
|
|
} else {
|
|
/* we should never get here, but bail out just in case */
|
|
SCLogDebug("sm->type %u", sm->type);
|
|
#ifdef DEBUG
|
|
BUG_ON(1);
|
|
#endif
|
|
}
|
|
SCReturnInt(0);
|
|
|
|
match:
|
|
/* this sigmatch matched, inspect the next one. If it was the last,
|
|
* the payload portion of the signature matched. */
|
|
if (sm->next != NULL) {
|
|
int r = DoInspectPacketUri(de_ctx, det_ctx, s, sm->next, payload,
|
|
payload_len);
|
|
SCReturnInt(r);
|
|
} else {
|
|
SCReturnInt(1);
|
|
}
|
|
}
|
|
|
|
/** \brief Do the content inspection & validation for a signature
|
|
*
|
|
* \param de_ctx Detection engine context
|
|
* \param det_ctx Detection engine thread context
|
|
* \param s Signature to inspect
|
|
* \param sm SigMatch to inspect
|
|
* \param f Flow
|
|
* \param flags app layer flags
|
|
* \param state App layer state
|
|
*
|
|
* \retval 0 no match
|
|
* \retval 1 match
|
|
*/
|
|
int DetectEngineInspectPacketUris(DetectEngineCtx *de_ctx,
|
|
DetectEngineThreadCtx *det_ctx, Signature *s, Flow *f, uint8_t flags,
|
|
void *alstate)
|
|
{
|
|
SCEnter();
|
|
int r = 0;
|
|
HtpState *htp_state = NULL;
|
|
|
|
htp_state = (HtpState *)alstate;
|
|
if (htp_state == NULL) {
|
|
SCLogDebug("no HTTP state");
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
/* locking the flow, we will inspect the htp state */
|
|
SCMutexLock(&f->m);
|
|
|
|
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
|
|
SCLogDebug("HTP state has no conn(p)");
|
|
goto end;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
SigMatch *sm = s->sm_lists[DETECT_SM_LIST_UMATCH];
|
|
DetectContentData *co = (DetectContentData *)sm->ctx;
|
|
SCLogDebug("co->id %"PRIu32, co->id);
|
|
#endif
|
|
|
|
size_t idx = AppLayerTransactionGetInspectId(f);
|
|
htp_tx_t *tx = NULL;
|
|
|
|
for ( ; idx < list_size(htp_state->connp->conn->transactions); idx++)
|
|
{
|
|
tx = list_get(htp_state->connp->conn->transactions, idx);
|
|
if (tx == NULL || tx->request_uri_normalized == NULL)
|
|
continue;
|
|
|
|
det_ctx->discontinue_matching = 0;
|
|
det_ctx->payload_offset = 0;
|
|
det_ctx->inspection_recursion_counter = 0;
|
|
|
|
//PrintRawDataFp(stdout, (uint8_t *)bstr_ptr(tx->request_uri_normalized),
|
|
// bstr_len(tx->request_uri_normalized));
|
|
|
|
/* Inspect all the uricontents fetched on each
|
|
* transaction at the app layer */
|
|
r = DoInspectPacketUri(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_UMATCH],
|
|
(uint8_t *) bstr_ptr(tx->request_uri_normalized),
|
|
bstr_len(tx->request_uri_normalized));
|
|
|
|
if (r == 1) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (r < 1)
|
|
r = 0;
|
|
|
|
end:
|
|
SCMutexUnlock(&f->m);
|
|
SCReturnInt(r);
|
|
}
|
|
|
|
/***********************************Unittests**********************************/
|
|
|
|
#ifdef UNITTESTS
|
|
/** \test Test a simple uricontent option */
|
|
static int UriTestSig01(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test uricontent option\"; "
|
|
"uricontent:\"one\"; sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test the pcre /U option */
|
|
static int UriTestSig02(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /on HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /one HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test pcre /U option\"; "
|
|
"pcre:/one/U; sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted with payload2, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didnt alert, but it should: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test the pcre /U option */
|
|
static int UriTestSig03(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test pcre /U option\"; "
|
|
"pcre:/blah/U; sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test the urilen option */
|
|
static int UriTestSig04(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test urilen option\"; "
|
|
"urilen:>20; sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test the urilen option */
|
|
static int UriTestSig05(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test urilen option\"; "
|
|
"urilen:>4; sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didnt alert with payload2, but it should: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test the pcre /U option */
|
|
static int UriTestSig06(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test pcre /U option\"; "
|
|
"pcre:/(oneself)+/U; sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didnt alert on payload2, but it should: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test the pcre /U option in combination with urilen */
|
|
static int UriTestSig07(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test pcre /U option with urilen \"; "
|
|
"pcre:/(one){2,}(self)?/U; urilen:3<>20; sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didnt alert, but it should: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didnt alert with payload2, but it should: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test the pcre /U option in combination with urilen */
|
|
static int UriTestSig08(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test pcre /U option with urilen\"; "
|
|
"pcre:/(blabla){2,}(self)?/U; urilen:3<>20; sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test the pcre /U option in combination with urilen */
|
|
static int UriTestSig09(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test pcre /U option with urilen \"; "
|
|
"pcre:/(one){2,}(self)?/U; urilen:<2; sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test the uricontent option in combination with urilen */
|
|
static int UriTestSig10(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test uricontent with urilen option\"; "
|
|
"uricontent:\"one\"; urilen:<2; sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test content, uricontent, urilen, pcre /U options */
|
|
static int UriTestSig11(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test content, uricontent, pcre /U and urilen options\"; "
|
|
"content:\"one\"; uricontent:\"one\"; pcre:/(one){2,}(self)?/U;"
|
|
"urilen:<2; sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test uricontent, urilen, pcre /U options */
|
|
static int UriTestSig12(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test pcre /U, uricontent and urilen option\"; "
|
|
"uricontent:\"one\"; "
|
|
"pcre:/(one)+self/U; urilen:>2; sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didnt alert with payload2, but it should: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test uricontent, urilen */
|
|
static int UriTestSig13(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test urilen option\"; "
|
|
"urilen:>2; uricontent:\"one\"; sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didnt alert with pkt, but it should: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didnt alert with payload2, but it should: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test uricontent, pcre /U */
|
|
static int UriTestSig14(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test uricontent option\"; "
|
|
"uricontent:\"one\"; pcre:/one(self)?/U;sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didnt alert with pkt, but it should: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didnt alert with payload2, but it should: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test pcre /U with anchored regex (bug 155) */
|
|
static int UriTestSig15(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"Test uricontent option\"; "
|
|
"uricontent:\"one\"; pcre:/^\\/one(self)?$/U;sid:1;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didnt alert with pkt, but it should: ");
|
|
goto end;
|
|
}
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didnt alert with payload2, but it should: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test pcre /U with anchored regex (bug 155) */
|
|
static int UriTestSig16(void)
|
|
{
|
|
int result = 0;
|
|
Flow f;
|
|
HtpState *http_state = NULL;
|
|
uint8_t http_buf1[] = "POST /search?q=123&aq=7123abcee HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0/\r\n"
|
|
"Host: 1.2.3.4\r\n\r\n";
|
|
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
|
|
uint8_t http_buf2[] = "POST /search?q=123&aq=7123abcee HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n"
|
|
"Cookie: hellocatch\r\n\r\n";
|
|
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
|
|
TcpSession ssn;
|
|
Packet *p = NULL;
|
|
Signature *s = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any any (msg:\"ET TROJAN Downadup/Conficker A or B Worm reporting\"; flow:to_server,established; uricontent:\"/search?q=\"; pcre:\"/^\\/search\\?q=[0-9]{1,3}(&aq=7(\\?[0-9a-f]{8})?)?/U\"; pcre:\"/\\x0d\\x0aHost\\: \\d+\\.\\d+\\.\\d+\\.\\d+\\x0d\\x0a/\"; sid:2009024; rev:9;)");
|
|
if (s == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 2009024)) {
|
|
printf("sig 1 didnt alert with pkt, but it should: ");
|
|
goto end;
|
|
}
|
|
p->alerts.cnt = 0;
|
|
|
|
DetectEngineStateReset(f.de_state);
|
|
p->payload = http_buf2;
|
|
p->payload_len = http_buf2_len;
|
|
|
|
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 2009024)) {
|
|
printf("sig 1 alerted, but it should not (host should not match): ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* \test Test multiple relative contents
|
|
*/
|
|
static int UriTestSig17(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /now_this_is_is_big_big_string_now HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"test multiple relative uricontents\"; "
|
|
"uricontent:\"this\"; uricontent:\"is\"; within:6; "
|
|
"uricontent:\"big\"; within:8; "
|
|
"uricontent:\"string\"; within:8; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* \test Test multiple relative contents
|
|
*/
|
|
static int UriTestSig18(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /now_this_is_is_is_big_big_big_string_now HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"test multiple relative uricontents\"; "
|
|
"uricontent:\"this\"; uricontent:\"is\"; within:9; "
|
|
"uricontent:\"big\"; within:12; "
|
|
"uricontent:\"string\"; within:8; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* \test Test multiple relative contents
|
|
*/
|
|
static int UriTestSig19(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /this_this_now_is_is_____big_string_now HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"test multiple relative uricontents\"; "
|
|
"uricontent:\"now\"; uricontent:\"this\"; "
|
|
"uricontent:\"is\"; within:12; "
|
|
"uricontent:\"big\"; within:8; "
|
|
"uricontent:\"string\"; within:8; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* \test Test multiple relative contents with offset
|
|
*/
|
|
static int UriTestSig20(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /_________thus_thus_is_a_big HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"test multiple relative uricontents\"; "
|
|
"uricontent:\"thus\"; offset:8; "
|
|
"uricontent:\"is\"; within:6; "
|
|
"uricontent:\"big\"; within:8; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* \test Test multiple relative contents with a negated content.
|
|
*/
|
|
static int UriTestSig21(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"test multiple relative uricontents\"; "
|
|
"uricontent:\"fix\"; uricontent:\"this\"; within:6; "
|
|
"uricontent:!\"and\"; distance:0; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* \test Test relative pcre.
|
|
*/
|
|
static int UriTestSig22(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /this_is_a_super_duper_"
|
|
"nova_in_super_nova_now HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"test multiple relative uricontents\"; "
|
|
"pcre:/super/U; uricontent:\"nova\"; within:7; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didn't alert, but it should have: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* \test Test multiple relative contents with a negated content.
|
|
*/
|
|
static int UriTestSig23(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"test multiple relative uricontents\"; "
|
|
"uricontent:!\"fix_this_now\"; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* \test Test multiple relative contents with a negated content.
|
|
*/
|
|
static int UriTestSig24(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"test multiple relative uricontents\"; "
|
|
"uricontent:\"we_need_to\"; uricontent:!\"fix_this_now\"; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 alerted, but it should not: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* \test Test normalized uricontents.
|
|
*/
|
|
static int UriTestSig25(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
|
|
"HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"test multiple relative uricontents\"; "
|
|
"pcre:/normalized/U; uricontent:\"normalized uri\"; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didn't alert, but it should have: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* \test Test multiple relative contents with a negated content.
|
|
*/
|
|
static int UriTestSig26(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"test multiple relative uricontents\"; "
|
|
"uricontent:\"fix_this\"; isdataat:4,relative; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didn't alert, but it should have: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* \test Test multiple relative contents with a negated content.
|
|
*/
|
|
static int UriTestSig27(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
|
|
"(msg:\"test multiple relative uricontents\"; "
|
|
"uricontent:\"fix_this\"; isdataat:!10,relative; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didn't alert, but it should have: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int UriTestSig28(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx,
|
|
"alert tcp any any -> any any (msg:\"dummy\"; "
|
|
"uricontent:\"this\"; "
|
|
"byte_extract:1,2,one,string,dec,relative; "
|
|
"uricontent:\"ring\"; distance:one; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didn't alert, but should have: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
static int UriTestSig29(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx,
|
|
"alert tcp any any -> any any (msg:\"dummy\"; "
|
|
"uricontent:\"this\"; "
|
|
"byte_extract:1,2,one,string,dec,relative; "
|
|
"uricontent:\"ring\"; distance:one; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didn't alert, but should have: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
static int UriTestSig30(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx,
|
|
"alert tcp any any -> any any (msg:\"dummy\"; "
|
|
"uricontent:\"this\"; "
|
|
"byte_extract:1,2,one,string,dec,relative; "
|
|
"uricontent:\"_b5ig\"; offset:one; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didn't alert, but should have: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
static int UriTestSig31(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx,
|
|
"alert tcp any any -> any any (msg:\"dummy\"; "
|
|
"uricontent:\"this\"; "
|
|
"byte_extract:1,2,one,string,dec,relative; "
|
|
"uricontent:\"his\"; depth:one; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didn't alert, but should have: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
static int UriTestSig32(void)
|
|
{
|
|
int result = 0;
|
|
uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
|
|
"User-Agent: Mozilla/1.0\r\n";
|
|
uint32_t http_buf_len = strlen((char *)http_buf);
|
|
Flow f;
|
|
TcpSession ssn;
|
|
HtpState *http_state = NULL;
|
|
Packet *p = NULL;
|
|
ThreadVars tv;
|
|
DetectEngineThreadCtx *det_ctx = NULL;
|
|
|
|
memset(&tv, 0, sizeof(ThreadVars));
|
|
memset(&f, 0, sizeof(Flow));
|
|
memset(&ssn, 0, sizeof(TcpSession));
|
|
|
|
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
|
|
|
|
FLOW_INITIALIZE(&f);
|
|
f.protoctx = (void *)&ssn;
|
|
f.flags |= FLOW_IPV4;
|
|
|
|
p->flow = &f;
|
|
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
|
|
p->flowflags |= FLOW_PKT_TOSERVER;
|
|
p->flowflags |= FLOW_PKT_ESTABLISHED;
|
|
f.alproto = ALPROTO_HTTP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
|
if (de_ctx == NULL) {
|
|
goto end;
|
|
}
|
|
de_ctx->mpm_matcher = MPM_B2G;
|
|
de_ctx->flags |= DE_QUIET;
|
|
|
|
de_ctx->sig_list = SigInit(de_ctx,
|
|
"alert tcp any any -> any any (msg:\"dummy\"; "
|
|
"uricontent:\"this\"; "
|
|
"byte_extract:1,2,one,string,dec,relative; "
|
|
"uricontent:\"g_st\"; within:one; sid:1;)");
|
|
if (de_ctx->sig_list == NULL) {
|
|
goto end;
|
|
}
|
|
|
|
SigGroupBuild(de_ctx);
|
|
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
|
|
|
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
|
|
if (r != 0) {
|
|
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
|
|
goto end;
|
|
}
|
|
|
|
http_state = f.alstate;
|
|
if (http_state == NULL) {
|
|
printf("no http state: ");
|
|
goto end;
|
|
}
|
|
|
|
/* do detect */
|
|
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
|
|
|
|
if (!PacketAlertCheck(p, 1)) {
|
|
printf("sig 1 didn't alert, but should have: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
if (det_ctx != NULL)
|
|
DetectEngineThreadCtxDeinit(&tv, det_ctx);
|
|
if (de_ctx != NULL)
|
|
SigGroupCleanup(de_ctx);
|
|
if (de_ctx != NULL)
|
|
DetectEngineCtxFree(de_ctx);
|
|
|
|
StreamTcpFreeConfig(TRUE);
|
|
FLOW_DESTROY(&f);
|
|
UTHFreePacket(p);
|
|
return result;
|
|
}
|
|
|
|
#endif /* UNITTESTS */
|
|
|
|
void UriRegisterTests(void)
|
|
{
|
|
|
|
#ifdef UNITTESTS
|
|
UtRegisterTest("UriTestSig01", UriTestSig01, 1);
|
|
UtRegisterTest("UriTestSig02", UriTestSig02, 1);
|
|
UtRegisterTest("UriTestSig03", UriTestSig03, 1);
|
|
UtRegisterTest("UriTestSig04", UriTestSig04, 1);
|
|
UtRegisterTest("UriTestSig05", UriTestSig05, 1);
|
|
UtRegisterTest("UriTestSig06", UriTestSig06, 1);
|
|
UtRegisterTest("UriTestSig07", UriTestSig07, 1);
|
|
UtRegisterTest("UriTestSig08", UriTestSig08, 1);
|
|
UtRegisterTest("UriTestSig09", UriTestSig09, 1);
|
|
UtRegisterTest("UriTestSig10", UriTestSig10, 1);
|
|
UtRegisterTest("UriTestSig11", UriTestSig11, 1);
|
|
UtRegisterTest("UriTestSig12", UriTestSig12, 1);
|
|
UtRegisterTest("UriTestSig13", UriTestSig13, 1);
|
|
UtRegisterTest("UriTestSig14", UriTestSig14, 1);
|
|
UtRegisterTest("UriTestSig15", UriTestSig15, 1);
|
|
UtRegisterTest("UriTestSig16", UriTestSig16, 1);
|
|
UtRegisterTest("UriTestSig17", UriTestSig17, 1);
|
|
UtRegisterTest("UriTestSig18", UriTestSig18, 1);
|
|
UtRegisterTest("UriTestSig19", UriTestSig19, 1);
|
|
UtRegisterTest("UriTestSig20", UriTestSig20, 1);
|
|
UtRegisterTest("UriTestSig21", UriTestSig21, 1);
|
|
UtRegisterTest("UriTestSig22", UriTestSig22, 1);
|
|
UtRegisterTest("UriTestSig23", UriTestSig23, 1);
|
|
UtRegisterTest("UriTestSig24", UriTestSig24, 1);
|
|
UtRegisterTest("UriTestSig25", UriTestSig25, 1);
|
|
UtRegisterTest("UriTestSig26", UriTestSig26, 1);
|
|
UtRegisterTest("UriTestSig27", UriTestSig27, 1);
|
|
|
|
UtRegisterTest("UriTestSig28", UriTestSig28, 1);
|
|
UtRegisterTest("UriTestSig29", UriTestSig29, 1);
|
|
UtRegisterTest("UriTestSig30", UriTestSig30, 1);
|
|
UtRegisterTest("UriTestSig31", UriTestSig31, 1);
|
|
UtRegisterTest("UriTestSig32", UriTestSig32, 1);
|
|
#endif /* UNITTESTS */
|
|
|
|
return;
|
|
}
|