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” 외에도 동일한 기능을 제공하는 온라인 사이트가 있다.
- (Request Bin 사이트와 동일한 기능 제공) https://requestcatcher.com/
- (나중에 위 사이트들에서 제공하는 기능을 직접 개발해봐도 재밌을 것 같다.)
🐛.. 🐛.. 🐛..