https://dreamhack.io/wargame/challenges/409
이전에 쿠키의 취약점을 통해 문제를 해결했다.
쿠키는 클라이언트 브라우저에 저장되어 조작될 위험이 존재하는데, 이 취약점을 막기위해 세션(session)이 도입되었다.
세션은 인증 정보를 서버에 저장하고 해당 데이터에 접근할 수 있는 키(유추할 수 없는 랜덤한 문자열)를 만들어 클라이언트에 전달한다. 그런 키를 일반적으로 Session ID라고 하며, 서버는 요청에 포함된 키에 해당하는 데이터를 가져와 인증 상태를 확인한다.
쿠키에는 클라이언트의 세션 정보가 저장되어 있고 서버는 이를 통해 이용자를 식별하고 인증을 처리한다. 공격자가 이용자의 쿠키를 훔칠 수 있으면 세션에 해당하는 이용자의 인증 상태를 훔칠 수 있는데, 이를 세션 하이재킹 (Session Hijacking)이라고 한다.
로그인에 대한 단서를 찾기위해 python코드를 먼저 보자
쿠키의 sessionid로부터 session_id
를 받아온다.
session_storage
에서 session_id
를 키 값으로 가지는 value값을 username
으로 반환한다.
비밀번호는 아이디에 입력으로 준 username
을 users
딕셔너리에서 아이디를 키 값으로 대응되는 value값이 된다.
또한 로그인에 성공하면 쿠키에 무작위 키 값을 sessionid
로 제공해준다
초기에는 개발자 툴의 쿠키에 아무것도 없을 것이다.
우선 로그인에 성공해 임의의 세션 id를 얻어보자
유저로 로그인에 성공했다
이제 다시 쿠키를 확인해보자
쿠키에 난수를 값으로 하는 sessionid가 생성되었다!
앞서 admin을 찾을 수 있는 username
은 session_id
의 값을 키 값으로 하여, session_storage
딕셔너리에서 찾을 수 있는데 뭔가 이상하다.
session_storage
에 아무것도 없다
이게 어떻게 된 일인가?
코드의 마저 남은 부분을 보면 session_storage
를 반환해준다고 나온다.
저 route에서 지정해준 URL경로로 들어가면 session_storage
를 확인할 수 있을 것이다.
사진 맨 윗줄의 route(경로)
는 초기 경로로부터 하위 경로로 들어가는 위치에 대응하면, 이어서 주어지는 함수를 실행하겠다는 의미이다.
그래서 로그인 화면을 들어갈때 URL을 보면 기존 URL의 뒤에 /login
이 붙게되고, route('/login')
으로 감싸진 코드가 실행이 되는 것이다.
이러한 단서를 기반으로 초기 URL의 뒤에 /admin
을 추가한 URL에 접근해보자.
딕셔너리 형태로 이루어진 session_storage
가 웹에 띄워졌다!
이제 admin에 대응하는 난수 키 값을 쿠키 sessionid의 값에 넣게되면 username
에 admin이 대응될 것이며, 따라서 플래그를 구할 수 있게 된다!