CSRF : LAB [4]

DATE : 2024/1/29

CSRF 공격을 수행하기 위해 페이지 기능을 확인해보자!

우선, LAB으로 들어가면 중앙에 배치된 검색 바를 이용해 블로그를 찾아볼 수 있다.

이때 hanhxx 라는 키워드를 검색해보면 당연히 아무런 정보가 나오지 않는다.

중요한 건, 이때 주고 받은 Packet이다.

사용자가 입력한 검색어가 search parameter로 전달되는 동시에, 화면에 바로 그 값이 출력 되고 있는데

이때 주목할 부분이 하나 더 있다.

방금 입력했던 검색어가 Set-Cookie header를 통해 LastSearchTerm cookie로 만들어진다는 점이다.

이는 사용자가 입력한 값을 그대로 가져다가 빈 칸에 넣고 있는 상황이기 때문에

Set-Cookie: LastSearchTerm=____;

검색 바에 어떤 내용을 입력하느냐에 따라 Response header를 조작할 수 있을 지도 모른다.

다음으로 LAB에서 알려준 계정으로 로그인을 해봤다.

로그인을 하게 되면 사용자의 메일을 수정할 수 있는 FORM이 제공되는데

수정할 메일을 입력하게 되면 위와 같이 email & csrf parameter가 담긴 요청이 서버로 날아가게 된다.

특이한 건 csrfKey라는 cookie가 사용된다는 점이다.

Packet 내용만 보고 유추해보면 아마 csrf token을 가리키는 Key를 csrfKey cookie에 전달하는 거 같다.

즉 csrf token에 상응하는 csrfKey를 알 필요가 있어 보인다.

이번 LAB에서는 wiener 계정 뿐만 아니라 carlos의 계정 또한 제공하고 있다.

이번엔 carlos 계정으로 로그인 해보았다.

로그인을 하고 csrfKey cookie를 확인해봤더니..?

csrfKey & csrf token 모두 wiener의 것과 동일한 걸 알아챌 수 있을 것이다.

이번 LAB에서는 사용자 계정에 상관 없이 하나의 csrfKey와 csrf token을 사용하고 있는 듯하다.

그렇다면 이 cookie와 token을 이용해 메일 수정 request를 완성할 수 있다..!

지금까지 알아본 내용을 정리해보면

(1) csrf token : csrf라는 값으로 전달된다.

(2) csrfKey : csrfKey cookie로 만들어진다.

(3) 이 두 값은 사용자에 상관 없이 고정된 값이다.

(4) 블로그 검색 기능을 사용하면 입력 값이 LastSearchTerm cookie 안으로 들어간다.

우리는 다른 사용자가 자신도 모르는 사이에 이메일 수정 요청을 서버에 보내도록 만들어야 하기 때문에

우선 요청에 필요한 email & csrf parameter를 눈에 보이지 않도록 Form tag 안에 넣어준다.

<form action='https://LAB_ID.web-security-academy.net/my-account/change-email' method='post'>
    <input type='hidden' name='email' value='test@victim.net'>
    <input type='hidden' name='csrf' value='__CSRF TOKEN__'>
</form>

다음으로 위에 작성한 form이 서버로 전달되도록 img tag를 삽입해준다.

<img src='' onerror=''>

이때 중요한 건, csrfKey와 csrf token은 짝꿍이기 때문에

csrfKey를 생성하도록 src를 지정해줘야 한다는 것!

src='https://LAB_ID.web-security-academy.net/?search=hanhxx;%0d%0aSet-cookie: csrfkey=__CSRFKEY__; SameSite=None'

src를 이와 같이 지정하게 되면 <img> tag를 화면에 그리기 위해서 해당 경로로 요청을 보내,

검색 바에 hanhxx;%0d%0a..SameSite=None을 입력한 것과 동일한 결과를 가져오게 된다.

따라서 Response header에는

Set-cookie: LastSearchTerm=hanhxx;
Set-cookie: csrfKey=__csrfkey__; SameSite=None;
...

Form으로 전달할 csrf token과 짝꿍인 csrf ket를 생성하는 내용이 들어가게 된다.

<img> tag로 이 요청을 보내게 되면 사실 이미지가 없기 때문에 에러가 발생하게 되고

이 타이밍에 메일 요청을 서버로 보내도록

onerror='document.forms[0].submit()'

submit()을 onerror에 적어주면 스크립트 완성이다.

공격자 서버에서 스크립트를 작성한 뒤, 피해자에게 보내기 버튼을 클릭하면 성공적으로

Lab을 마무리할 수 있다. 👍

계속해서 CSRF 문제를 접해보고 있는데,

사실 스크립트를 작성해 공격이 이루어지다 보니 XSS라고 착각할 수 있다.

하지만! 엄연히 XSS와 CSRF는 다른 취약점이며

지금은" XSS로 CSRF를 수행하고 있다"는 게 적절한 설명일 듯하다.

Last updated