欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

看我如何发现价值3万6千美金的谷歌RCE漏洞

来源:本站整理 作者:佚名 时间:2018-05-28 TAG: 我要投稿


本文讲述了乌拉圭公立大学18岁学生 Ezequiel Pereira 发现谷歌(Google)最高级别RCE漏洞的相关过程。在今年年初,Ezequiel发现了谷歌Google App Engine (GAE)某非生产环境下的一个漏洞,利用该漏洞可以实现对谷歌部署环境的间接访问,并能发现和调用谷歌内部API接口,按照谷歌漏洞评价机制,该漏洞被评定为最高级别的远程代码执行漏洞(RCE),最终,Ezequiel凭借该漏洞,获得了谷歌赏金项目单个漏洞最高奖励的3万6千美金($36,337)。以下是Ezequiel对该漏洞的挖掘思路和相关过程分享。
提示:本文涉及了大量谷歌GAE的使用和操作,需要读者具备一些GAE应用经验。另外,漏洞测试过程中的一些概念和引用来自于 Ezequiel 在GAE上架设的这个App示例应用-http://save-the-expanse.appspot.com/,你可以在他的Github中来查看,其中包含了整个漏洞测试过程中涉及的源码和过程,有在线的Nmap、 gRPC C++ client 和 Google Protocol Buffe(谷歌内部的混合语言数据标准)。
先导概念
Google App Engine:GAE,是谷歌旗下一个开发托管网络应用程序的平台,它使用了谷歌数据管理中心的云计算技术,能跨越多个服务器和数据中心来虚拟化应用程序,可用任意编程语言构建可扩展的网页后端和移动后端,目标旨在开放的云端平台上打造新型的网页和移动应用。App Engine 支持 Node.js、Java、Ruby、C#、Go、Python 和 PHP,开发者只需轻松编写代码即可。
Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准,用于 RPC 系统和持续数据存储系统,Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化(序列化),它很适合做数据存储或 RPC 数据交换格式,可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前Google Protocol Buffer提供了 C++、Java、Python 三种语言的 API。
猜测琢磨
早前,我不经意间发现,谷歌GAE应用对每个HTTP请求的响应中都包含了一个”X-Cloud-Trace-Context”的头信息,由此,我先假设任何返回该头信息的网站都可能在GAE上运行。
幸运的是,后来我了解到 appengine.google.com 也运行在GAE上,但它却能执行一些通用用户和其它环境应用中不能执行的操作,因此,我尝试着来看看它是如何来执行这些操作的。很明显,它肯定是调用了一些API、接口或谷歌自身应用之类的东西来实现这些操作的,但我想应该总有一种方法来一窥究竟的。
一开始,我了解了GAE app应用的内部操作机制,比如日志写入或OAuth令牌获取,之后,我发现在Java 8环境中,它会向谷歌位于亚马逊DNS服务器地址http://169.254.169.253:10001/rpc_http上的某个内部HTTP服务端,发送二进制线型格式(wire format)的谷歌内部Protocol Buffer混合语言数据消息(PB 消息),其涉及到的HTTP请求大致如下:
POST /rpc_http HTTP/1.1
Host: 169.254.169.253:10001
X-Google-RPC-Service-Endpoint: app-engine-apis
X-Google-RPC-Service-Method: /VMRemoteAPI.CallRemoteAPI
Content-Type: application/octet-stream
Content-Length:
而这些PB消息则是一些 “apphosting.ext.remote_api.Request” 请求消息,它具备以下几个属性:
service_name = 要调用的API名称
method = 要调用的API方法名称
request = 内部的PB请求消息字节 (由二进制线型格式编码)
request_id = 安全票据(随每个GAE请求一起提供给app),标记为可选,但是却是必需的安全验证方式
HTTP请求的响应与表示API响应或错误消息的PB消息相对应。
Java 8环境下的安全票据可以通过以下代码行来进行获取:
import com.google.apphosting.api.ApiProxy;
import java.lang.reflect.Method;
Method getSecurityTicket = ApiProxy.getCurrentEnvironment().getClass().getDeclaredMethod("getSecurityTicket");
getSecurityTicket.setAccessible(true);
String security_ticket = (String) getSecurityTicket.invoke(ApiProxy.getCurrentEnvironment());
可以大概描述一个过程示例,比如我要获取这个 “https://www.googleapis.com/auth/xapi.zoo” 测试范围的谷歌认证令牌,那么会涉及以下几个步骤:
1 生成一个apphosting.GetAccessTokenRequest请求消息,其中包含:
scope = ["https://www.googleapis.com/auth/xapi.zoo"]
2 生成一个apphosting.ext.remote_api.Request请求消息,其中包含:
service_name = “app_identity_service” (API提供的GAE服务账户)
method = “GetAccessTokenRequest”
request = 以二进制线型格式编码的,前一步骤中生成的PB消息字节
request_id = Security ticket
3 发送HTTP请求
4 解码”apphosting.GetAccessTokenResponse“响应信息
由于这种Java 8环境中,可以通过这个被发送了PB消息的内部服务端来访问到谷歌的一些内部资源,我猜想该服务端肯定和 “appengine.google.com” 的内部操作相关,但烦心的是我还暂时未在该服务端中发现某些蛛丝马迹。
测试验证
起初,我认为整个PB消息和HTTP请求交互过程,可能还用到了谷歌在亚马逊DNS服务器地址169.254.169.253中的其它服务端,所以,我还向GAE服务中上传了一份静态的Nmap程序来扫描探测169.254.169.253的各种端口,因为Nmap要在GAE中运行,所以我以app方式进行了上传,由于其它的文件系统是只读权限,因此需要运行时,我就把它复制到/tmp目录下赋予执行权。这是一个Nmap运行实例。
Scanning all ports on 169.254.169.253
Starting Nmap 6.49BETA1 ( http://nmap.org ) at 2018-05-22 08:41 GMT
Cannot find nmap-payloads. UDP payloads are disabled.
Nmap scan report for 169.254.169.253

[1] [2] [3] [4]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载