正则表达式规则匹配字符串
Regex rule match up to string
我需要使用 grep / egrep / sed 从 SNORT 规则字符串中提取某些部分。
给定一个可以采用以下格式的字符串:
alert tcp any any -> any any (msg:"Some message";
content:"c1"; content:"GET /blah"; offset:0; depth:9; content:"something else";)
我将如何提取以下内容:
content:"GET /blah"; offset:0; depth:9;
鉴于以下内容为真:
- 它必须匹配直到下一个内容匹配开始(如果有的话)
- 一个规则可能只有这个内容项,它可能有更多,并且它们可以以任何顺序排列
- 可以在偏移和深度运算符之前、之后或之间应用其他修饰符,它们也必须按如下方式提取:
content:"GET "; offset:5; http_uri; depth:12;
规则可以是 "malformed" 即,在内容术语后可以有两个或更多分号,而不是一个分号。
到目前为止,我认为可以在其他正则表达式系统中使用的是:
(GET|POST).*?(?=content)
这背后的想法是 .*?
是对任何字符任意次数的非贪婪匹配,并且是对下一个术语 "content" 的非抓取(不确定是否是该术语)匹配。
我相信如果没有后续内容术语并且似乎也没有在 grep 或 egrep 中提取任何内容,我相信这会中断。
不知道该怎么做,有什么想法吗?
这应该可以解决问题:
grep -Po '\bcontent\s*:\s*"(GET|POST)\b[^"]*"((?!;\s*content\s*:)[^"]|"[^"]*")*;'
示例输入:
alert tcp any any -> any any (msg:"Some message";
content:"c1"; content:"GET /blah"; offset:0; depth:9; content:"something else";)
content:"GET "; offset:5; http_uri; depth:12;
输出:
content:"GET /blah"; offset:0; depth:9;
content:"GET "; offset:5; http_uri; depth:12;
解释:
- 我没有展望下一个
content
,而是使用 negative 展望来消费单词 content
以外的任何内容。这样,行尾也算作比赛结束。
正则表达式的详细信息:
\b
- 单词边界(以防止匹配,例如 othercontent
)
content\s*:\s*
- 字面意思:内容后跟一个冒号;有可选空格
"
- 开场白
(GET|POST)
- 这些动词之一
\b
- 单词边界(以防止匹配,例如 POSTAL
)
[^"]*"
- 包括收盘价在内的所有内容
(
- 开始重复子模式
(?!;\s*content\s*:)
- 负前瞻,以确保我们在任何后续 content
之前停止
[^"]
- 任何非引号;空格、字母、冒号、分号...
|
- 或...
"[^"]*"
- 一些属性字符串;将其作为一个整体进行匹配,以防止负面前瞻在引号之间选择某些东西
)*
- 结束重复子模式;零次或多次
;
- 结束分号
我需要使用 grep / egrep / sed 从 SNORT 规则字符串中提取某些部分。
给定一个可以采用以下格式的字符串:
alert tcp any any -> any any (msg:"Some message";
content:"c1"; content:"GET /blah"; offset:0; depth:9; content:"something else";)
我将如何提取以下内容:
content:"GET /blah"; offset:0; depth:9;
鉴于以下内容为真:
- 它必须匹配直到下一个内容匹配开始(如果有的话)
- 一个规则可能只有这个内容项,它可能有更多,并且它们可以以任何顺序排列
- 可以在偏移和深度运算符之前、之后或之间应用其他修饰符,它们也必须按如下方式提取:
content:"GET "; offset:5; http_uri; depth:12;
规则可以是 "malformed" 即,在内容术语后可以有两个或更多分号,而不是一个分号。
到目前为止,我认为可以在其他正则表达式系统中使用的是:
(GET|POST).*?(?=content)
这背后的想法是 .*?
是对任何字符任意次数的非贪婪匹配,并且是对下一个术语 "content" 的非抓取(不确定是否是该术语)匹配。
我相信如果没有后续内容术语并且似乎也没有在 grep 或 egrep 中提取任何内容,我相信这会中断。
不知道该怎么做,有什么想法吗?
这应该可以解决问题:
grep -Po '\bcontent\s*:\s*"(GET|POST)\b[^"]*"((?!;\s*content\s*:)[^"]|"[^"]*")*;'
示例输入:
alert tcp any any -> any any (msg:"Some message";
content:"c1"; content:"GET /blah"; offset:0; depth:9; content:"something else";)
content:"GET "; offset:5; http_uri; depth:12;
输出:
content:"GET /blah"; offset:0; depth:9;
content:"GET "; offset:5; http_uri; depth:12;
解释:
- 我没有展望下一个
content
,而是使用 negative 展望来消费单词content
以外的任何内容。这样,行尾也算作比赛结束。
正则表达式的详细信息:
\b
- 单词边界(以防止匹配,例如othercontent
)content\s*:\s*
- 字面意思:内容后跟一个冒号;有可选空格"
- 开场白(GET|POST)
- 这些动词之一\b
- 单词边界(以防止匹配,例如POSTAL
)[^"]*"
- 包括收盘价在内的所有内容(
- 开始重复子模式(?!;\s*content\s*:)
- 负前瞻,以确保我们在任何后续content
之前停止
[^"]
- 任何非引号;空格、字母、冒号、分号...|
- 或..."[^"]*"
- 一些属性字符串;将其作为一个整体进行匹配,以防止负面前瞻在引号之间选择某些东西)*
- 结束重复子模式;零次或多次;
- 结束分号