In this article we take a closer look at a flaring script for report-uri., one that we will use to confuse and distract the blue team by sending random false positives. There is no question that CSP and report-uri are a strong pair that helps the blue team to detect your intrusion.  But what if this could help us in some way? While you may trigger a WAF to report some false positives, with report-uri it's even easier.

You can send your own “alerts” and  determine when and what to be reported.

Recently in a red team exercise I was involved with we had an externally available employee portal, it was kind of self-written and we assumed it was built around a template engine. We also had a few other external sites, perfect material for XSS and many of these deployed a solid CSP. Even when they are not that sophisticated they make your life on the red team harder, so lets turn them to our advantage.

Let’s Flare

So my Idea was simple: Let’s feed something to the blue team to keep them busy.

A traditional flare

A Flare is used to distract heat seeking missiles – that’s exactly what we gonna do. So I came up with the name flaReportUri for the script I’ve developed.

CSP – Content Security Policy

If you’re into pentesting, I assume you know about the Content Security Policy. It looks somewhat like this:

script-src 'none'; report-uri https://secreslab.report-uri.com/r/d/csp/enforce; [...]

If the Browser determines a violation against those rules he will block them (if stated in “Content-Security-Policy”) and Report the violation to report-uri. If the Policy is within “Content-Security-Policy-Report-Only”, he won’t block the violation, but still report it. This is useful for testing the policy.

As you can see, I’ve used Scott Helmes report-uri.com Service for this example. You can see what your Browser is doing, if you visit https://badredirect-1.lab.sec-research.net/csp-violation.html (and have a fuzzing proxy enabled). The Browser will post something like this to the report-uri:

{
    "csp-report": {
        "blocked-uri": "self",
        "document-uri": "https://badredirect-1.lab.sec-research.net/csp-violation.html",
        "line-number": 16,
        "original-policy": "script-src 'none'; report-uri https://secreslab.report-uri.com/r/d/csp/enforce",
        "script-sample": "alert('Hello!')",
        "violated-directive": "script-src 'none'"
    }
}

In the report-uri.com Report it will look like this:

So we will need different violations for the blue team to draw their attention away.

First of all, I randomised the agents from the following list: https://techblog.willshouse.com/2012/01/03/most-common-user-agents/

Second, I randomised the violation script sample, I took a few lines from here https://gist.githubusercontent.com/kurobeats/9a613c9ab68914312cbb415134795b45/raw/954b4d3a29cd0fbeb5b841b54126326a6c14a5c1/xss_vectors.txt (kudos to you sir!)

I also counted the lines in the document, to return a feasible number for line-number.

I stored the variables in text-files so it can be easily adapted.

Now, lets see what the script does to the Report:

The little variations are owed to the very small CSP itself.  In real life, the variations are much bigger. Also the script is not perfect – but it did its job: It distracted the blue team for like 6 hours (in the debriefing the blue team said, it kept them quite busy until the realised they cannot trust the reports).  In the first moment they searched for XSS vulnerabilities in the external Web App.

While they were busy we found a different way in, which I’m not allowed to disclose. I know now, that they have recognized the network monitoring alert, but were to distracted from the Report-URI reports (which was exactly what I hoped for).

You can download the FlareScript here: https://badredirect-1.lab.sec-research.net/flaReportURI.tar.gz

Or just copy paste and create user-agent/violation/etc files for your own:

import requests
import json
import re
import random
import time
import argparse

param={}
param['agents'] = './flare/useragents.txt'
param['violations'] = './flare/violations.txt'
param['uris'] = './flare/uris.txt'

def parseCsp(cspstring):
    cspstring=cspstring.strip()
    csp={}
    cspEntries=cspstring.split(";")
    cspEntries=list(filter(None, cspEntries))
    for entry in cspEntries:
        entry=entry.strip()
        entrysplitted = entry.split(" ")
        cspkey=entrysplitted.pop(0) #debug purposes
        csp[cspkey.lower()] = entrysplitted
    return csp

Lessons learned

  1. In the Debriefing the blue team mentioned the additional stress that this situation caused. Stress is a crucial factor in a red team assessment – as well as it is in a real life defense situation.
  2. Report-URI is a powerful tool, but the detection and alerting is delegated to the browser which makes it vulnerable for intended false positives.
  3. If the alerts are too obvious you might get distracted (but you might not ;-)).
  4. It would be great, if report_uri displays and let you filter the IP address of the sender
  5. If you receive reports, check your server logfiles, if the alerts are plausible
The image used to head this article is called Space Oddity and it was created by Robert Williams.