pcre 中的终止问题
Termination issue in pcre
实际上我正在为我的 Snort IDS 构建规则并试图解决 Billion Laughs 攻击的问题。它只不过是预定义变量的递归调用。 Snort 规则可能包含 pcre,因此我尝试为这种攻击构建智能规则。这可能是这种攻击的一种简单形式,在实体行之间有随机行。
<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a1 "&a2;&a2;&a2;&a2;&a2;&a2;">
test
<!ENTITY a1 "&a2;&a2;&a2;&ertertert;&a2;&a2;">
<!ENTITY a1 "&a2;&a2;&a2;&ertertert;&a2;&a2;">
<!ENTITY a1 "&a2;&a2;&a2;&a2;&a2;&a2;">
d
dd
<html abc>
a
<!ENTITY a2 "&a3;&a3;&a3;&a3;&a3;">
<!ENTITY a1 "&a0;&a0;&a0;&a0;&d5;">
]>
<data>&a2;</data>
这是我的实际规则:
(<!ENTITY\s[a-zA-Z0-9]*\s"(&[a-zA-Z0-9]+;){4,}">(\s?)[^]]*){5,}
解释一下我想达到的目标:
只要有至少 5 个实体行和至少 4 个 & 参数,就必须触发该规则。如果5行都依次跟进,就没有问题,
但是 ENTITY 行不需要一个接一个地出现。所以我必须捕获两个 ENTITY 行之间的所有其他内容,这使得整个事情成为一个大的终止问题,因为 [^]]* 捕获除 ] 之外的所有内容,并且还捕获整个 ENTITY 行并使我的量词 {5, } 完全没用。其实我找不到任何好的解决方案来解决我的问题。
感谢你们的帮助!
您可以使用
(?s)<!ENTITY\s[a-z0-9]*\s"(&[a-zA-Z0-9]+;){4,}">(?:.*?<!ENTITY\s[a-z0-9]*\s"(&[a-zA-Z0-9]+;){4,}">){4,}
详情
(?s)
- DOTALL 模式开启,.
现在匹配任何字符
<!ENTITY
- 文字 <!ENTITY
子串
\s
- 一个空格
[a-z0-9]*
- 0+ 个字母/数字
\s
- 一个空格
"
- 一个"
(&[a-zA-Z0-9]+;){4,}
- 4 次或更多次重复 &
,1+ 个字母数字字符,然后是 ;
">
- ">
子串
(?:
- 非捕获组匹配的开始....
.*?
- 任意 0+ 个字符,尽可能少
<!ENTITY\s[a-z0-9]*\s"(&[a-zA-Z0-9]+;){4,}">
- 与上面相同的模式
){4,}
- ... 4 次或更多次。
实际上我正在为我的 Snort IDS 构建规则并试图解决 Billion Laughs 攻击的问题。它只不过是预定义变量的递归调用。 Snort 规则可能包含 pcre,因此我尝试为这种攻击构建智能规则。这可能是这种攻击的一种简单形式,在实体行之间有随机行。
<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a1 "&a2;&a2;&a2;&a2;&a2;&a2;">
test
<!ENTITY a1 "&a2;&a2;&a2;&ertertert;&a2;&a2;">
<!ENTITY a1 "&a2;&a2;&a2;&ertertert;&a2;&a2;">
<!ENTITY a1 "&a2;&a2;&a2;&a2;&a2;&a2;">
d
dd
<html abc>
a
<!ENTITY a2 "&a3;&a3;&a3;&a3;&a3;">
<!ENTITY a1 "&a0;&a0;&a0;&a0;&d5;">
]>
<data>&a2;</data>
这是我的实际规则:
(<!ENTITY\s[a-zA-Z0-9]*\s"(&[a-zA-Z0-9]+;){4,}">(\s?)[^]]*){5,}
解释一下我想达到的目标:
只要有至少 5 个实体行和至少 4 个 & 参数,就必须触发该规则。如果5行都依次跟进,就没有问题, 但是 ENTITY 行不需要一个接一个地出现。所以我必须捕获两个 ENTITY 行之间的所有其他内容,这使得整个事情成为一个大的终止问题,因为 [^]]* 捕获除 ] 之外的所有内容,并且还捕获整个 ENTITY 行并使我的量词 {5, } 完全没用。其实我找不到任何好的解决方案来解决我的问题。
感谢你们的帮助!
您可以使用
(?s)<!ENTITY\s[a-z0-9]*\s"(&[a-zA-Z0-9]+;){4,}">(?:.*?<!ENTITY\s[a-z0-9]*\s"(&[a-zA-Z0-9]+;){4,}">){4,}
详情
(?s)
- DOTALL 模式开启,.
现在匹配任何字符<!ENTITY
- 文字<!ENTITY
子串\s
- 一个空格[a-z0-9]*
- 0+ 个字母/数字\s
- 一个空格"
- 一个"
(&[a-zA-Z0-9]+;){4,}
- 4 次或更多次重复&
,1+ 个字母数字字符,然后是;
">
-">
子串(?:
- 非捕获组匹配的开始.....*?
- 任意 0+ 个字符,尽可能少<!ENTITY\s[a-z0-9]*\s"(&[a-zA-Z0-9]+;){4,}">
- 与上面相同的模式
){4,}
- ... 4 次或更多次。