GSP496

Visão geral
Este laboratório mostra alguns riscos de segurança de uma configuração padrão do cluster do GKE e as medidas de proteção necessárias para evitar escapes do pod e escalonamento de privilégios do cluster. Os caminhos de ataque são relevantes nos seguintes cenários:
- Uma falha do aplicativo em um pod externo que permite ataques de falsificação de solicitação do lado do servidor (SSRF)
- Um contêiner totalmente comprometido em um pod que permite a execução de comando remoto (RCE)
- Um usuário interno mal-intencionado ou um invasor com credenciais comprometidas que permitem criar/atualizar um pod em um determinado namespace
Este laboratório, criado por engenheiros do GKE Helmsman, explica como aumentar a segurança das configurações padrão do cluster do GKE.
*O código de exemplo deste laboratório é fornecido no estado em que se encontra, sem provisões ou garantias*
Objetivos
Após concluir o laboratório, você entenderá a necessidade de proteger os metadados da instância do GKE e definir políticas PodSecurityPolicy adequadas ao seu ambiente.
Você realizará as seguintes ações:
- Criar um pequeno cluster do GKE usando as configurações padrão
- Validar os caminhos mais comuns de escape do pod e o escalonamento de privilégios do cluster da perspectiva de um usuário interno mal-intencionado
- Aumentar a proteção do cluster do GKE para resolver esses problemas
- Validar o cluster para que essas ações não sejam mais permitidas
Configuração e requisitos
Antes de clicar no botão Começar o Laboratório
Leia estas instruções. Os laboratórios são cronometrados e não podem ser pausados. O timer é ativado quando você clica em Iniciar laboratório e mostra por quanto tempo os recursos do Google Cloud vão ficar disponíveis.
Este laboratório prático permite que você realize as atividades em um ambiente real de nuvem, e não em uma simulação ou demonstração. Você vai receber novas credenciais temporárias para fazer login e acessar o Google Cloud durante o laboratório.
Confira os requisitos para concluir o laboratório:
- Acesso a um navegador de Internet padrão (recomendamos o Chrome).
Observação: para executar este laboratório, use o modo de navegação anônima (recomendado) ou uma janela anônima do navegador. Isso evita conflitos entre sua conta pessoal e de estudante, o que poderia causar cobranças extras na sua conta pessoal.
- Tempo para concluir o laboratório: não se esqueça que, depois de começar, não será possível pausar o laboratório.
Observação: use apenas a conta de estudante neste laboratório. Se usar outra conta do Google Cloud, você poderá receber cobranças nela.
Como iniciar seu laboratório e fazer login no console do Google Cloud
-
Clique no botão Começar o laboratório. Se for preciso pagar por ele, uma caixa de diálogo vai aparecer para você selecionar a forma de pagamento.
No painel Detalhes do Laboratório, à esquerda, você vai encontrar o seguinte:
- O botão Abrir Console do Google Cloud
- O tempo restante
- As credenciais temporárias que você vai usar neste laboratório
- Outras informações, se forem necessárias
-
Se você estiver usando o navegador Chrome, clique em Abrir console do Google Cloud ou clique com o botão direito do mouse e selecione Abrir link em uma janela anônima.
O laboratório ativa os recursos e depois abre a página Fazer Login em outra guia.
Dica: coloque as guias em janelas separadas lado a lado.
Observação: se aparecer a caixa de diálogo Escolher uma conta, clique em Usar outra conta.
-
Se necessário, copie o Nome de usuário abaixo e cole na caixa de diálogo Fazer login.
{{{user_0.username | "Username"}}}
Você também encontra o nome de usuário no painel Detalhes do Laboratório.
-
Clique em Próxima.
-
Copie a Senha abaixo e cole na caixa de diálogo de Olá.
{{{user_0.password | "Password"}}}
Você também encontra a senha no painel Detalhes do Laboratório.
-
Clique em Próxima.
Importante: você precisa usar as credenciais fornecidas no laboratório, e não as da sua conta do Google Cloud.
Observação: se você usar sua própria conta do Google Cloud neste laboratório, é possível que receba cobranças adicionais.
-
Acesse as próximas páginas:
- Aceite os Termos e Condições.
- Não adicione opções de recuperação nem autenticação de dois fatores (porque essa é uma conta temporária).
- Não se inscreva em testes gratuitos.
Depois de alguns instantes, o console do Google Cloud será aberto nesta guia.
Observação: para acessar os produtos e serviços do Google Cloud, clique no Menu de navegação ou digite o nome do serviço ou produto no campo Pesquisar.
Ativar o Cloud Shell
O Cloud Shell é uma máquina virtual com várias ferramentas de desenvolvimento. Ele tem um diretório principal permanente de 5 GB e é executado no Google Cloud. O Cloud Shell oferece acesso de linha de comando aos recursos do Google Cloud.
-
Clique em Ativar o Cloud Shell
na parte de cima do console do Google Cloud.
-
Clique nas seguintes janelas:
- Continue na janela de informações do Cloud Shell.
- Autorize o Cloud Shell a usar suas credenciais para fazer chamadas de APIs do Google Cloud.
Depois de se conectar, você verá que sua conta já está autenticada e que o projeto está configurado com seu Project_ID, . A saída contém uma linha que declara o projeto PROJECT_ID para esta sessão:
Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}
A gcloud
é a ferramenta de linha de comando do Google Cloud. Ela vem pré-instalada no Cloud Shell e aceita preenchimento com tabulação.
- (Opcional) É possível listar o nome da conta ativa usando este comando:
gcloud auth list
- Clique em Autorizar.
Saída:
ACTIVE: *
ACCOUNT: {{{user_0.username | "ACCOUNT"}}}
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- (Opcional) É possível listar o ID do projeto usando este comando:
gcloud config list project
Saída:
[core]
project = {{{project_0.project_id | "PROJECT_ID"}}}
Observação: consulte a documentação completa da gcloud
no Google Cloud no guia de visão geral da gcloud CLI.
Tarefa 1: criar um cluster simples do GKE
- Defina uma zona em uma variável de ambiente chamada MY_ZONE. Este laboratório usa "". Você pode selecionar uma zona se preferir:
export MY_ZONE={{{project_0.default_zone|ZONE}}}
- Execute este comando para iniciar o cluster do Kubernetes
simplecluster
que é gerenciado pelo Kubernetes Engine. Depois configure-o para processar 2 nós:
gcloud container clusters create simplecluster --zone $MY_ZONE --num-nodes 2 --metadata=disable-legacy-endpoints=false
A criação de um cluster leva alguns minutos porque o Kubernetes Engine provisiona as máquinas virtuais. Neste laboratório, os avisos sobre os recursos disponíveis nas novas versões podem ser ignorados.
- Após a criação do cluster, verifique a versão instalada do Kubernetes com o comando
kubectl version
:
kubectl version
O comando gcloud container clusters create
autentica automaticamente a kubectl
.
- Confira os nós em execução no console do GCP. No Menu de navegação, clique em Compute Engine > Instâncias de VM.
O cluster do Kubernetes está pronto para ser usado.
Clique em Verificar meu progresso para conferir o objetivo. Crie um cluster simples do GKE.
Tarefa 2: executar um pod do SDK do Google Cloud
- No prompt do Cloud Shell, inicie uma única instância do contêiner do SDK do Google Cloud:
kubectl run -it --rm gcloud --image=google/cloud-sdk:latest --restart=Never -- bash
Esse processo leva alguns minutos.
Observação: se você receber um erro de expiração, execute o comando de novo.
- No contêiner do pod, agora há um shell bash:
root@gcloud:/#
Pode levar alguns segundos para o contêiner iniciar e o prompt de comando aparecer. Caso o prompt de comando não seja exibido, pressione Enter.
Confira o endpoint do Compute Metadata
- Execute o comando a seguir para acessar o endpoint
v1
do Compute Metadata:
curl -s http://metadata.google.internal/computeMetadata/v1/instance/name
A resposta será semelhante a esta:
...snip...
Your client does not have permission to get URL /computeMetadata/v1/instance/name
from this server. Missing Metadata-Flavor:Google header.
...snip...
Perceba que um erro aparece e informa que um cabeçalho HTTP personalizado está faltando.
- Adicione o cabeçalho personalizado na próxima execução e recupere o nome da instância do Compute Engine que executa o pod:
curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/name
A resposta será semelhante a esta:
gke-simplecluster-default-pool-b57a043a-6z5v
Observação: se um cabeçalho HTTP personalizado não for necessário para acessar um endpoint de metadados da instância do Compute Engine, um invasor poderia precisar apenas de uma falha no aplicativo para burlar um URL da Web e fornecer as credenciais do usuário. Ao exigir um cabeçalho HTTP personalizado, um ataque será mais difícil, porque o invasor precisaria de uma falha no aplicativo e de um cabeçalho personalizado.
Mantenha o shell no pod disponível para a próxima etapa.
- Caso você saia acidentalmente do pod, execute novamente o seguinte comando:
kubectl run -it --rm gcloud --image=google/cloud-sdk:latest --restart=Never -- bash
Analise as credenciais de bootstrapping do nó do GKE
- No mesmo shell do pod, execute o comando a seguir para listar os atributos associados às instâncias subjacentes do GCE. Lembre-se de incluir a barra final:
curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/attributes/
Talvez o dado mais confidencial da listagem seja kube-env
. Ele contém diversas variáveis usadas pelo kubelet
como credenciais iniciais ao anexar o nó ao cluster do GKE. As variáveis CA_CERT
, KUBELET_CERT
e KUBELET_KEY
contêm essas informações e são consideradas confidenciais a administradores fora do cluster.
- Para conferir as variáveis e os dados possivelmente confidenciais, execute o seguinte comando:
curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env
Considere as situações abaixo:
- Uma falha que permita SSRF em um aplicativo de pod
- Uma falha do aplicativo ou biblioteca que permita RCE em um pod
- Um usuário interno com permissão para criar ou executar no pod
Nesses casos, há uma grande probabilidade de comprometimento e exfiltração das credenciais confidenciais de bootstrapping do kubelet
pelo endpoint do Compute Metadata. É possível usar as credenciais do kubelet
em algumas situações e escalonar os privilégios para cluster-admin
. Isso permite controle total do cluster do GKE, inclusive dos dados, aplicativos e acessos aos nós subjacentes.
Use as permissões atribuídas à conta de serviço do pool do nó
Por padrão, os projetos do Google Cloud com a API Compute ativada têm uma conta de serviço no formato NNNNNNNNNN-compute@developer.gserviceaccount.com
no projeto e o papel Editor
anexado a ela. Os clusters do GKE criados sem a especificação de uma conta de serviço usam a conta de serviço padrão do Compute e a anexam a todos os nós de trabalho.
- Execute o seguinte comando
curl
para listar os escopos do OAuth associados à conta de serviço anexada à instância subjacente do Compute Engine:
curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes
(saída) https://www.googleapis.com/auth/devstorage.read_only https://www.googleapis.com/auth/logging.write https://www.googleapis.com/auth/monitoring https://www.googleapis.com/auth/service.management.readonly https://www.googleapis.com/auth/servicecontrol https://www.googleapis.com/auth/trace.append
A combinação dos escopos de autenticação e as permissões da conta de serviço determinam quais aplicativos podem ser acessados nesse nó. A lista acima mostra os escopos mínimos necessários para a maioria dos clusters do GKE, mas alguns casos de uso exigem escopos maiores.
Aviso: se, durante a criação do cluster, você configurou o escopo da autenticação para incluir "https://www.googleapis.com/auth/cloud-platform", qualquer API Google Cloud estaria no escopo, e apenas as permissões do IAM atribuídas à conta de serviço determinariam o acesso.
Além disso, se a conta de serviço padrão com o papel Editor
do IAM estiver em uso, qualquer pod nesse pool de nós teria permissões de Editor
no projeto do Google Cloud em que o cluster do GKE estiver implantado. O papel Editor
do IAM tem várias permissões de leitura/gravação para interagir com os recursos do projeto, como instâncias do Compute, buckets do Cloud Storage, registros do GCR, entre outros, o que provavelmente não é o desejado
- Para sair do pod, digite:
exit
Observação: se não voltar ao Cloud Shell, pressione ctrl+c
Tarefa 3: implantar um pod que monte o sistema de arquivos do host
Um dos caminhos mais simples de aplicar o escape ao host subjacente é montando o sistema de arquivos do host no do pod com volumes
e volumeMounts
padrão do Kubernetes em uma especificação Pod
.
- Isso pode ser demonstrado executando o seguinte comando para criar um pod que monte o sistema de arquivos
/
subjacente do host em uma pasta chamada /rootfs
no contêiner:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: hostpath
spec:
containers:
- name: hostpath
image: google/cloud-sdk:latest
command: ["/bin/bash"]
args: ["-c", "tail -f /dev/null"]
volumeMounts:
- mountPath: /rootfs
name: rootfs
volumes:
- name: rootfs
hostPath:
path: /
EOF
- Execute
kubectl get pod
e faça isso novamente até que ele atinja o estado "Running":
kubectl get pod
(Saída)
NAME READY STATUS RESTARTS AGE
hostpath 1/1 Running 0 30s
Clique em Verificar meu progresso para conferir o objetivo. Implantar um pod que monte o sistema de arquivos do host
Tarefa 4: analisar e comprometer o host subjacente
- Execute o seguinte comando para incluir um shell no pod recém-criado:
kubectl exec -it hostpath -- bash
- Mude o ponto do sistema de arquivos raiz do shell do pod para o do host subjacente:
chroot /rootfs /bin/bash
Com esses comandos simples, o pod agora é um shell root
no nó. Faça o seguinte:
Execute o comando padrão do Docker com permissão total
|
docker ps
|
Liste as imagens do Docker
|
docker images
|
Use docker run em um contêiner privilegiado que preferir
|
docker run --privileged <imagename>:<imageversion>
|
Analise os secrets ativos do Kubernetes
|
mount | grep volumes | awk '{print $3}' | xargs ls
|
Use exec em qualquer contêiner em execução (mesmo em outro pod e namespace).
|
docker exec -it <docker container ID> sh
|
Quase todas as operações que podem ser feitas pelo usuário root
estão disponíveis nesse shell do pod. Isso inclui mecanismos de persistência, como adição de usuários/chaves SSH, execução de contêineres privilegiados do Docker no host fora da visualização do Kubernetes, entre outras funções.
- Execute
exit
duas vezes: uma para deixar o chroot
e outra para sair do shell do pod:
exit
exit
Observação: se não voltar ao Cloud Shell, pressione ctrl+c
- Agora exclua o pod
hostpath
:
kubectl delete pod hostpath
Entenda os controles disponíveis
As próximas etapas vão demonstrar os seguintes tópicos:
-
Como desativar o endpoint legado da API de metadados do Compute Engine: ao especificar uma chave e um valor de metadados personalizados, o endpoint
v1beta1
não ficará mais disponível na instância.
-
Ativar a ocultação de metadados: ao passar uma configuração adicional durante a criação do cluster e/ou do pool de nós, um proxy leve será instalado em cada nó para todas as solicitações da API de metadados e impedirá o acesso a endpoints confidenciais.
-
Ativar e usar a admissão de segurança de pods: ative o controlador de admissão de segurança de pods (PSA, na sigla em inglês) no cluster do GKE. Isso permite aplicar padrões de segurança de pods que melhoram a postura de segurança do cluster.
Tarefa 5: implantar um segundo pool de nós
Para que você tenha experiências com e sem a proteção do endpoint de metadados, será criado um segundo pool de nós que incluirá duas configurações adicionais. Os pods programados para o pool de nós genérico não terão proteção. Já os programados para o segundo pool de nós contarão com essa segurança.
Observação: endpoints legados foram suspensos em 30 de setembro de 2020. Nas versões 1.12 e mais recentes do GKE, a configuração "--metadata=disable-legacy-endpoints=true" será ativada automaticamente. O comando a seguir define isso.
- Crie o segundo pool de nós:
gcloud beta container node-pools create second-pool --cluster=simplecluster --zone=$MY_ZONE --num-nodes=1 --metadata=disable-legacy-endpoints=true --workload-metadata-from-node=SECURE
Clique em Verificar meu progresso para conferir o objetivo. Implantar um segundo pool de nós
Tarefa 6: executar um pod do SDK do Google Cloud
- No Cloud Shell, inicie uma única instância do contêiner do SDK do Google Cloud. Ela será executada apenas no segundo pool de nós com as proteções ativadas, sem operar como o usuário raiz:
kubectl run -it --rm gcloud --image=google/cloud-sdk:latest --restart=Never --overrides='{ "apiVersion": "v1", "spec": { "securityContext": { "runAsUser": 65534, "fsGroup": 65534 }, "nodeSelector": { "cloud.google.com/gke-nodepool": "second-pool" } } }' -- bash
Observação: se você receber um erro de expiração, execute o comando de novo.
- Haverá um shell bash em execução no contêiner do pod no pool de nós
second-pool
. Isto vai aparecer:
nobody@gcloud:/$
Pode levar alguns segundos para o contêiner iniciar e o prompt de comando abrir.
Se um prompt de comando não for exibido, pressione Enter.
Analise vários endpoints bloqueados
- Com a configuração do segundo pool de nós definida como
--workload-metadata-from-node=SECURE
, o comando abaixo para recuperar o arquivo confidencial, kube-env
, apresentará falha:
curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env
(Saída)
This metadata endpoint is concealed.
- No entanto, outros comandos a endpoints não confidenciais ainda terão sucesso se o cabeçalho HTTP adequado tiver passado:
curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/name
Exemplo de saída
gke-simplecluster-second-pool-8fbd68c5-gzzp
- Saia do pod:
exit
Você voltará ao Cloud Shell.
Tarefa 7: aplicar os padrões de segurança dos pods
- Para avançar, conceda permissões explícitas para transformar sua conta de usuário em
cluster-admin:
kubectl create clusterrolebinding clusteradmin --clusterrole=cluster-admin --user="$(gcloud config list account --format 'value(core.account)')"
(Saída)
clusterrolebinding.rbac.authorization.k8s.io/clusteradmin created
- Agora você vai aplicar um padrão de segurança de pod. Escolha o padrão mais adequado para o namespace "default". O perfil "restricted" oferece mais segurança:
kubectl label namespace default pod-security.kubernetes.io/enforce=restricted
- Em seguida, você vai criar um ClusterRole. Se quiser controlar quem pode modificar os níveis de admissão de segurança do pod nos namespaces, crie um ClusterRole chamado
pod-security-manager
:
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-security-manager
rules:
- apiGroups: ['policy']
resources: ['podsecuritypolicies']
resourceNames: ['privileged', 'baseline', 'restricted']
verbs: ['use']
- apiGroups: ['']
resources: ['namespaces']
verbs: ['get', 'list', 'watch', 'label']
EOF
- Em seguida, você vai criar um RoleBinding. Para restringir quem pode mudar os rótulos de namespace relacionados à admissão de segurança do pod, crie um RoleBinding no namespace "default":
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-security-modifier
namespace: default
subjects:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:authenticated
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: pod-security-manager
EOF
Observação: para aplicação de segurança de pods dinâmica e altamente personalizada, considere usar ferramentas como OPA Gatekeeper ou Kyverno.
Clique em Verificar meu progresso para conferir o objetivo. Implantar objetos PodSecurityPolicy
Tarefa 8: implantar um pod bloqueado que ative o sistema de arquivos do host
Como a conta usada para implantar o cluster do GKE recebeu permissões cluster-admin em uma etapa anterior, é necessário criar uma conta de "usuário" separada para interagir com o cluster e validar a aplicação do PodSecurityPolicy.
- Para fazer isso, execute:
gcloud iam service-accounts create demo-developer
(Saída)
Created service account [demo-developer].
- Agora execute os comandos abaixo para conceder à conta de serviço permissão para interagir com o cluster e tentar criar pods:
MYPROJECT=$(gcloud config list --format 'value(core.project)')
gcloud projects add-iam-policy-binding "${MYPROJECT}" --role=roles/container.developer --member="serviceAccount:demo-developer@${MYPROJECT}.iam.gserviceaccount.com"
- Para ter acesso ao arquivo das credenciais da conta de serviço, execute este código:
gcloud iam service-accounts keys create key.json --iam-account "demo-developer@${MYPROJECT}.iam.gserviceaccount.com"
- Configure
kubectl
para autenticar como esta conta de serviço:
gcloud auth activate-service-account --key-file=key.json
- Execute o código abaixo para configurar
kubectl
a usar as credenciais ao se comunicar com o cluster:
gcloud container clusters get-credentials simplecluster --zone $MY_ZONE
- Agora tente criar outro pod que ative o sistema de arquivos
/
do host subjacente em uma pasta chamada /rootfs
no contêiner:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: hostpath
spec:
containers:
- name: hostpath
image: google/cloud-sdk:latest
command: ["/bin/bash"]
args: ["-c", "tail -f /dev/null"]
volumeMounts:
- mountPath: /rootfs
name: rootfs
volumes:
- name: rootfs
hostPath:
path: /
EOF
- Esta resposta valida o bloqueio pelo padrão de segurança do pod:
Error from server (Forbidden): error when creating "STDIN": pods "hostpath" is forbidden: violates PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "hostpath" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "hostpath" must set securityContext.capabilities.drop=["ALL"]), restricted volume types (volume "rootfs" uses restricted volume type "hostPath"), runAsNonRoot != true (pod or container "hostpath" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "hostpath" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
- Implante outro pod que atenda aos critérios do
restrictive-psp
:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: hostpath
spec:
securityContext:
runAsNonRoot: true # Garantir que o usuário não é raiz
runAsUser: 1000
fsGroup: 2000
seccompProfile: # Adicionar um perfil seccomp
type: RuntimeDefault
containers:
- name: hostpath
image: google/cloud-sdk:latest
command: ["/bin/bash"]
args: ["-c", "tail -f /dev/null"]
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
EOF
(Saída)
pod/hostpath created
Clique em Verificar meu progresso para conferir o objetivo. Implantar um pod bloqueado que ative o sistema de arquivos do host
Parabéns!
Neste laboratório, você configurou um cluster padrão do Kubernetes no Google Kubernetes Engine. Em seguida, você sondou e analisou o acesso disponível ao pod, aumentou a proteção do cluster e confirmou que ações nocivas não são mais possíveis.
Próximas etapas / Saiba mais
Treinamento e certificação do Google Cloud
Esses treinamentos ajudam você a aproveitar as tecnologias do Google Cloud ao máximo. Nossas aulas incluem habilidades técnicas e práticas recomendadas para ajudar você a alcançar rapidamente o nível esperado e continuar sua jornada de aprendizado. Oferecemos treinamentos que vão do nível básico ao avançado, com opções de aulas virtuais, sob demanda e por meio de transmissões ao vivo para que você possa encaixá-las na correria do seu dia a dia. As certificações validam sua experiência e comprovam suas habilidades com as tecnologias do Google Cloud.
Manual atualizado em 14 de fevereiro de 2024
Laboratório testado em 14 de fevereiro de 2024
Copyright 2025 Google LLC. Todos os direitos reservados. Google e o logotipo do Google são marcas registradas da Google LLC. Todos os outros nomes de produtos e empresas podem ser marcas registradas das respectivas empresas a que estão associados.