[Dreamhack] csrf-2 풀이

minkyung·2023년 6월 6일
0

Dreamhack

목록 보기
4/6

csrf-1 문제와 유사하게 csrf 공격, 즉 사용자의 session 정보를 이용하여 악의적인 요청을 하도록 만드는 문제이다.

코드 분석은 까다롭지만 exploit은 쉽다.

🔎 csrf-2 분석

들어가면 처음 보이는 화면

vuln(csrf) page, flag page, login page 총 3개의 페이지로 이동을 할 수 있다.

vuln(csrf) page는 이전의 문제들처럼 취약점이 존재하는 공격 대상 링크이다.

flag 페이지에는 vuln 페이지로 연결되는 url 링크를 적어서 제출할 수 있다.

마지막으로 login 페이지이다. 이전 문제들에서는 보지 못한 새로운 페이지이다.

💻 소스코드 분석

users

먼저 users 에 대한 딕셔너리가 있다. guest는 guest, admin은 FLAG인데 이게 아마 로그인에 필요한 회원 정보이고 각각 ID, PW 값인듯하다.

guest로 로그인 해보면 이렇게 된다.

index():

index 페이지를 잘 보면, rendering 할 때의 text를 username에 따라서 다르게 표시하고 있다.

기본적으로는 pleas login
username이 admin이 아닐 경우 (guest) you are not an admin
admin일 경우 flag is [FLAG]로 flag를 출력한다.

여기서 admin 계정으로 로그인을 해야겠다는 생각을 할 수 있다.
그런데 우리는 FLAG를 알기위해 admin으로 로그인을 해야하는데, admin의 비밀번호가 FLAG인 상황..

코드를 끝까지 살펴보면 chang_password라는 함수가 있다.

change_password():

이 페이지는 존재하긴 하지만 숨겨져있는 페이지이다.

이 페이지가 존재하는지 확인하기 위해 링크 끝에 /change_password를 입력하여 이동해보면 잘못된 url 페이지가 뜨는 것이 아닌, 코드대로 index.html로 이동하는 것을 알 수 있다.

그럼 이 페이지로 이동하여 admin의 pw를 바꿔주어 로그인을 하면 될 것 같다.

좀 더 자세히 소스코드를 분석해보자.

def change_password():
    pw = request.args.get("pw", "")
    session_id = request.cookies.get('sessionid', None)
    try:
        username = session_storage[session_id]        

코드를 보면 인자로 pw를 받아오고 cookie 값에서 sessionid 라는 것을 받아온다.
그 후 session_storage에 session_id 값으로 저장된 것을 찾아 username으로 설정한다.

그럼 우선 cookie 값에 admin의 sessionid가 저장되어 있어야 하는데 이 부분의 쿠키값이 언제 만들어지고 추가가 되는 걸까?

flag():

바로 flag 페이지를 확인해보면, 여기서 제출을 눌러 POST를 할 때
session_id로 랜덤 헥사값이 만들어지고 이 값이 다시 session_storage에 admin이라고 저장이 된다.

그리고 이 session_id 값은 우리가 입력한 param 과 함께 check_csrf 함수로 전달 된다.

check_csrf() & read_url() :

이 부분의 코드는 많이 봐와서 익숙하다. check_csrf에서 전달한 session_id 가 cookie가 되고 입력한 param을 url 형태로 만들어준다. 주소는 127.0.0.1:8000으로 우리가 접근할 수 없는 환경을 의미한다.

다음으로 read_url에서는 먼저 127.0.0.1:8000 url을 열고 거기에 cookie를 추가한다. cookie에는 admin의 session을 의미하는 랜덤 헥사값이 들어갈 것이다. 그 다음 우리가 입력한 url을 연다.

📒 해답

결국 우리는 admin의 sessionid가 저장된 url에서 change_password 페이지로 이동하여 pw를 바꾸도록 유도해야한다.

127.0.0.1:8000은 우리가 접근할 수 없기 때문에 flag 페이지에서 cookie에 admin의 sessionid를 저장시킨 후의 (cookie 값 추가는 코드를 보면 알아서 한다.) 127.0.0.1:8000으로 이동하게 하고 change_password 페이지로 이동하여 pw=1234 와 같이 바꿔주도록 exploit을 작성했다.

<img src="http://127.0.0.1:8000/change_password?pw=1234">

이걸 입력하고 제출하면 pw 변경 성공!

정상적으로 비밀번호가 바뀌었다.

flag 탈취 성공 💗

profile
개발/보안 기록용

0개의 댓글