Feature #341 ยป 0001-bug-341-support-for-urilen-check-on-both-norm-and-ra.patch
src/detect-engine-uri.c | ||
---|---|---|
static int DoInspectPacketUri(DetectEngineCtx *de_ctx,
|
||
DetectEngineThreadCtx *det_ctx,
|
||
Signature *s, SigMatch *sm,
|
||
uint8_t *payload, uint32_t payload_len)
|
||
uint8_t *payload, uint32_t payload_len,
|
||
htp_tx_t *tx)
|
||
{
|
||
SCEnter();
|
||
... | ... | |
/* 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);
|
||
int r = DoInspectPacketUri(de_ctx,det_ctx,s,sm->next, payload, payload_len, tx);
|
||
if (r == 1) {
|
||
SCReturnInt(1);
|
||
}
|
||
... | ... | |
* 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);
|
||
payload, payload_len, tx);
|
||
if (r == 1) {
|
||
SCReturnInt(1);
|
||
}
|
||
... | ... | |
int r = 0;
|
||
DetectUrilenData *urilend = (DetectUrilenData *) sm->ctx;
|
||
uint32_t p_len = payload_len;
|
||
if (urilend->raw_buffer)
|
||
p_len = bstr_len(tx->request_uri);
|
||
switch (urilend->mode) {
|
||
case DETECT_URILEN_EQ:
|
||
if (payload_len == urilend->urilen1)
|
||
if (p_len == urilend->urilen1)
|
||
r = 1;
|
||
break;
|
||
case DETECT_URILEN_LT:
|
||
if (payload_len < urilend->urilen1)
|
||
if (p_len < urilend->urilen1)
|
||
r = 1;
|
||
break;
|
||
case DETECT_URILEN_GT:
|
||
if (payload_len > urilend->urilen1)
|
||
if (p_len > urilend->urilen1)
|
||
r = 1;
|
||
break;
|
||
case DETECT_URILEN_RA:
|
||
if (payload_len > urilend->urilen1 &&
|
||
payload_len < urilend->urilen2)
|
||
if (p_len > urilend->urilen1 &&
|
||
p_len < urilend->urilen2)
|
||
r = 1;
|
||
break;
|
||
}
|
||
... | ... | |
* the payload portion of the signature matched. */
|
||
if (sm->next != NULL) {
|
||
int r = DoInspectPacketUri(de_ctx, det_ctx, s, sm->next, payload,
|
||
payload_len);
|
||
payload_len, tx);
|
||
SCReturnInt(r);
|
||
} else {
|
||
SCReturnInt(1);
|
||
... | ... | |
/* 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));
|
||
(uint8_t *)bstr_ptr(tx->request_uri_normalized),
|
||
bstr_len(tx->request_uri_normalized), tx);
|
||
if (r == 1) {
|
||
break;
|
||
}
|
||
... | ... | |
return result;
|
||
}
|
||
static int UriTestSig33(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\"; "
|
||
"urilen:15; sid:1;)");
|
||
if (de_ctx->sig_list == NULL) {
|
||
goto end;
|
||
}
|
||
SigGroupBuild(de_ctx);
|
||
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
||
int r = AppLayerParse(NULL, &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 UriTestSig34(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\"; "
|
||
"urilen:15, norm; sid:1;)");
|
||
if (de_ctx->sig_list == NULL) {
|
||
goto end;
|
||
}
|
||
SigGroupBuild(de_ctx);
|
||
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
||
int r = AppLayerParse(NULL, &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 UriTestSig35(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\"; "
|
||
"urilen:16; sid:1;)");
|
||
if (de_ctx->sig_list == NULL) {
|
||
goto end;
|
||
}
|
||
SigGroupBuild(de_ctx);
|
||
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
||
int r = AppLayerParse(NULL, &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 shouldn't 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 UriTestSig36(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\"; "
|
||
"urilen:16, norm; sid:1;)");
|
||
if (de_ctx->sig_list == NULL) {
|
||
goto end;
|
||
}
|
||
SigGroupBuild(de_ctx);
|
||
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
||
int r = AppLayerParse(NULL, &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 shouldn't 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 UriTestSig37(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\"; "
|
||
"urilen:17, raw; sid:1;)");
|
||
if (de_ctx->sig_list == NULL) {
|
||
goto end;
|
||
}
|
||
SigGroupBuild(de_ctx);
|
||
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
||
int r = AppLayerParse(NULL, &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 UriTestSig38(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\"; "
|
||
"urilen:18, raw; sid:1;)");
|
||
if (de_ctx->sig_list == NULL) {
|
||
goto end;
|
||
}
|
||
SigGroupBuild(de_ctx);
|
||
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
|
||
int r = AppLayerParse(NULL, &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 shouldn't 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)
|
||
... | ... | |
UtRegisterTest("UriTestSig30", UriTestSig30, 1);
|
||
UtRegisterTest("UriTestSig31", UriTestSig31, 1);
|
||
UtRegisterTest("UriTestSig32", UriTestSig32, 1);
|
||
UtRegisterTest("UriTestSig33", UriTestSig33, 1);
|
||
UtRegisterTest("UriTestSig34", UriTestSig34, 1);
|
||
UtRegisterTest("UriTestSig35", UriTestSig35, 1);
|
||
UtRegisterTest("UriTestSig36", UriTestSig36, 1);
|
||
UtRegisterTest("UriTestSig37", UriTestSig37, 1);
|
||
UtRegisterTest("UriTestSig38", UriTestSig38, 1);
|
||
#endif /* UNITTESTS */
|
||
return;
|
src/detect-urilen.c | ||
---|---|---|
/**
|
||
* \brief Regex for parsing our urilen
|
||
*/
|
||
#define PARSE_REGEX "^(?:\\s*)(<|>)?(?:\\s*)([0-9]{1,5})(?:\\s*)(?:(<>)(?:\\s*)([0-9]{1,5}))?(?:\\s*)$"
|
||
#define PARSE_REGEX "^(?:\\s*)(<|>)?(?:\\s*)([0-9]{1,5})(?:\\s*)(?:(<>)(?:\\s*)([0-9]{1,5}))?\\s*(?:,\\s*(norm|raw))?\\s*$"
|
||
static pcre *parse_regex;
|
||
static pcre_extra *parse_regex_study;
|
||
... | ... | |
char *arg2 = NULL;
|
||
char *arg3 = NULL;
|
||
char *arg4 = NULL;
|
||
char *arg5 = NULL;
|
||
#define MAX_SUBSTRINGS 30
|
||
int ret = 0, res = 0;
|
||
int ov[MAX_SUBSTRINGS];
|
||
ret = pcre_exec(parse_regex, parse_regex_study, urilenstr, strlen(urilenstr),
|
||
0, 0, ov, MAX_SUBSTRINGS);
|
||
if (ret < 3 || ret > 5) {
|
||
if (ret < 3 || ret > 6) {
|
||
SCLogError(SC_ERR_PCRE_PARSE, "parse error, ret %" PRId32 "", ret);
|
||
goto error;
|
||
}
|
||
... | ... | |
arg4 = (char *) str_ptr;
|
||
SCLogDebug("Arg4 \"%s\"", arg4);
|
||
}
|
||
if (ret > 5) {
|
||
res = pcre_get_substring((char *)urilenstr, ov, MAX_SUBSTRINGS, 5, &str_ptr);
|
||
if (res < 0) {
|
||
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
|
||
goto error;
|
||
}
|
||
arg5 = (char *) str_ptr;
|
||
SCLogDebug("Arg5 \"%s\"", arg5);
|
||
}
|
||
}
|
||
urilend = SCMalloc(sizeof (DetectUrilenData));
|
||
if (urilend == NULL)
|
||
goto error;
|
||
urilend->urilen1 = 0;
|
||
urilend->urilen2 = 0;
|
||
memset(urilend, 0, sizeof(DetectUrilenData));
|
||
if (arg1[0] == '<')
|
||
urilend->mode = DETECT_URILEN_LT;
|
||
... | ... | |
}
|
||
}
|
||
if (arg5 != NULL) {
|
||
if (strcasecmp("raw", arg5) == 0) {
|
||
urilend->raw_buffer = 1;
|
||
}
|
||
}
|
||
if (arg1 != NULL)
|
||
SCFree(arg1);
|
||
pcre_free_substring(arg1);
|
||
if (arg2 != NULL)
|
||
SCFree(arg2);
|
||
pcre_free_substring(arg2);
|
||
if (arg3 != NULL)
|
||
SCFree(arg3);
|
||
pcre_free_substring(arg3);
|
||
if (arg4 != NULL)
|
||
SCFree(arg4);
|
||
pcre_free_substring(arg4);
|
||
if (arg5 != NULL)
|
||
pcre_free_substring(arg5);
|
||
return urilend;
|
||
error:
|
||
... | ... | |
urilend = DetectUrilenParse("10");
|
||
if (urilend != NULL) {
|
||
if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_EQ)
|
||
if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_EQ &&
|
||
!urilend->raw_buffer)
|
||
ret = 1;
|
||
DetectUrilenFree(urilend);
|
||
... | ... | |
urilend = DetectUrilenParse(" < 10 ");
|
||
if (urilend != NULL) {
|
||
if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_LT)
|
||
if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_LT &&
|
||
!urilend->raw_buffer)
|
||
ret = 1;
|
||
DetectUrilenFree(urilend);
|
||
... | ... | |
urilend = DetectUrilenParse(" > 10 ");
|
||
if (urilend != NULL) {
|
||
if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_GT)
|
||
if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_GT &&
|
||
!urilend->raw_buffer)
|
||
ret = 1;
|
||
DetectUrilenFree(urilend);
|
||
... | ... | |
urilend = DetectUrilenParse(" 5 <> 10 ");
|
||
if (urilend != NULL) {
|
||
if (urilend->urilen1 == 5 && urilend->urilen2 == 10 &&
|
||
urilend->mode == DETECT_URILEN_RA)
|
||
urilend->mode == DETECT_URILEN_RA &&
|
||
!urilend->raw_buffer)
|
||
ret = 1;
|
||
DetectUrilenFree(urilend);
|
||
}
|
||
return ret;
|
||
}
|
||
/** \test Test the Urilen keyword setup */
|
||
static int DetectUrilenParseTest05(void)
|
||
{
|
||
int ret = 0;
|
||
DetectUrilenData *urilend = NULL;
|
||
urilend = DetectUrilenParse("5<>10,norm");
|
||
if (urilend != NULL) {
|
||
if (urilend->urilen1 == 5 && urilend->urilen2 == 10 &&
|
||
urilend->mode == DETECT_URILEN_RA &&
|
||
!urilend->raw_buffer)
|
||
ret = 1;
|
||
DetectUrilenFree(urilend);
|
||
}
|
||
return ret;
|
||
}
|
||
/** \test Test the Urilen keyword setup */
|
||
static int DetectUrilenParseTest06(void)
|
||
{
|
||
int ret = 0;
|
||
DetectUrilenData *urilend = NULL;
|
||
urilend = DetectUrilenParse("5<>10,raw");
|
||
if (urilend != NULL) {
|
||
if (urilend->urilen1 == 5 && urilend->urilen2 == 10 &&
|
||
urilend->mode == DETECT_URILEN_RA &&
|
||
urilend->raw_buffer)
|
||
ret = 1;
|
||
DetectUrilenFree(urilend);
|
||
}
|
||
return ret;
|
||
}
|
||
/** \test Test the Urilen keyword setup */
|
||
static int DetectUrilenParseTest07(void)
|
||
{
|
||
int ret = 0;
|
||
DetectUrilenData *urilend = NULL;
|
||
urilend = DetectUrilenParse(">10, norm ");
|
||
if (urilend != NULL) {
|
||
if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_GT &&
|
||
!urilend->raw_buffer)
|
||
ret = 1;
|
||
DetectUrilenFree(urilend);
|
||
}
|
||
return ret;
|
||
}
|
||
/** \test Test the Urilen keyword setup */
|
||
static int DetectUrilenParseTest08(void)
|
||
{
|
||
int ret = 0;
|
||
DetectUrilenData *urilend = NULL;
|
||
urilend = DetectUrilenParse("<10, norm ");
|
||
if (urilend != NULL) {
|
||
if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_LT &&
|
||
!urilend->raw_buffer)
|
||
ret = 1;
|
||
DetectUrilenFree(urilend);
|
||
}
|
||
return ret;
|
||
}
|
||
/** \test Test the Urilen keyword setup */
|
||
static int DetectUrilenParseTest09(void)
|
||
{
|
||
int ret = 0;
|
||
DetectUrilenData *urilend = NULL;
|
||
urilend = DetectUrilenParse(">10, raw ");
|
||
if (urilend != NULL) {
|
||
if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_GT &&
|
||
urilend->raw_buffer)
|
||
ret = 1;
|
||
DetectUrilenFree(urilend);
|
||
}
|
||
return ret;
|
||
}
|
||
/** \test Test the Urilen keyword setup */
|
||
static int DetectUrilenParseTest10(void)
|
||
{
|
||
int ret = 0;
|
||
DetectUrilenData *urilend = NULL;
|
||
urilend = DetectUrilenParse("<10, raw ");
|
||
if (urilend != NULL) {
|
||
if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_LT &&
|
||
urilend->raw_buffer)
|
||
ret = 1;
|
||
DetectUrilenFree(urilend);
|
||
... | ... | |
UtRegisterTest("DetectUrilenParseTest02", DetectUrilenParseTest02, 1);
|
||
UtRegisterTest("DetectUrilenParseTest03", DetectUrilenParseTest03, 1);
|
||
UtRegisterTest("DetectUrilenParseTest04", DetectUrilenParseTest04, 1);
|
||
UtRegisterTest("DetectUrilenParseTest05", DetectUrilenParseTest05, 1);
|
||
UtRegisterTest("DetectUrilenParseTest06", DetectUrilenParseTest06, 1);
|
||
UtRegisterTest("DetectUrilenParseTest07", DetectUrilenParseTest07, 1);
|
||
UtRegisterTest("DetectUrilenParseTest08", DetectUrilenParseTest08, 1);
|
||
UtRegisterTest("DetectUrilenParseTest09", DetectUrilenParseTest09, 1);
|
||
UtRegisterTest("DetectUrilenParseTest10", DetectUrilenParseTest10, 1);
|
||
UtRegisterTest("DetectUrilenSetpTest01", DetectUrilenSetpTest01, 1);
|
||
UtRegisterTest("DetectUrilenSigTest01", DetectUrilenSigTest01, 1);
|
||
#endif /* UNITTESTS */
|
src/detect-urilen.h | ||
---|---|---|
uint16_t urilen1; /**< 1st Uri Length value in the signature*/
|
||
uint16_t urilen2; /**< 2nd Uri Length value in the signature*/
|
||
uint8_t mode; /**< operator used in the signature */
|
||
uint8_t raw_buffer;
|
||
}DetectUrilenData;
|
||
int DetectUrilenMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *,
|