ShareProfile


소스코드 분석

  • app.py 파일에서 사용되는 주요 함수는 아래와 같다.
주요 함수기능 설명
create_token(username)유저명을 기반으로 JWT 토큰을 생성
verify_token(token)인자로 전달받은 token 값을 디코딩
init_db()users, profiles 테이블 생성 및 초기화
get_db()데이터베이스 연결 및 쿼리 결과 행으로 반환
index()”/” 경로 접근 시 profiles 테이블에 저장된 값들을 화면에 렌더링
login()유효한 계정정보로 로그인 시 해당 계정에 대한 JWT 토큰 발급
register()회원가입 시 입력된 정보를 users, profiles 테이블에 저장
update_profile()JSON 형태로 전달받은 token 값을 검증하고, 프로필 업데이트 진행
admin()JSON 형태로 전달받은 token 값을 검증하고, JWT 토큰이 관리자의 토큰일 경우 플래그를 출력
report()스레드를 생성하여 check 함수 호출(실행)
get_admin_password()관리자 계정의 패스워드 값을 반환
check()셀레니움 라이브러리의 드라이버 모듈을 통해 관리자 계정 로그인

  • 관리자 계정의 패스워드는 os.urandom(16).hex()로 구성되어 있기 때문에 브루트포스로 값을 확인하는 것은 어려웠다. 따라서, 관리자 계정 혹은 권한을 획득할 수 있는 다른 방법을 탐색해야 한다.

  • report() 함수를 살펴보면, 아래의 과정을 통해 관리자 계정으로 접속을 시도한다.
    • report() > check() > get_admin_password() > login()

  • loginBtn 버튼이 클릭되면, /api/login 경로로 POST 요청을 보내고,
  • 응답을 받는데 성공하면, 해당 계정의 JWT 토큰 값이 data.token 형태로 URL 주소에 반환된다.
    • (67라인에 의해 "/?token=" + encodeURIComponent(data.token) 경로로 이동된다.

  • login() 함수는 아래의 순서로 동작한다.
    • (1) POST /api/login 요청 시 입력된 파라미터(username, password)로 DB에 유효한 계정 조회
    • (2) 조회되는 계정명이 있고, 패스워드도 일치하면 해당 계정의 JWT 토큰을 생성하여 반환

EXPLOIT

  • HTTP 요청 시에는 요청 헤더에 “Referer” 헤더가 존재하는데, 이 값은 해당 요청이 어느 위치(자원)로부터 왔는지를 나타내는 값이다. 만약 네이버 메인 홈페이지에서 검색창에 임의의 값을 입력하면 “Referer” 주소는 아래와 같이 바로 전 페이지의 URL이 설정된다.

  • 그럼 이제 “Referer” 헤더에 관리자의 토큰 값이 오도록 설정해야 하는데, 이걸 어떻게 할 수 있을까?
  • blind-command 문제에서 사용했던 Request bin 을 사용해볼 수 있겠다.

  • (1) ShareProfile 홈페이지에서 회원가입 후 해당 계정(EX; TEST)으로 로그인
  • (2) 프로필 업데이트 기능을 통해 프로필 이미지 경로를 “Request Bin” 주소로 설정 후 업데이트
  • (3) “Report” 버튼을 눌러, 백그라운드 셀레니움에서 관리자 계정으로 로그인 하도록 유도
    • (3-1) 관리자 계정으로 로그인 성공 후 관리자의 JWT 토큰 발급
    • (3-2) URL이 /?token={관리자 JWT} 으로 설정됨
    • (3-3) TEST 계정의 프로필 이미지 URL(Request Bin URL)로 요청이 보내짐
    • (3-4) “RequestBin”에서 확인 시 /?token={관리자 JWT} 값이 “Referer” 헤더에 노출됨

  • 플래그를 얻기 위해서는 /api/admin 경로로 관리자 계정의 JWT 토큰을 함께 전송하면 된다.
  • (쨘! 플래그 획득 성공)

번외

  • 드림핵에서 제공하는 “Request Bin” 외에도 동일한 기능을 제공하는 온라인 사이트가 있다.
  • (나중에 위 사이트들에서 제공하는 기능을 직접 개발해봐도 재밌을 것 같다.)

🐛.. 🐛.. 🐛..