CSRF Advanced

소스코드 분석
def flag()
- /flag 경로로 POST 요청이 들어오면, 조건문 안의
check_csrf함수가 호출된다.

def check_csrf()
- 전달받은 인자(param) 값을
url변수에 저장하고read_url함수를 호출한다.

def read_url()
- 42-27 라인이 이 함수의 핵심 코드이다.
- /login 경로로 이동하여
admin계정으로 로그인을 시도한 후에/vuln?param={사용자 입력 값}으로 요청을 보낸다.

def login()
read_url함수의 46라인에 의해 /login 경로로 관리자 계정 접속이 시도된다.- 해당 요청은 유효한 아이디/패스워드가 전달되었으므로 정상적으로 세션과 CSRF 토큰이 저장된다.
- sessiond_id = os.urandom(8).hex()
- csrftoken = md((username + request.remote_addr).encode()).hexdigest()

def vuln()
- vuln 함수에서는 /vuln?param={사용자 입력 값} 에 대한 문자열 필터링 로직이 존재한다.
- 이미지(img) 태그 등을 사용하면 우회가 가능해 보인다.

def change_password()
- /change_password 경로로 요청이 보내지면 요청 헤더로부터
sessionid값을 가져와 저장한다. - 이후 서버에 저장된 세션 및 CSRF 토큰 값이 존재하면 아래 조건문(128 라인)으로 넘어간다.
- (1)
pw는 새로 설정할 패스워드 값이다. (/change_password 요청 시 인자로 함께 넘겨주어야 한다.) - (2)
csrf_token은 로그인 시 생성된 CSRF 토큰 값이다. (관리자 계정의 CSRF 토큰 값을 함께 넘겨줘야 한다.)

- (1)
- 관리자 계정의 CSRF 토큰 값은 아래와 같이 취약하게 생성되고 있어 값 탈취가 가능했다.
- (username + request.remote_addr) 값이 MD5 단방향 해시화 된 후 헥스 값으로 표현된 형태다.

- (username + request.remote_addr) 값이 MD5 단방향 해시화 된 후 헥스 값으로 표현된 형태다.
- 유저명(username)은 “admin” 이며, 요청을 보낸 원격지 주소(remote_addr)은 로컬 호스트이다.
- 이를 통해 관리자 계정의 CSRF 토큰 값을 생성했다.

- /flag 경로에서 관리자 계정의 패스워드를 변경을 시도했다.
<img/src='http://127.0.0.1:8000/change_password?pw=admin&csrftoken=7505b9c72ab4aa94b1a4ed7b207b67fb'>
- 변경된 패스워드로 관리자 계정 접속에 성공했다.

🐛.. 🐛.. 🐛..