return TRUE;
}
-
/* Move through the bytes of the tvbuff, looking for a match against the
* regexp from the given content.
*/
return FALSE;
}
- /* Copy remaining bytes into NULL-terminated string. */
+ /* Copy remaining bytes into NULL-terminated string. Unfortunately, this interface does't allow
+ us to find patterns that involve bytes with value 0.. */
int length_remaining = tvb_captured_length_remaining(tvb, start_offset);
gchar *string = (gchar*)g_malloc(length_remaining + 1);
tvb_memcpy(tvb, (void*)string, start_offset, length_remaining);
/* Can only find start if we have the rule and know the protocol */
guint content_start_match = 0;
+ guint payload_start = 0;
if (rule) {
- content_start_match = get_content_start_match(rule, tree);
+ payload_start = content_start_match = get_content_start_match(rule, tree);
}
/* Snort output arrived and was previously stored - so add to tree */
/* Look up offset of match. N.B. would only expect to see on first content... */
guint offset_to_add = 0;
- /* May need to add absolute offset into packet... */
+ /* May need to start looking from absolute offset into packet... */
if (rule->contents[n].offset_set) {
- offset_to_add = rule->contents[n].offset;
+ content_start_match = payload_start + rule->contents[n].offset;
+ offset_to_add = 0;
}
/* ... or a number of bytes beyond the previous content match */
else if (rule->contents[n].distance_set) {
rule->contents[n].str,
content_text_template,
rule->contents[n].str);
+
+ /* Next match position will be after this one */
+ if (match_found) {
+ content_start_match = content_last_match_end;
+ }
+
if (!attempt_match) {
proto_item_append_text(ti, " (no match attempt made)");
}
if (rule->contents[n].fastpattern) {
proto_item_append_text(ti, " (fast_pattern)");
}
+ if (rule->contents[n].rawbytes) {
+ proto_item_append_text(ti, " (rawbytes)");
+ }
if (rule->contents[n].nocase) {
proto_item_append_text(ti, " (nocase)");
}
if (rule->contents[n].http_cookie != 0) {
proto_item_append_text(ti, " (http_cookie)");
}
+ if (rule->contents[n].http_user_agent != 0) {
+ proto_item_append_text(ti, " (http_user_agent)");
+ }
if (attempt_match && !rule->contents[n].negation && !match_found) {
/* Useful for debugging, may also happen when Snort is reassembling.. */
* - returns: requested string. Returns from static buffer when copy is FALSE */
static char* read_token(char* source, char delimeter, int *length, int *accumulated_length, gboolean copy)
{
- static char static_buffer[512];
+ static char static_buffer[1024];
int offset = 0;
char *source_proper = skipWhiteSpace(source, accumulated_length);
}
}
+/* Set the rawbytes property of a content field */
+static void rule_set_content_rawbytes(Rule_t *rule)
+{
+ if (rule->last_added_content) {
+ rule->last_added_content->rawbytes = TRUE;
+ }
+}
+
/* Set the http_method property of a content field */
static void rule_set_content_http_method(Rule_t *rule)
{
}
}
+/* Set the http_UserAgent property of a content field */
+static void rule_set_content_http_user_agent(Rule_t *rule)
+{
+ if (rule->last_added_content) {
+ rule->last_added_content->http_user_agent = TRUE;
+ }
+}
+
/* Add a uricontent field to the rule */
static gboolean rule_add_uricontent(Rule_t *rule, const char *uricontent_string, gboolean negated)
{
/* Write rule path variable value */
/* Don't assume $RULE_PATH will end in a file separator */
if (snort_config->rule_path_is_absolute) {
+ /* Rule path is absolute, so it can go at start */
g_snprintf(substituted_filename, 512, "%s%s%s",
snort_config->rule_path,
g_file_separator,
include_filename + 10);
}
else {
+ /* Rule path is relative to config directory, so it goes first */
g_snprintf(substituted_filename, 512, "%s%s%s%s%s",
config_directory,
g_file_separator,
}
else {
/* No $RULE_PATH, just use directory and filename */
- g_snprintf(substituted_filename, 512, "%s/%s", config_directory, include_filename);
+ /* But may not even need directory if included_folder is absolute! */
+ if (!g_path_is_absolute(include_filename)) {
+ g_snprintf(substituted_filename, 512, "%s/%s", config_directory, include_filename);
+ }
+ else {
+ g_strlcpy(substituted_filename, include_filename, 512);
+ }
}
/* Try to open the file. */
else if (strcmp(name, "http_cookie") == 0) {
rule_set_content_http_cookie(rule);
}
+ else if (strcmp(name, "http_user_agent") == 0) {
+ rule_set_content_http_user_agent(rule);
+ }
+ else if (strcmp(name, "rawbytes") == 0) {
+ rule_set_content_rawbytes(rule);
+ }
else if (strcmp(name, "classtype") == 0) {
rule_set_classtype(rule, value);
}
return FALSE;
}
+ if (pcre_length >= 512) {
+ /* Have seen regex library crash on very long expressions
+ * (830 bytes) as seen in SID=2019326, REV=6 */
+ return FALSE;
+ }
+
/* Verify that string starts with / */
if (content->str[0] != '/') {
return FALSE;