Session Injection
Session Injection
Session Injection
Table of Content
Table of Content 2
Introduction 4
About this exercise 5
License 5
Syntax of this course 6
The web application 6
The Play Framework 8
Fingerprinting 8
Play session 10
White Box approach 11
Black Box approach 15
Session Injection 17
Details 17
Exploitation 18
Login with admin privileges 18
Login as another user 19
Conclusion 21
2/21
PentesterLab.com » Play Session Injection
3/21
PentesterLab.com » Play Session Injection
Introduction
This course details the exploitation of a session injection in the Play
framework. This issue can be used to inject arbitrary content inside the
session and therefore modify the application logic to escalate privileges.
4/21
PentesterLab.com » Play Session Injection
License
This exercise by PentesterLab is licensed under the Creative Commons
Attribution-NonCommercial-NoDerivs 3.0 Unported License. To view a copy of
this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/.
5/21
PentesterLab.com » Play Session Injection
The green boxes provide tips and information if you want to go further.
The blue boxes are "homework": things you can work on once you are done
with this exercise:
6/21
PentesterLab.com » Play Session Injection
Throughout the training, the hostname vulnerable is used for the vulnerable
machine, you can either replace it by the IP address of the machine, or you
can just add an entry to your host file with this name and the corresponding
IP address. It can be easily done by modifying:
7/21
PentesterLab.com » Play Session Injection
Fingerprinting
Here the Play application is deployed on the port 80 and running as root (to
be able to bind on the port 80). We can observe that Play is used by
looking at the Server header:
8/21
PentesterLab.com » Play Session Injection
PLAY_SESSION=dc76c24ea96cdf0009188367583f07bee1126aff-
%00___AT%3A103939fbeba60071e96c5dd505a7916d8b49c9c9%00%00user%3Atest%00
9/21
PentesterLab.com » Play Session Injection
Play session
The session mechanism used by Play is really similar to Rack sessions (used
by Ruby-on-Rails by default). The content of the session is sent back to the
clients instead of being stored server side. To prevent an attacker from
tampering his session. A signature of the session is calculated. We will now
dive into this mechanism by reviewing the code involved in this bug.
10/21
PentesterLab.com » Play Session Injection
We will now see how the sessions mechanism worked before the vulnerability
was reported.
11/21
PentesterLab.com » Play Session Injection
First, the code retrieve the cookie used for the session, for example
PLAY_SESSION. If the cookie is present it will then split it into 2 parts:
It will then verify the signature using the method Crypto.sign and the secret
key Play.secretKey.
12/21
PentesterLab.com » Play Session Injection
We can see that the session's signature is based on HMAC (the code is
available in Crypto.java
https://github.com/playframework/play1/blob/1.2.5/framework/src/play/libs/Crypto.java)
as we can see in the code below:
try {
Mac mac = Mac.getInstance("HmacSHA1");
We can also see that the code in Scope.java used a non time-constant string
comparison:
if (sign.equals(Crypto.sign(data, Play.secretKey.getBytes()))) {
13/21
PentesterLab.com » Play Session Injection
Once the signature is verified, Play parses the session's data using the
following mechanism:
If you have already look in the sessions parsing of few web frameworks, you
quickly realise that this mechanism is fairly different to a lot of frameworks.
Most framework will rely on known formats (like YAML, JSON, object
serialisation) to store session's information. Here the data is only splitted
using a regular expression and a loop.
14/21
PentesterLab.com » Play Session Injection
Let's now see how information is added to the server side session:
We can see here that we can't use a key that contains a :. However nothing
prevent a value from containing a NULL Byte. If an attacker is able to inject
NULL Bytes in a value (for example in his/her username), he/she can
potentially inject additional variables inside the session (without knowing the
secret key used for the signature).
15/21
PentesterLab.com » Play Session Injection
If you have control over data1 and/or data2, you need to try to inject the
various delimiters and keywords to see if you can trigger unexpected
behavior.
16/21
PentesterLab.com » Play Session Injection
Session Injection
Details
As we just saw, the data in the session follow this pattern:
17/21
PentesterLab.com » Play Session Injection
Our goal now will be to inject NULL BYTEs (%00) and separator (%3a) to add
arbitrary keys and values within the session. The session will stay valid since
this injection is performed by the server before it signs the data. And the
modified session will only trigger unexpected behavior when it gets sent back
to the server.
Exploitation
Since you will probably have to try multiple times before finding the right
value, it's probably worth writing a small script to automate the process:
Register a user.
Access the website logged as this user.
Here, you get logged in as soon as you register to keep things easy. You
could also use QA tools for browser automation (like Selenium) if the
registration process had multiple complex steps.
18/21
PentesterLab.com » Play Session Injection
Our goal is to inject a variable admin equals to 1 inside the session. Based
on what we saw before, we know that we will need to use: %00admin%3a1%00.
We will also need to properly finish the declaration of the current variable
(namely user).
The last NULL BYTE comes from the server code so you don't need to end
your payload with a NULL byte. By using the payload above, you should be
able to create a user with admin privileges.
19/21
PentesterLab.com » Play Session Injection
In this part, we will try to login as another user: admin1. If you remember the
method used to parse the session, you see that the latest variable in the
session will always overwrite any previous declaration (due to the usage of an
HashMap):
[...]
public void put(String key, String value) {
[...]
data.put(key, value);
[...]
We are therefore able to inject another key user that will overwrite the one
from the application. The following table shows what result you want to
achieve:
20/21
PentesterLab.com » Play Session Injection
Conclusion
This exercise explained how to exploit a session injection in the Play
framework. This bug is pretty interesting since we use the server to create a
forged session and we then use it to gain access to administrator privileges
or to log in as another user. Once again, re-inventing the wheel can be
dangerous, and you should probably rely on known formats if you want to
store information. I hope you enjoyed learning with PentesterLab.
21/21