RSS Feed

Local Request Forgery

This post explains how to abuse Internet Explorer’s Local Intranet Zone using malicious web pages served from the local disk. In corporate environments this could lead to impersonation of the victim on internal web applications and exfiltration of data outside the corporate network. 

Internet Explorer renders web pages in Security Zones; each zone comes with security settings that reflect the level of safety of that zone. 

When Internet Explorer opens a web page, the Urlmon DLL determines the zone from which the page was loaded. There are four predefined security zones:

  • Local intranet zone: all sites inside an organisation.

  • Trusted sites zone: all sites considered trusted.

  • Restricted sites zone: all sites considered not trusted. 

  • Internet zone: all Internet sites (not in the Trusted or Restricted zones)

In addition to the above four zones, the hidden My Computer zone includes all files served from network shares, the local hard disk and removable drives.


Cross-Site Request Forgery (CSRF) is an attack that abuses the inherent trust a web server places in the browser. Generally, any request within an authenticated session is assumed to be made, directly or indirectly, by the user. The attack described below can be considered a variation of Cross-Site Request Forgery where the attacker can also read the response. Instead of coercing the user to visit a malicious Internet website, the attacker sends an email with a malicious HTML page attached; when the victim opens this page with Internet Explorer it is loaded from the local file system and Internet Exploror (IE) renders it in the My Computer security zone. This zone allows scripts to issue requests to any website bypassing both the Same Origin Policy (SOP) and Cross-Origin Request Sharing (CORS).


Since IE 7, Protected Mode adds an integrity mechanism to restrict write access to securable objects (like processes, files, and registry keys) with higher integrity levels. If Protected Mode is disabled cookies are included when (malicious) scripts issue HTTP requests. The Local Intranet Zone is used in many corporate environments for internal web applications. Note that Protected Mode is disabled by default for the Local Intranet Zone on all current versions of Internet Explorer. Consequently, the malicious web page attached to an email described above can include JavaScript to target an internal application to which the victim is authenticated. This JavaScript will bypass SOP and CORS, because the page is rendered in the My Computer Zone, which enables the attacker to perform requests and read responses.


Demo Application

A simple demo web application was built as a Proof-of-Concept. The application is served from the Local Intranet Zone domain www.corporate.internal as shown in the screenshot below:


Monet HR is a web application used for HR purposes, it allows employees to view and manage their personal data such as personal and employment information, compensation, holidays, etc. 


The demo application exposes a single Servlet to authenticated users:


The servlet allows the user to perform two actions:

  • getCSRF (retrieves the CSRF token associated with user’s session)

  • getInfos (retrieves user’s information, it requires a CSRF token)



  1. The target web application is served from the Local Intranet Zone.

  2. Protected mode is turned OFF for Local Intranet Zone (default).

  3. The victim is authenticated on the target web application.


Attack PoC

  1. The victim receives an email with a web page attached.

  2. The victim opens the web page with Internet Explorer.

  3. The victim clicks on “Allow Blocked Content” button.

  4. (only for demo purposes) The victim clicks on “Steal Infos”, this triggers the malicious script.


The page served from the local file disk is rendered in the My Computer Zone, and can therefore bypass the Same Origin Policy and Cross Origin Resource Sharing. It can send requests to any application in the Local Intranet Zone, and cookies will be included in the request.

  1. When clicking on the button Steal Infos the JavaScript first issues an XHR to http://corporate.internal/monet/logged/userHandler to retrieve the CSRF token. This violates CORS (the script sends a cross-domain POST request with content type application/json but no preflight OPTIONS request is performed). It also violates SOP as the script can read the response coming back from a different origin.

  2. Having retrieved the CSRF token the JavaScript issues another request to the demo application, requesting the user’s information (a CSRF token is required in the JSON object). Again the JavaScript violates CORS and SOP, as it sends a POST request (with application/json content type) and it can read the user’s personal information back
  3. The malicious page then exfiltrates the stolen data to a third party website ( using a POST request with content type application/json (thus still in violation Cross-Origin Resource Sharing) and can read the response to that request as well (still violating SOP).

The above explanation can be referenced in the screenshot below where request and responses are printed in the DOM.

 The attacker can then view the exfiltrated data on a domain outside of the corporate network:



The attack described above may be considered a variation of Cross-Site Request Forgery. However, server-side CRSF mitigations are not applicable. The demo application employed in the PoC required the submission of an anti-CSRF token, but since the malicious JavaScript can bypass SOP and CORS, it can read the CSRF token and use it in the request.

As this is a client-side issue, the only effective mitigation is to ensure that Internet Explorer enforces SOP and CORS by enabling Protected Mode for the Local Intranet Zone. Since Internet Explorer 7.0 on Windows Vista, this can be achieved through Group Policy Objects (GPO).




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: