最近,Pocket应用的开发人员修复了几个泄露数据的漏洞,黑客可从服务器上获取敏感信息。这里献上教程,供大家学习交流。
Pocket是什么
我已经很多年没把Firefox当作我的主力浏览器了,所以其实之前我都没有听说过Pocket,直到我在Bugzilla看到这么篇帖子,讲的就是Mozilla基金会在所有版本的Firefox中预装了Pocket插件,并且这个插件无法卸载。尽管这引起了用户们的强烈抗议,基金会还是固执地绑定Pocket。
Pocket的功能就是让用户保存网页“稍后阅读”。Pocket可以将你要阅读或者一时没有读完的网页标记下来,接着同步到服务器端,然后你就可以在不同的设备上阅读。作为信息安全从业者,我发现这种功能通常都会导致安全问题,所以我就打算检查一下Pocket有没有问题。
事实上,这些漏洞中,大部分就可以被攻击者利用了。攻击者想要利用这些漏洞都不需要什么复杂的工具,甚至连脚本的知识都不需要。
尝试1:协议处理程序
用户可以通过Pocket网站上的队列管理功能添加URL到队列中。由于应用的用途主要是浏览网上的网页,所以这些URL理应被限制,应该只允许http和https链接。所以首先我尝试在队列中添加以下链接:
file:///etc/passwd
ssh://localhost
telnet://localhost:25
很遗憾,经过测试,这些都没成功
尝试2:利用Pocket功能作为内网代理
我之前在Apache服务器的状态页面看到过一条Apache错误信息。这种错误信息通常是.htaccess或者Apache配置文件限制了localhost或一些信任的网段访问server-status的时候才会出现的:
Forbidden
You don't have permission to access /server-status on this server.
我在我的Pocket队列中加了一条新链接:http://127.0.0.1/server-status。加入后,后端服务器就会发送HTTP请求获取内容。Apache会信任来自localhost的请求吗?
事实证明,这一招很管用,之后我就在Pocket队列中看到了如下信息:
Apache Server Status for 127.0.0.1
Server Version: Apache/2.2.29 (Unix) DAV/2
Server Built: Mar 12 2015 03:50:17
Current Time: Tuesday, 28-Jul-2015 10:07:45 CDT
Restart Time: Tuesday, 28-Jul-2015 03:20:12 CDT
Parent Server Generation: 12
Server uptime: 6 hours 47 minutes 32 seconds
Total accesses: 241913 - Total Traffic: 4.1 GB
CPU Usage: u1209.24 s110.06 cu0 cs0 - 5.4% CPU load
9.89 requests/sec - 177.5 kB/second - 17.9 kB/request
40 requests currently being processed, 14 idle workers
...
服务器状态情况的全部输出被同步到了我的Android上。Apache的mod_status可以显示出大量有用的信息,包括内部来源和目标IP地址,发送的请求中的URL的参数,还有查询参数。对于Pocket应用,请求的URL包括Pocket用户们正在浏览的URL,因为这些请求是通过HTTP GET方式进行的。
要隐藏上述的这些服务器信息,我们可以关闭Apache中的ExtendedStatus。大部分Pocket的后端服务器都关闭了ExtendedStatus,但是很小一部分的服务器还是开着,所以就导致攻击者可以获取到这些有用的信息。
另外,通过修改server-status 的GET参数,攻击者可以强制然Pocket重新下载页面,这样黑客就有可能获取到不同服务器的信息。
http://127.0.0.1/server-status?meaningless_parameter=1
http://127.0.0.1/server-status?meaningless_parameter=2
http://127.0.0.1/server-status?meaningless_parameter=3
Pocket搭建在亚马逊EC2上
既然Pocket存在漏洞可以让用户获取到Pocket后端服务器的相关信息,我们就看看利用这个漏洞我们还能获取到哪些信息。简单使用dig命令,我们就可以知道Pocket用的是亚马逊的EC2服务器。亚马逊的EC2有个实例元数据服务。这个服务只能从内部访问,无需验证,在所有的EC2实例上都有。我们可以尝试使用这个服务获取更多的信息:
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/hostname
http://169.254.169.254/latest/meta-data/ami-id
在Pocket队列中添加了上面的这些链接后,我就能看到完整的服务器回应了。EC2的元数据包括很多对攻击者有用的信息,包括IAM登录信息,还有关于这个instance的细节信息,包括可用区、instance类型、网络类型、MAC地址,块存储器的信息等。
攻击者还可以干什么呢?
对localhost的HTTP服务进行端口扫描,这可以绕过EC2的防火墙规则
对端口扫描的结果进行分析,识别开启的web应用
在Pocket内部环境下进行漏洞利用
很多大企业或者小公司都会有只能通过内部访问的web应用,这些应用通常无需验证,因此很容易会被攻击者利用。
server-status中的这些内部IP地址能用来干什么呢
从亚马逊EC2元数据上可以看出,Pocket使用的EC2服务器是在us-east-1(美东1区)区域,网络类型是classic(EC2有两种网络类型可选:EC2-Classic 和VPC。VPC更好一些,有些实例类型也只有VPC上才有。VPC在创建子网络和访问控制列表(ACL)的时候更加灵活)。
由于Pocket用的是EC2-Classic,要访问server-status中的内部IP地址,只需要在us-east-1区域租个2美分/小时的t1.micro实例。这样攻击者就可以使用RFC-1918地址访问这些实例上运行的服务了,例如ssh和http,甚至还可以进行端口扫描。
使用这些内部IP地址访问后端服务器有几个优点:
可以绕过前端负载平衡器和前端的WAF防火墙之类的东西,在有前端负载平衡器的情况下,攻击者可以通过设置X-Forwarded-For修改源IP地址,黑客可以通过这种方法避开ACL或者伪造log。
输入重定向
像Pocket这一类的应用在处理HTTP重定向链接的时候很有可能会忽视某些问题,造成安全隐患。那在URL队列中加入重定向链接会发生什么呢?我输入了file:///etc/passwd,后果很严重:
HTTP/1.1 301 Moved Permanently
Location: file:///etc/passwd
Content-Length: 52
Date: Tue, 28 Jul 2015 18:42:58 GMT
Connection: keep-alive
Moved Permanently. Redirecting to file:///etc/passwd
我在Android机上刷新了Pocket应用后,队列中就增加了file:///etc/passwd。点击之后,/etc/passwd完整的内容就呈现在了我眼前。
应Pocket的要求,/etc/passwd内容已删除
漏洞能够造成什么影响可以留给读者考虑。
有了/etc/passwd之后能干什么
在测试Pocket的时候,我用这个重定向漏洞请求了file:///proc/self/status文件,这个文件可以用来获取正在运行的进程的更多信息。
下面就是部分进程状态信息:
Uid: 0 0 0 0
Gid: 0 0 0 0
以root身份运行这个进程能够造成什么后果也留给读者考虑。
把漏洞结合起来
Pocket针对我的报告快速做出了回应,所以我没能够把这些漏洞结合起来。但是设想如果真的有个心怀不轨的攻击者发现了这些漏洞,他能做些什么呢?
1. 通过301重定向获取file:///etc/passwd文件,然后获取EC2用户的home目录
2. 从用户home目录获取ssh私钥
3. 使用/server-status获取内部IP地址
4. 租一个EC2实例,地区设置在US-EAST-1地区
5. 用获取的到的ssh私钥连接Pocket后端服务器的IP地址
接下来能做什么,你懂的^_^
Pocket的漏洞披露政策还是很负责的,我把所有的漏洞细节第一时间提交给了Pocket官方,而漏洞披露时间是由提交者自行决定的,不过要在漏洞提交后的21天后,好让Pocket有时间处理漏洞。现在漏洞都已经修复。