Cross Site Scripting (XSS) Payload Generator

This post will help you to evade some of those tricky cross site scripting restrictions with the help of a new tool I’ve pushed to our XSS Payloads repository.

There are times during a web application penetration test when Cross Site Scripting (XSS) has been identified with a trivial payload such as <script>alert(1)</script> or via a Burp Suite scan result and you want to take it further, but for various reasons it’s not as easy as you would like to inject a useful JavaScript payload. This could be due to output encoding or character blacklisting, which might turn all your single and double quotes into their HTML entity equivalent, or it could be that simply by a quirk of where the injection occurs only non-letter characters can be used. In these cases we usually turn to encoding to build up an obfuscated string which will hopefully bypass these restrictions and that the application can interpret and execute.

For example, an application might block certain keywords in a string, so you encode your payload as base64 and then execute it by decoding with atob() and passing that into eval(), assigned to the “onerror” event of an image, to bypass restrictions on scripts:

<img src=x onerror=eval(atob('YWxlcnQoJ0kgb25seSB3cml0ZSBsYW1lIFBvQ3MnKQ==')) />

Burp Suite includes a few options for this, such as the “Decoder” tool, which can convert strings to and from base64, URL encoding, ASCII hex etc, and the often overlooked “Construct string” function which includes “Construct string in JavaScript” to create a string purely by using the String.fromCharCode() method.

C:\Users\coakley\Desktop\download (1).png

Constructing a string using String.fromCharCode

This is fine for doing a quick fire and forget payload, but what happens when it doesn’t work and you want to make some changes? You slowly find yourself getting caught in your browser’s Developer Tools and making tweaks, then laboriously having to re-encode them to make your chosen bypass method work, then re-encapsulating them into whatever delivery method you were able to use to execute the XSS payload. It’s time consuming, boring and ends up leading to difficult to spot errors because you’re no longer looking at readable source code.

When the injection method becomes more complex, such as when testing blind XSS with something like 0xsobky’s XSS polyglot, having to encode a simple payload into a string begins to quickly become non-trivial.

There were no time-saving options for solving this problem so I decided to make one, and added it to our XSS Payloads repository. It works by setting three basic options for the payload you want to generate which combine to create an encoded string. They should be fairly logical once you get started, but in brief, they are as follows.

XSS Payload

This is what you want the actual action to be when the XSS is executed and includes two methods for inserting an external script (JQuery and document.createElement), two methods for invoking a URL request ( XMLHttpRequest and Image), which are good for establishing execution has occurred when testing for blind XSS, and finally the option to simply write your own JavaScript snippet for when you just gotta have alert(1).

Selecting one of the two load script payloads automatically gives you the option of choosing from the scripts in the XSS payloads repository.


Loading a remote script using JQuery


The next option contains a series of basic obfuscation methods. These are designed to simply bypass filters. By default “None” is selected which simply puts the XSS payload verbatim into the resulting injection string. We also have the option of:

  • String eval() – passes the payload into the eval function.
  • Base64 – uses atob() to pass the base64 payload into eval.
  • Reverse – hides the payload by reversing it before passing to eval.
  • String.fromCharCode() – builds the string by ordinal values.
  • Hex codes – uses hex notation to create a string.
C:\Users\coakley\Desktop\download (2).png

Using the string reverse obfuscation technique

Injection type

This is how the XSS payload actually ends up being interpreted by a browser and is where an app pentester should be spending their time. A basic polyglot that we all know and love is to assume the string is being output unescaped within an element attribute or textarea, and simply attempts to break out of those:


We’ve included other examples for different situations as well, such as within an svg element onload event or, my personal favourite – 0xsobky’s XSS polyglot, which is included in Daniel Miessler’s excellent SecLists repository. If the application can take the input that lengthy and it’s at all vulnerable to XSS, then there’s a good chance this payload will find it.


Add these all together and we end up with something pretty complex looking, which might have taken a bit of time to create manually:

C:\Users\coakley\Desktop\download (3).png

The final payload

If that didn’t work then you can simply tweak some of the options and the XSS payload will be regenerated automatically for you.

If you’ve used one of these payloads in a new and interesting way or you’ve thought of a new payload, obfuscation or injection option to add to the configuration, let me know – I’m @strawp on Twitter. Enjoy!

CVE-2018-20319: Why you should always have two factor authentication on your VPN

The OpenConnect VPN client, on all supported platforms, suffered from a possible information leak that could result in an attacker with elevated local privileges obtaining plaintext credentials.  This VPN security vulnerability has now been patched and assigned CVE-2018-20319.

Affected Software

Vendor website:

Affected versions: OpenConnect client – Windows, Linux, Mac OS X, Android, Solaris, BSD, GNU/Hurd – versions 7.08 and below.


The closed source Cisco AnyConnect VPN client infamously suffered from an information leak, whereby credentials and session cookie information was stored insecurely in memory. An attacker with access to the endpoint could scan the memory and retrieve the credentials. An advisory was issued for this:

Nettitude has exploited this VPN security vulnerability on several occasions, scraping credentials from the Cisco AnyConnect client memory during red team engagements, and we always recommended that two factor authentication is used for any VPN.

At the end of 2018, I installed the open source OpenConnect client in order to connect to a VPN, and thought I would have a poke around in memory to see if this too suffered from a similar issue.

Lo and behold, plaintext credentials are visible in memory in the OpenConnect Windows client:

After discovering this, I performed a quick test on the Linux client. You need to have root privileges in order to scan the memory. I used the scanmem tool, the source code of which is available on

The Linux client also suffered from the same issue, which is not surprising because it’s using the same code base as the Windows version.

I contacted one of the developers in the OpenConnect IRC channel, and contrary to some of my experiences with closed source vendors, I was met with great enthusiasm. The bug was fixed exceptionally rapidly by David Woodhouse and is part of the version 8.00 release.

Advice for Software Developers

Secure programming guidelines are to clear memory of sensitive data immediately when it is no longer required. There is a MITRE documented software weakness entry for this issue at  When using C or C++, be especially careful as the compiler can optimise away a call to memset just before memory is released.

See the following CERT secure programming guidelines for more information:


You never know if some stealthy malware is scanning memory on your endpoints. Always use two factor authentication and patch software regularly to avoid falling foul of vulnerabilities like this one.


  • 20 December 2018 – Discovery
  • 21 December 2018 – CVE issued
  • 22 December 2018 – Vendor contacted
  • 05 January 2019 – Vendor fixed issue
  • 19 June 2019 – Nettitude disclose details

CVE-2019-7315: Genie Access WIP3BVAF IP Camera Directory Traversal

We have discovered a directory traversal vulnerability that affects Genie Access’ WIP3BVAF WISH IP 3MP IR Auto Focus Bullet Camera.  This security vulnerability can act as the first step to full device compromise and has been assigned CVE-2019-7315.

Proof of concept (PoC) of path traversal vulnerability discovered

The directory traversal vulnerability can be exploited via the web management interface for the IP camera, using a URL as follows:

Here is a screenshot showing the contents of the shadow file for a WIP3BVAF IP camera, including the root password hash:

As the WIP3BVAF IP camera makes use of a weak hashing algorithm (DES), it is relatively easy to brute force the hash and obtain the cleartext password, especially if a weak password is in use. Once the password has been recovered, it is possible to obtain a root shell on the camera via telnet:

From here, the username and plaintext password for the web interface can be retrieved by using a tool such as strings against the /mnt/mtd/flash/config.dat file. Once these have been obtained, administrative access to the management interface is possible, where the camera feeds can be viewed and disabled, or the camera configuration adjusted.

Models with the directory traversal vulnerability

All firmware versions for this particular model (3.x.x) are affected.

While a firmware version (4.2.1) has been released to address the security vulnerability in later camera models, this version is not transferable to the WIP3BVAF model. This is due to the fact that the WIP3BVAF model is based on H.264 encoding, while later models of camera manufactured by Genie Access make use of H.265 encoding.

The WIP3BVAF is no longer manufactured by Genie Access and can be considered as end of life. According to the manufacturer, no patch addressing this vulnerability will be released.


As demonstrated, the path traversal vulnerability can be the potential starting point for complete compromise of the WIP3BVAF camera.

Since no fix will be forthcoming due to the camera being end of life and no longer manufactured, it is advisable to refrain from using this model. If this isn’t an option, a sufficiently isolated VLAN should be considered for the camera to prevent it being easily accessible, and a strong, unique password should be set for the root user.

Genie Access Directory Traversal Vulnerability Timeline

  • Vulnerability discovered: 7 Jan 2019
  • Genie Access informed: 13 Jan 2019
  • Genie Access response detailing no fix would be forthcoming: 16 Jan 2019
  • Nettitude public disclosure: 29 May 2019

Operational Security with PoshC2 Framework

This post describes a new capability that has been deployed within PoshC2, which is designed to assist with revealing a wider set of target environment variables at the dropper stage, as part of operational security controls.

Imagine the following scenario.  You’ve deployed IP address white-listing on a proxy in order to limit implant installation to a specific environment.  A connection arrives back from a host that’s not associated with your target environment, so the connection is dropped and PoshC2 never sees the incoming connection attempt.  By adding some additional logging on the proxy, and utilising the new script, you can now reveal specific environment variables about where the dropper was executed.  This information allows for better decision making on what to do next in this scenario.  It yields greater situational awareness.

The background

When carrying out red team testing, a number of safety checks are required to:

  1. Environmentally key the implant to the target environment variables.
  2. Make sure only those targeted assets are compromised.

The purpose of this post is not to discuss these safety measures in depth.  Rather, it is to instead focus on the problem wherein a target environment has been IP white-listed on the attacking infrastructure, but a connection has come back from an IP address not already on that approved list of target environments.  Large organisations do not always readily or thoroughly understand their full external IP address range, or do not force tunnelling of all traffic across a VPN.  It is therefore not uncommon to receive legitimate connect backs from non-whitelisted sources.

As a simulated attacker, you now have a decision to make; you have sent very unique malicious links to a target employee and those have been verified as followed, and certain local checks have been satisfied, but the connection is coming from an IP address that’s not on your white-list. The dropper must have been executed and has consequently called back to your attacking infrastructure to download the core implant from the PoshC2 server.  Now what?

Further detail

PoshC2’s implant is a staged implant and utilises a dropper to satisfy certain criteria before calling back to the C2 server to pick up a core implant. The dropper uses a unique encryption key specific to the PoshC2 instance, but not unique to each dropper. Each dropper shares the same encryption key; it is only when the core implant is sent down that each implant is uniquely keyed for all further communication.

Generally, the following infrastructure is set up to support a PoshC2 instance. This includes a number of redirectors or Internet Proxies that forward C2 communications back to the PoshC2 instance, limiting exposure of the C2 servers and allowing a flexible approach to building many redirectors to combat take-downs or blocked URL’s.

The redirectors can be made up of any infrastructure or technology, whether it be cloud based redirectors such as CloudFront, or applications running on a host such as Socat, python or Apache, to name a few.

Apache is a preference for its rewrite rules, which can be used to make smart decisions on traffic traversing the proxy. White-listing the X-forwarded-for address is one common method and can be written into rewrite rules using a RewriteMap, as follows.

Something you might not know

The configuration of the dropper has now been modified to retry multiple times after a timeout, if the connection returns a HTTP 404 response. This provides extra time to make a decision on whether to add the IP address to the white-list, without losing the implant. If the IP address is then added to the white-list, then when the dropper connects back, it will be allowed to traverse to the PoshC2 server instance and download the core implant.

Extra help

The script was created to assist in decision making by providing more information. The connection from the dropper includes a cookie value that details useful environment variables such as those detailed below, however it is encrypted with the key created on initialisation of the PoshC2 instance.

  • Domain
  • User Account
  • Hostname
  • Implant Architecture
  • Process ID
  • URL

Capturing the cookie

By default the cookie value will not be stored anywhere on the proxy server. As previously mentioned, Apache is powerful and includes a number of options to assist, one of which is ModSecurity.

Installing ModSecurity:

apt install libapache2-modsecurity

Enabling the configuration to capture cookies for requests that are returned a HTTP 404 response:

Now if a dropper connects and gets a 404 response, the following log entry will be created in “/var /log/apache2/sec.log”:

The script

The script has been created to ingest the log file and parse the ‘SessionID’ from the log file, then connect to the PoshC2 database to retrieve the encryption keys and use the encryption functions to reverse the cookie value. It has to be executed on the PoshC2 server.

python log.txt


With increased visibility comes better decision making.  Knowledge of the workstations domain and the user generally provides most, if not all, of the information you need to assess whether an asset is in scope.  We have multiple layers of protection in our approach to risk management to ensure that we stay on the right side of the rules of engagement, and this is just one of them.  We recommend that you develop your own set of risk management procedures too.