06-Session Security
06-Session Security
Once you are connected in VPN to the lab environment, all the web applications will be
available at the following URL: http://info.session.site/.
There are three main sections for each type of lab: Video, Lab, Challenges.
• Video section contains web applications used during video lessons. Therefore, if
you need any information about the scenario, the attacks and so on, please refer to
the corresponding video.
• Labs section contains web application where you can practice the techniques of the
specific module and have solutions. You can find them later in this manual
• Challenges labs do not have solutions; otherwise, why call them challenges? If you
study the course and think like a penetration tester, you will achieve the goal!
The best tool is, as usual, your brain. Then you may need of:
• Web Browser
• Burp Suite
Once you have your virtual network ready, configure the following IP address as default
DNS: 10.100.13.37
• WINDOWS: change the property of the TAP network device, adding as first DNS
server of the IP of the server.
• LINUX: add an entry into /etc/resolv.conf file with the IP address of the server
This web application suffers from bad session management. The session identifier is stored
in a cookie and is represented by a numeric value. It is created and incremented (from the
last assigned sessionID) each time a customer logs into the system. By exploiting this
weakness, an attacker can guess a valid session identifier assigned to another logged-in
user and impersonate his session.
Arrogant Bank includes an important feature: a feedback area where users can leave
comments and suggestions about services offered by the online bank.
The web application is affected by a persistent XSS. Sessions are implemented through
cookies and cookies do not have the HTTPOnly flag set.
To install a persistent XSS on the feedback page that will steal the Session cookie.
The web application suffers from Session fixation vulnerability. SessionID is embedded in
URL and can be “fixated” by an attacker and used to impersonate the victim.
Customers can access their private area providing valid credentials. The private area
allows them to use the e-Transfer feature to send money directly to other customers with a
checking account in the same bank.
The web application suffers from CSRF vulnerability. An attacker can induce a logged user
to perform a money transfer simply letting the victim visit a malicious page. This page is
under attacker’s control, and it is hosted on a third domain (so different from the bank
domain).
Moreover, they can check their balance and through the e-Transfer feature send money
directly to other customers with a checking account in the same bank.
Web application stores information about the checking accounts by using JavaScript. This
vulnerability could permit an attacker to create a malicious page stealing information
about the customer visiting it.
The web application suffers from bad session management. The session identifier is stored
in a cookie, and it is generated by using a fixed component and a random one. Simply by
analyzing deeper how the sessionIDs are generated, an attacker can guess which sessionID
is used by the victim and impersonate his session account.
You have to exploit a CSRF vulnerability present in the web application. You are required to
build an exploit so that a new blog post, authored by “Admin,” will appear on the blogs page
as soon as the Admin visits the blogs page (so just admin’s visit to a page will trigger the
exploit and make an embarrassing blog post appear).
You do not know Admin’s credentials, and you do not have to find it.
A CSRF payload can be triggered by having the victim surreptitiously issue an HTTP
request that performs some action on his behalf “riding” his authenticated session.
As soon as you have built your payload, you can simulate an authenticated visit of the
Admin to the blogs page by clicking the link that you find on the top right of the Blogs page.
• If you manage to have the Admin post a message, you will find the secret
within the blog post.
The web application is vulnerable to “unrestricted file upload,” and your goal is to catch
some information about your competitor: William Lete!
We know that Mr. Lete has a problem with a server. He has just opened a ticket asking for
support. We also know that he has sent the server address and the RDP credentials!
Oh, one more thing. Mr. Lete has forgotten to logout, and so his session is still alive.
• You have to find the RDP password and the session identifier related to his
session (the content of the cookie PHPSESSID)
Open the attacker’s browser (e.g., Mozilla) and go to the main page of the web application.
Login using the following credentials:
• Username: mike
• Password: ABC7d8z1
Through Burp proxy, you will notice that after a successful login, a cookie has been
installed on the attacker’s browser. The cookie has the following data:
• Name: SESSID
• Value: 0000001
Cookie SESSID, as the name suggests, is used by the web application to manage the session
mechanism. Through this id, the web server binds HTTP requests coming back from Mike’s
browser to his account data stored on the web server and will not ask for credentials again
(the web server retains that status through different pages).
You probably noticed that the value of sessionID is represented by the string 0000001, so
its numerical value is 1. Keep this value in mind.
The image above shows an HTTP request sent by the browser to request the myaccount
page. The Cookie header used by the session mechanism allows the web server to
recognize the logged-in user.
The attacker’s goal is to determine any correlation between two session identifiers
provided by the web application. We can get another sessionID and compare them both.
The simplest way to obtain a new sessionID is to login again. Use the same credentials:
• Username: mike
• Password: ABC7d8z1
Through Burp proxy, you will notice that after the second login the following cookie is
installed on the browser:
• Name: SESSID
• Value: 0000002
It seems that sessionID’s are just increased each time a user performs a successful. This is a
seriously vulnerable way to manage sessions and allows an attacker to easily guess the
sessionID’s of other logged-in users.
We can conclude that the session identifier provided by the web application is predictable
and that the web application suffers from the predictable session identifier vulnerability.
Open a second browser (for example, Google Chrome) and login with the following
credentials:
• Username: jason
• Password: 8AqL168a
As the attacker, now you should guess a valid session identifier used by another logged-in
user. You know that the last identifiers assigned were 0000001 and 0000002.
This will be someone who has logged-in to the web application after you.
You can use Burp proxy to intercept your attacking requests and change the value of the
sessionID before the requests are sent to the server.
When Burp alerts you about a new intercepted request, update the cookie with the value
0000003 and forward the request.
When we issue this request, we are impersonating another user account. The new
sessionID you used was actually assigned by the web application to another user: Jason.
Please note that Burp uses the term “token” to refer, in a more generic manner, to all ID’s
generated by a web application that are supposed to be random or unpredictable.
The request must be one that will, in the response, set the session cookie.
Now we will work on the HTTP response that will set our session cookie. We will do a
manual selection, highlighting the sessionID within the Set-Cookie header in the
response. The sequencer will immediately identify a pattern to extract the sessionID.
Click on Analyze when you are done. This will be the result:
Please note that for more reliable statistical analysis, you will have to collect many more
than 135 tokens (around 1000 begins to be acceptable).
Open the browser (for example Mozilla) and go to the main page of the web application.
Login with the following credentials:
• Username: mike
• Password: ABC7d8z1
The web form in the feedback area suffers from a persistent XSS in the message parameter.
The attacker can exploit this vulnerability to steal visitors session cookies.
You have multiple ways to do so. For example, you can have a server listening for cookies.
In this case, we will see a very simple way to accomplish the task. The following code will
steal the session cookie of any visitor and will insert it in a hidden block of the feedback
page permanently. This way, you can come back to the page later and see sessionID’s in the
web page source code.
Note that cookie stealing is possible only because it can be accessed by JavaScript
(HttpOnly flag is not set).
The XSS payload is embedded within the message of the feedback. This is a proposed
payload:
• Username: jason
• Password: 8AqL168a
Head to the Feedback page. This page contains the malicious code. Can you see it? If all
went well in Task 2, you should NOT notice anything suspicious.
This kind of exploitation is a variation of what you find everywhere on the internet, a small
web server that receives the cookie sent by the JavaScript Payload.
Feel free to create your own JavaScript payload to retrieve the session cookie without
leaving traces on the web page source code.
• SESSID = <randomToken>
As you can see, SessionID is embedded in the URL, and it has been assigned by a web server
regardless of the unauthenticated status of the visitor.
• User: mike
• Password: ABC7d8z1
After login, SessionID is not updated, so our web application is vulnerable to Session
Fixation attacks.
What we need to do is to force the victim to login to the vulnerable website using a URL
that contains an arbitrary sessionID.
SESSID=ovCx25cVNDS0fSCrWyAr
To mimic the victim, open a second browser (for example Google Chrome), use the link
forged at the previous step and log in with the following credentials:
• Username: jason
• Password: 8AqL168a
The victim (you in this case) has successfully logged in using a SessionID that had been
selected by the attacker!
Now, the session is owned by the victim, and its ID is known by the attacker. Please note
that the victim will NOT notice anything suspicious because log-in operation went through
just fine.
You do not know Jason’s credentials but thanks to the Session Fixation vulnerability, you
have successfully exploited his session.
Open the attacker browser (for example Mozilla) and go to the Arrogant Bank home page.
Login with the following credentials:
• Username: mike
• Password: ABC7d8z1
You will notice that ArrogantBank is offering a new service: e-Transfer. With this feature, a
logged user will be able to send money to another customer of the same bank.
Let us examine how the service works. To do this, we will enable Burp proxy to intercept
all the HTTP requests leaving the browser. After that, we will start a test money transfer,
and we will observe which parameters are sent by the browser with the requests.
Please note that money transfer is performed using an HTTP request and that the following
parameters are embedded in the URL
There is no unpredictable token sent with the request so you can conclude that web
application is vulnerable to CSRF in the script startCreditTransfer.php.
• accountNumber : 99999999992
• swiftCode : B4F15S6S
• amount : <wanted Money>
According to the web application logic, the payload will be embedded in the following URL:
http://<webSite>/startCreditTransfer.php?amount=100&accountNumbe
r=99999999992&swift=B4F15S6S
By simply loading that URL, an authenticated victim will send money to the attacker.
There are many ways to let a logged user load a URL. The most trivial is to send a link to the
victim in hope that he will click on it.
In this case, the victim could become suspicious, as he would see the webpage of
ArrogantBank with the result of the money transfer.
Another, better and stealthier, way to achieve the same goal is to embed the CSRF payload
URL in the SRC attribute of an Image within an HTML page. Same-origin does not apply; we
are just requesting an external resource without having to read the response.
The Image tag can be embedded in any page that the victim trusts (Facebook, Third party
Forums, Your website)
• CSRF payload with the suspicious request won’t appear in the link that we send
to the victim
• The victim doesn’t see the output of the request
• Higher chances that the victim will visit the page with the Image than a link that
includes long and suspicious content
Therefore, the attacker can use a personal website under his control on a different domain
to host the following malicious code:
For educational purposes, we have already created a feedback message from an attacker.
This message has a link to a page that embeds the above image. When you visit the
feedback page you should see it:
Link to the
malicious page
The My site input field of the form was used to include the link.
• Username: jason
• Password: 8AqL168a
Note that you should have $2599 in your account. Whatever the amount is, please note it
down.
Now move to the feedback area. Please click on the link to the malicious page.
When you do, you will land to the attacker’s web page that embeds the malicious hidden
image. You can verify so by inspecting the web page source code:
Now visit your Myaccount page again and verify your total money.
It should be $100 less than before. Where did those dollars go?
Note that if web application had had an anti-CSRF token, the attacker could not have built
the URL payload without guessing that token. Any unpredictable token would have made
the application safe from CSRF.
Open the attacker browser (for example Mozilla) and go to the Arrogant Bank home page.
Login with the following credentials:
• Username: mike
• Password: ABC7d8z1
Enable Burp proxy to intercept all the HTTP responses coming to the browser.
You can see that checking account information is stored in JavaScript variables, provided
by the URL balance.php. This resource acts as a JavaScript library file so that it can be
imported by any web page regardless of its domain origin.
Note that the JavaScript variables can be loaded only if a logged user loads the malicious
page. Unauthenticated users will get an empty file.
Open a second browser (for example Google Chrome), and login with the following
credentials:
• Username: jason
• Password: 8AqL168a
The browser will load the JavaScript variables related to the logged session and will steal
checking account information:
For education purposes, the malicious page will show you all the stolen information. In a
real-world attack, this information is secretly retrieved and collected by the attacker.
Open the attacker browser (for example Mozilla) and go to the main page of the web
application. Login with the following credentials:
• Username: mike
• Password: ABC7d8z1
Different from the previous battle, this sessionID does not seem to be a numerical value.
Let us analyze the goodness of the session IDs assigned by the web application using a tool
like Burp Sequencer. Our goal is analyzing possible correlations of sessionIDs.
Please note that Burp uses the term “token” to refer, in a more generic manner, to all those
ID’s generated by a web application that are supposed to be random or unpredictable.
Now we will work on the HTTP response that will set our session cookie. We will do a
manual selection, highlighting the sessionID within the Set-Cookie header in the
response. Sequencer will immediately identify a pattern to extract the sessionID.
At this point, we can click on Start capture (screen above) to perform a number of logins
and to obtain a corresponding number of session ID’s to be analyzed. A minimum of 100
tokens is necessary to perform an analysis.
Of course, the randomness of the session ID’s is recognized to be extremely poor, and
there’s really no entropy.
Please note that for more reliable statistical analysis you will have to collect much more
than 135 tokens (around 1000 begins to be acceptable).
The chart shows that chars at the second and third position are generated in a random
manner, differently from the others assuming always the same values.
Coming back to our sessionID (that received at first login) we have highlighted in green the
random portion of the sessionID.
0116d696b65
We can conclude that sessionIDs include a fixed component (9 chars) and a random
component (2 chars).
However, the fixed component could depend from the current user logged or from some
other field (hidden to us). Therefore, we are not sure that it is the same for all the users.
Before bruteforcing the web application let us inspect deeper the ending fixed component,
in our case 6d696b65.
0<XX><hex(loggedUsername)>
So, fixed a username, only two chars are effectively generated in a random manner.
However, if the attacker does not know the username of the logged victim, the previous
statement is wrong!
This is a classic example where the human interaction is fundamental to the pentesting
process.
We can conclude that the guessing attack can be run easily if the attacker knows the victim
username because he will have to bruteforce only two components of the sessionID.
Differently, the attack could be very hard because he will have to bruteforce 2 + N
components of the sessionID, where N is the length of the victim username, and it is not
known.
Open a second browser (for example Google Chrome) and login with the following
credentials:
• Username: jason
• Password: 8AqL168a
0XY6a61736f6e
Now we must bruteforce only the green portion of the previous wildcard.
We can use Burp Intruder to start this attack. We will use the myaccount.php page as target
because the HTTP response from this page returns the status code 200 if the request has
been authenticated (so with a right sessionID) and the status code 302 otherwise.
Burp intruder will perform HTTP requests to the myaccount.php page specifying a
different sessionID to each attempt.
1 – Selecting the element you want to bruteforce enclosing it within two chars §.
When all the HTTP requests have been performed, analyze the responses. All the responses
will have a status code 302 except the authenticated request.
You can also add grep-match options for the username, since the application shows (in
myaccount.php) the username of the user logged, or use the Filter options
Therefore, you will analyze only the HTTP request returning a 200 status code. You will see
that the guessed sessionID is 0236a61736f6e.