72
75
void DetectHttpStatMsgRegister (void) {
73
76
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].name = "http_stat_msg";
74
77
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].Match = NULL;
75
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].AppLayerMatch = DetectHttpStatMsgMatch;
78
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].AppLayerMatch = NULL;
76
79
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].alproto = ALPROTO_HTTP;
77
80
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].Setup = DetectHttpStatMsgSetup;
78
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].Free = DetectHttpStatMsgFree;
81
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].Free = NULL;
79
82
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].RegisterTests = DetectHttpStatMsgRegisterTests;
81
84
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].flags |= SIGMATCH_PAYLOAD;
85
* \brief match the specified content in the signature with the received http
86
* status message header in the http response.
88
* \param t pointer to thread vars
89
* \param det_ctx pointer to the pattern matcher thread
90
* \param f pointer to the current flow
91
* \param flags flags to indicate the direction of the received packet
92
* \param state pointer the app layer state, which will cast into HtpState
93
* \param s pointer to the current signature
94
* \param sm pointer to the sigmatch
99
int DetectHttpStatMsgMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx,
100
Flow *f, uint8_t flags, void *state, Signature *s,
109
SCLogDebug("got lock %p", &f->m);
111
DetectContentData *co = (DetectContentData *)sm->ctx;
113
HtpState *htp_state = (HtpState *)state;
114
if (htp_state == NULL) {
115
SCLogDebug("no HTTP layer state has been received, so no match");
119
if (!(htp_state->flags & HTP_FLAG_STATE_OPEN)) {
120
SCLogDebug("HTP state not yet properly setup, so no match");
124
SCLogDebug("htp_state %p, flow %p", htp_state, f);
125
SCLogDebug("htp_state->connp %p", htp_state->connp);
126
SCLogDebug("htp_state->connp->conn %p", htp_state->connp->conn);
128
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
129
SCLogDebug("HTTP connection structure is NULL");
135
idx = AppLayerTransactionGetInspectId(f);
140
int size = (int)list_size(htp_state->connp->conn->transactions);
141
for (; idx < size; idx++)
143
tx = list_get(htp_state->connp->conn->transactions, idx);
147
if (tx->response_message == NULL)
150
SCLogDebug("we have a response message");
152
/* call the case insensitive version if nocase has been specified in the sig */
153
if (co->flags & DETECT_CONTENT_NOCASE) {
154
if (SpmNocaseSearch((uint8_t *) bstr_ptr(tx->response_message),
155
bstr_len(tx->response_message), co->content, co->content_len) != NULL)
157
SCLogDebug("match has been found in received request and given http_"
162
if (SpmSearch((uint8_t *) bstr_ptr(tx->response_message),
163
bstr_len(tx->response_message), co->content, co->content_len) != NULL)
165
SCLogDebug("match has been found in received request and given http_"
172
SCMutexUnlock(&f->m);
173
SCReturnInt(ret ^ ((co->flags & DETECT_CONTENT_NEGATED) ? 1 : 0));
176
SCMutexUnlock(&f->m);
177
SCLogDebug("released lock %p", &f->m);
182
* \brief this function clears the memory of http_stat_msg modifier keyword
184
* \param ptr Pointer to the Detection Stat Message data
186
void DetectHttpStatMsgFree(void *ptr)
188
DetectContentData *hsmd = (DetectContentData *)ptr;
191
if (hsmd->content != NULL)
192
SCFree(hsmd->content);
197
88
* \brief this function setups the http_stat_msg modifier keyword used in the rule
199
90
* \param de_ctx Pointer to the Detection Engine Context
204
95
* \retval -1 On failure
207
static int DetectHttpStatMsgSetup (DetectEngineCtx *de_ctx, Signature *s, char *str)
98
static int DetectHttpStatMsgSetup (DetectEngineCtx *de_ctx, Signature *s, char *arg)
209
DetectContentData *hd = NULL;
100
DetectContentData *cd = NULL;
210
101
SigMatch *sm = NULL;
212
/** new sig match to replace previous content */
215
if (str != NULL && strcmp(str, "") != 0) {
216
SCLogError(SC_ERR_INVALID_ARGUMENT, "http_stat_msg shouldn't be supplied"
217
" with an argument");
221
SigMatch *pm = DetectContentGetLastPattern(s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
223
SCLogWarning(SC_ERR_INVALID_SIGNATURE, "http_stat_msg found inside "
224
"the rule, without a content context. Please use a "
225
"content keyword before using http_stat_msg");
229
/* http_stat_msg should not be used with the fast_pattern rule */
230
if (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_FAST_PATTERN) {
231
SCLogWarning(SC_WARN_COMPATIBILITY, "http_stat_msg rule can not "
232
"be used with the fast_pattern rule keyword. "
233
"Unsetting fast_pattern on this modifier. Signature ==> %s",
235
((DetectContentData *)pm->ctx)->flags &= ~DETECT_CONTENT_FAST_PATTERN;
237
/* http_stat_msg should not be used with the rawbytes rule */
238
} else if (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_RAWBYTES) {
103
if (arg != NULL && strcmp(arg, "") != 0) {
104
SCLogError(SC_ERR_INVALID_ARGUMENT, "http_stat_msg supplied with args");
108
sm = SigMatchGetLastSMFromLists(s, 2,
109
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
110
/* if still we are unable to find any content previous keywords, it is an
113
SCLogError(SC_ERR_INVALID_SIGNATURE, "\"http_stat_msg\" keyword "
114
"found inside the rule without a content context. "
115
"Please use a \"content\" keyword before using the "
116
"\"http_stat_msg\" keyword");
120
cd = (DetectContentData *)sm->ctx;
122
/* http_stat_msg should not be used with the rawbytes rule */
123
if (cd->flags & DETECT_CONTENT_RAWBYTES) {
239
124
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_stat_msg rule can not "
240
"be used with the rawbytes rule keyword");
125
"be used with the rawbytes rule keyword");
244
nm = SigMatchAlloc();
246
SCLogError(SC_ERR_MEM_ALLOC, "SigMatchAlloc failed");
250
/* Setup the HttpStatMsg data from Content data structure */
251
hd = SCMalloc(sizeof(DetectContentData));
255
memset(hd, 0, sizeof(DetectContentData));
257
/* Setup the http_stat_msg keyword data */
258
hd->content_len = ((DetectContentData *)pm->ctx)->content_len;
259
hd->content = ((DetectContentData *)pm->ctx)->content;
260
hd->flags |= (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_NOCASE) ?
261
DETECT_CONTENT_NOCASE : 0x00;
262
hd->flags |= (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_NEGATED) ?
263
DETECT_CONTENT_NEGATED : 0x00;
264
nm->type = DETECT_AL_HTTP_STAT_MSG;
265
nm->ctx = (void *)hd;
267
/* pull the previous content from the pmatch list, append
268
* the new match to the match list */
269
SigMatchReplaceContent(s, pm, nm);
271
/* free the old content sigmatch, the content pattern memory
272
* is taken over by the new sigmatch */
273
BoyerMooreCtxDeInit(((DetectContentData *)pm->ctx)->bm_ctx);
277
/* Flagged the signature as to inspect the app layer data */
129
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) {
130
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains a non http "
135
if (cd->flags & DETECT_CONTENT_WITHIN || cd->flags & DETECT_CONTENT_DISTANCE) {
136
SigMatch *pm = SigMatchGetLastSMFromLists(s, 4,
137
DETECT_CONTENT, sm->prev,
138
DETECT_PCRE, sm->prev);
139
/* pm can be NULL now. To accomodate parsing sigs like -
140
* content:one; http_modifier; content:two; distance:0; http_modifier */
142
if (pm->type == DETECT_CONTENT) {
143
DetectContentData *tmp_cd = (DetectContentData *)pm->ctx;
144
tmp_cd->flags &= ~DETECT_CONTENT_RELATIVE_NEXT;
146
DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx;
147
tmp_pd->flags &= ~ DETECT_PCRE_RELATIVE_NEXT;
150
} /* if (pm != NULL) */
153
pm = SigMatchGetLastSMFromLists(s, 4,
154
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH],
155
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]);
157
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_stat_msg seen with a "
158
"distance or within without a previous http_stat_msg "
159
"content. Invalidating signature.");
162
if (pm->type == DETECT_PCRE) {
163
DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx;
164
tmp_pd->flags |= DETECT_PCRE_RELATIVE_NEXT;
166
DetectContentData *tmp_cd = (DetectContentData *)pm->ctx;
167
tmp_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
170
cd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, cd, DETECT_SM_LIST_HSMDMATCH);
171
sm->type = DETECT_CONTENT;
173
/* transfer the sm from the pmatch list to hcbdmatch list */
174
SigMatchTransferSigMatchAcrossLists(sm,
175
&s->sm_lists[DETECT_SM_LIST_PMATCH],
176
&s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
177
&s->sm_lists[DETECT_SM_LIST_HSMDMATCH],
178
&s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]);
180
/* flag the signature to indicate that we scan the app layer data */
278
181
s->flags |= SIG_FLAG_APPLAYER;
280
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) {
281
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting"
286
182
s->alproto = ALPROTO_HTTP;
290
DetectHttpStatMsgFree(hd);