我在这里发布一个问题作为最后的手段,我浏览了网络并进行了多次尝试但没有成功。
复制 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
- 替代实体设置为 1
然后他们解决了,或者没有。
总而言之,我真的很想了解我显然不了解的内容。为什么那些参数和函数似乎没有效果?libxml2 是否优先于 PHP?
非常感谢!
参考:
- https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing
- http://au2.php.net/libxml_disable_entity_loader
- http://au2.php.net/manual/en/libxml.constants.php
- http://www.vsecurity.com/download/papers/XMLDTDEntityAttacks.pdf
- http://www.mediawiki.org/wiki/XML_External_Entity_Processing
- 如何使用 PHP 的各种 XML 库来获得类似 DOM 的功能并避免 DoS 漏洞,例如 Billion Laughs 或 Quadratic Blowup?