본문 바로가기

Wargame(hacking)/PortSwigger

Lab : DOM XSS via client-side prototype pollution

Write Up

 

먼저, Prototype pollution 근원지를 수동으로 탐색해 본다. 이는 많은 시도와 에러들이 동반된다. 즉 Object.prototype 이 작동하는 근원지를 찾을 때까지 임의의 속성을 추가하는 다양한 방법을 시도해야 한다. 

 

→ 쿼리 스트링, URL fragment, JSON input을 통해 임의 속성 주입을 시도해 본다. 

 

해당 Lab에서는 쿼리 스트링을 사용해 속성 주입을 시도하였고, 성공적으로 prototype pollution 이 발생하였다. 

 

그림 1

 

만약, 속성이 Prototype에 추가되지 않은 경우 대괄호 표기 대신 점 표기 방식으로 전환하거나 그 반대로 전환하는 등 다양한 기술을 사용해봐야 한다. ( 해당 Lab에서는 . 표기 법으로는 prototype pollution에 실패 )

 

→ 위에서 전역에 임의의 속성을 추가할 수 있는 소스를 식별한 후의 단계는 exploit을 만드는 데 사용할 수 있는 적합한 가젯을 찾는 것이다. 

 

그림 2

 

deparam.js는 결론적으로 봤을 때, 객체를 반환하는 역할을 하는 js 이다. 그리고 searchLogger.js의 주요 코드는 아래와 같다. 

 

async function searchLogger() {
    let config = {params: deparam(new URL(location).searchParams.toString())};

    if(config.transport_url) {
        let script = document.createElement('script');
        script.src = config.transport_url;
        document.body.appendChild(script);
    }

    if(config.params && config.params.search) {
        await logQuery('/logger', config.params);
    }
}

 

config 객체에 transport_url이 존재하면, 새로운 <script> 태그를 생성하여 src 속성을 transport_url로 설정하며, 이 <script> 태그를 문서의 body에 추가하여 외부 스크립트를 동적으로 로드한다. 

 

config 객체에 정의된 transport_url 속성이 없고, 이는 src 요소를 제어할 수 있는 잠재적인 장치이다. 

 

→ exploit

 

그림 3

 

위와 같이 개발자 도구의 debugger를 활용하여, break point를 걸어준 뒤 config 객체의 transport_url 속성 값이 할당되는 것을 확인할 수 있다. 

 

그림 4

 

위 그림 4와 같이 XSS를 유발하는 payload를 삽입하여, <script>를 동적으로 로드 시켜 문제를 해결한다. 

 

 

 

▶ 참고 및 출처

  • https://portswigger.net/web-security/prototype-pollution/client-side/lab-prototype-pollution-dom-xss-via-client-side-prototype-pollution
  • https://medium.com/@fath3ad.22/understanding-dom-based-xss-sources-and-sinks-c17ae4bc7455