澄清整个PHP版本的XXE漏洞
我在这里发表了一个最后的问题,我已经浏览了网络,经历了许多尝试,但没有成功.
复制XXE攻击是我正在努力做的,以防止它们,但是我似乎并不关心PHP与XML实体的工作方式.为了纪录我在Ubuntu 12.04上使用PHP 5.5.10,但是我已经在5.4和5.3上做了一些测试,而libxml2似乎是版本2.7.8(似乎不包括默认的解析实体). 在以下示例中,使用true或false调用libxml_disable_entity_loader()没有任何效果,或者我做错了. $xml = <<<XML <?xml version="1.0"?> <!DOCTYPE root [ <!ENTITY c PUBLIC "bar" "/etc/passwd"> ]> <root> <test>Test</test> <sub>&c;</sub> </root> XML; libxml_disable_entity_loader(true); $dom = new DOMDocument(); $dom->loadXML($xml); // Prints Test. print $dom->textContent; 但是,我可以具体地传递一些参数来加载loadXML()以允许一些选项,当该实体是本地文件时,而不是当它是一个外部URL时. $xml = <<<XML <?xml version="1.0"?> <!DOCTYPE root [ <!ENTITY c PUBLIC "bar" "/etc/passwd"> ]> <root> <test>Test</test> <sub>&c;</sub> </root> XML; $dom = new DOMDocument(); $dom->loadXML($xml,LIBXML_NOENT | LIBXML_DTDLOAD); // Prints Test. print $dom->textContent; 现在,如果我们将实体更改为其他的东西,如下面的例子,实体被解决了,但我无法使用参数或函数禁用它…发生什么事? $xml = <<<XML <?xml version="1.0"?> <!DOCTYPE root [ <!ENTITY c "Blah blah"> ]> <root> <test>Test</test> <sub>&c;</sub> </root> XML; $dom = new DOMDocument(); $dom->loadXML($xml); // Prints Test. print $dom->textContent; 我可以找到的唯一方法是覆盖DOMDocument对象的属性. > resolveExternals设置为1 那么他们是解决了,还是不解决. 所以总结一下,我真的很想明白我显然不明白.为什么这些参数和功能似乎没有效果? libxml2是否优先于PHP? 非常感谢! 参考文献: > https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing
保持简单..因为它应该很简单:-)
你的第一个代码片段 libxml_disable_entity_loader根据您的系统默认情况下是否解析实体(我的)不执行或不执行任何操作.这由libxml的LIBXML_NOENT选项控制. 没有它,文档处理器可能甚至不会尝试翻译外部实体,因此libxml_disable_entity_loader没有任何真正的影响(如果libxml未在默认情况下加载实体,这在您的测试用例中似乎是这种情况). 将LIBXML_NOENT添加到loadXML(),如下所示: $dom->loadXML($xml,LIBXML_NOENT); 你会很快得到: PHP Warning: DOMDocument::loadXML(): I/O warning : failed to load external entity "/etc/passwd" in ... PHP Warning: DOMDocument::loadXML(): Failure to process entity c in Entity,line: 7 in ... PHP Warning: DOMDocument::loadXML(): Entity 'c' not defined in Entity,line: 7 in ... 你的第二个代码片段 在这种情况下,您通过使用LIBXML_NOENT选项启用实体解析,这就是为什么它在/ etc / passwd之后. 该示例在我的机器上正常工作,即使是外部URL – 我将ENTITY更改为外部URL: <!ENTITY c PUBLIC "bar" "https://stackoverflow.com/opensearch.xml"> 然而,它甚至可以受到例如的影响. allow_url_fopen PHP INI设置 – 将其设置为false,PHP将不会加载远程文件. 你的第三个代码片段 您提供的XML实体不是外部的,而是内部的(参见例如here). 您的实体: <!ENTITY c "Blah blah"> 内部实体的定义如何: <!ENTITY % name "entity_value"> 因此,PHP或libxml没有任何理由阻止此类实体的解析. 结论 我已经很快地建立了一个PHP XXE tester script,它尝试了不同的设置,并显示XXE是否成功,在哪种情况下. 实际显示警告的唯一一行是“LIBXML_NOENT”. 如果任何其他线路加载警告,外部实体加载!您的设置默认允许加载外部实体. 使用SHOULD USE libxml_disable_entity_loader(),无论您的/您的提供商的机器默认设置如何,您都不能出错.如果你的应用程序被迁移,它可能会立即变得脆弱. 正确使用 正如MediaWiki在link you’ve posted所说.
$oldValue = libxml_disable_entity_loader(true); // do whatever XML-processing related libxml_disable_entity_loader($oldValue); 注意:libxml_disable_entity_loader()还禁止直接加载外部xml文件(而不是通过实体): <?php $remote_xml = "https://stackoverflow.com/opensearch.xml"; $dom = new DOMDocument(); if ($dom->load($remote_xml) !== FALSE) echo "loaded remote xml!n"; else echo "failed to load remote xml!n"; libxml_disable_entity_loader(true); if ($dom->load($remote_xml) !== FALSE) echo "loaded remote xml after libxml_disable_entity_loader(true)!n"; else echo "failed to remote xml after libxml_disable_entity_loader(true)!n"; 在我的机器上 loaded remote xml! PHP Warning: DOMDocument::load(): I/O warning : failed to load external entity "https://stackoverflow.com/opensearch.xml" in ... failed to remote xml after libxml_disable_entity_loader(true)! 这可能与this PHP bug有关,但PHP真的很愚蠢: libxml_disable_entity_loader(true); $dom->loadXML(file_get_contents($remote_xml)); 工作很好 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |