Vegan: Chrome extension to defeat BeEF

The Browser Exploit Framework (BeEF) is an easy-to-use open-source tool for attacking web browsers used by security professionals and attackers alike. There are few known methods for defending against BeEF attacks, so I decided to build a Chrome extension to thwart attacks. It is called Vegan.

The Vegan Chrome Extension can be downloaded here.  This is an open source proof of concept, and is provided as is.  Use at your own discretion.

In order for BeEF to gain control over a browser, the browser must be tricked to execute malicious JavaScript code. This can happen on any website that the attacker can control, or even in malicious advertisements, and tends to occur transparently to the affected user. This JavaScript code connects back to the BeEF control panel, which is essentially a highly interactive command and control panel. The attacker then has the option to run a myriad of attacks or information gathering tools.

Looking for Existing Methods

I started searching for anything that at least detected BeEF being used. I did not find much.

What I did find was a Snort rule (from EmergingThreats.net). Here is an abbreviated version of that rule:

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (flow:to_server,established; content:"Cookie|3a 20|BEEFSESSION=";)

For anyone not familiar with Snort, it is an intrusion detection/prevention system that operates by observing network traffic and testing whether it matches various rules. It is a useful tool that should be in every defender’s tool belt. This Snort rule specifically is looking for any HTTP clients on the local network communicating with any remote HTTP server, and will alert if the HTTP client is sending a cookie with the name BEEFSESSION.  If we infect a client, we do not actually see this cookie being set but instead see BEEFHOOK.

BeEF Basic Demo and Cookies

As it turns out, the BEEFSESSION cookie is only set on the browser administering the BeEF web panel, and not on the victim’s. If this rule was looking for BEEFHOOK instead, it could potentially be effective.

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (flow:to_server,established; content:"Cookie|3a 20|BEEFHOOK=";)

For instances of BeEF with the default configuration, this should detect any browsers currently infected by BeEF, as long as they are communicating over unencrypted HTTP.

“Keep out...or enter. I’m a sign, not a cop”

This is one of my favorite quotes from the Simpsons (at least from recent years), even if it was only written on a sign. I feel it is great symbolism for poor security practice everywhere. I feel the Snort rule is like this sign, saying there is protection against BeEF, but really only if the attacker wants to give up immediately.

For any attacker with the super technological savvy to know how to modify a configuration file and any forethought to believe someone may be looking for a cookie with this name, the Snort rule is trivial to bypass. From the BeEF configuration file, we can see that we can change not only this cookie name, but quite a few other values, including other cookie names.

BeEF Configuration File

While I am a user and fan of Snort, I was not particularly excited about the prospect of using it to protect against BeEF. One of the reasons is that BeEF is functional over HTTPS, so plaintext-only detection would not be particularly effective. An additional reason is I would need to set up Snort on any of my computers that I traveled with in order to protect myself on any network I did not control. That level of effort for a not so common method of attack was a bit excessive.

Building My Own Method

I subscribe to the philosophy that, to keep the internet as safe as possible, there needs to be a balance between offensive research and defensive research. If one outweighs the other, we start to lose ground against the ever changing and growing threats we face. If offense is given too much focus, we build far too few defensive methods to protect, and really end up purely in a cycle of identify and patch. If defense has too much focus, our simulated attacks against networks/software/etc. fall behind the curve, allowing for the defenses to be potentially blindsided by massive scale vulnerabilities being used by malicious actors and not being responsibly disclosed.

It is because of this philosophy that I am explaining my process, with hopes that others will join me.

Building a Chrome Extension to Explore Options

I decided to build my protection into Chrome browser so I could easily deploy it to devices regardless of the OS, handle HTTPS seamlessly with HTTP and approach the problem from the choke point.

Chrome extensions are relatively simple to develop, given some familiarity with Chrome’s API. Extensions at a minimum consist of a manifest file (manifest.json) and at least one Javascript file. They can also have HTML files, icons and other files if the extension has a user interface.

Let’s start with the following extension code:

manifest.json

{  
  "manifest_version": 2,
  "name": "Vegan",
  "description": "This extension detects BeEF hooks and blocks the offending domain, effectively stopping the attack.",
  "version": "1.0",
  "background": {
    "scripts": ["popup.js"]
  },
  "permissions": [
    "cookies",
    "*://*/*"
  ]
}

popup.js

// Detect bad cookies
chrome.cookies.onChanged.addListener(function(changeInfo)
  {
    console.log(changeInfo);
  }
);


This extension will log any cookie events sent from Chrome to the extension.

BeEF's Cookie Events

We can see various cookies being set and unset here. This includes the BEEFHOOK cookie. Now let’s modify the BEEFHOOK cookie in our configuration and see how this changes.

BeEF's Modified Cookies

Screenshot_-_06022015_-_112915_AM

We can see that the configuration change has modified the cookie name being set. We also see a cookie named “cookie” with a value of “none” being set and unset, which might be a better indicator to look for.

Wait, where did this cookie come from?

Thanks to the BeEF project being open source, we can simply determine what the purpose of this cookie is.

Screenshot_-_06022015_-_113552_AM

As it turns out, these cookies are created and destroyed in order to test the ability of the browser to create different types of cookies. Additionally, the name and value of these cookies are not configurable (without modifying the BeEF project itself).

Build Detection Method for Unmodified Versions of BeEF

Let’s try triggering on any event regarding a cookie with the name of “cookie” and value of “none”.

popup.js

// Detect bad cookies
chrome.cookies.onChanged.addListener(function(changeInfo)
  {
    if(changeInfo.cookie.name=="cookie" && changeInfo.cookie.value=="none")
    {
      alert("Potential beef hook...");
      console.log(changeInfo);
    }
  }
);


Detection of Attempted BeEF Hook

BeEF Hook Cookie Events

 

For good measure, let’s also check for the presence of a cookie with a value that is the correct length for a BEEFHOOK cookie.

popup.js

// Detect bad cookies
chrome.cookies.onChanged.addListener(function(changeInfo)
  {
    if(changeInfo.cookie.name=="cookie" && changeInfo.cookie.value=="none")
    {
      console.log(changeInfo);
      chrome.cookies.getAll({domain: changeInfo.cookie.domain}, function(cookies)
        {
          var dl = cookies.length;
          if(dl>0)
          {
            for(var x = 0; x < dl; x++)
            {
              var c = cookies[x];
              if(c.value.length == 80)
              {
                console.log(c);
                alert("Malicious cookie detected for domain: " + c.domain);
              }
            }
          }
        }
      );
    }
  }
);


Improved Detection Method

 

Prevention is the Name of the Game

While a detection method is important, it really only tells the user they are now at the will of the attacker, and there is not much the victim can do.  The real value comes from prevention, because if we can both make the user aware of an attack and stop them from being at the will of an attacker, they are truly protected.

In order to add a prevention mechanism to this Chrome extension, we will block any domain attempts to set the cookie we are detecting. This will prevent the browser from being able to communicate with the BeEF panel.

manifest.json

{
  "manifest_version": 2,
  "name": "Vegan",
  "description": "This extension detects BeEF hooks and blocks the offending domain, effectively stopping the attack.",
  "version": "1.0",
  "background": {
    "scripts": ["popup.js"]
  },
  "permissions": [
    "cookies",
    "*://*/*",
    "webRequest",
    "webRequestBlocking"
  ]
}


popup.js

var blocked_domains = [];
chrome.webRequest.onBeforeRequest.addListener(function(details)
  {
    return {cancel: blocked_domains.indexOf(details.url.match(/^[\w-]+:\/*\[?([\w\.-]+)\]?(:[\w]+)?(?::\d+)?/)[1])>-1};
  }, 
  {
    urls: ["<all_urls>"]
  }, 
  ['blocking']
);
 
// Detect bad cookies
chrome.cookies.onChanged.addListener(function(changeInfo)
  {
    if(changeInfo.cookie.name=="cookie" && changeInfo.cookie.value=="none")
    {
      chrome.cookies.getAll({domain: changeInfo.cookie.domain}, function(cookies)
        {
          var dl = cookies.length;
          if(dl>0)
          {
            for(var x = 0; x < dl; x++)
            {
              var c = cookies[x];
              if(c.value.length == 80)
              {
                console.log(c);
                chrome.cookies.remove({name: c.name, url: "http://" + c.domain + c.path});
                if(blocked_domains.indexOf(c.domain)==-1)
                {
                  blocked_domains.push(c.domain);
                  // todo Save changes to block list
                }
                alert("Malicious cookie detected for domain: " + c.domain + " (now blocked)");
              }
            }
          }
        }
      );
    }
  }
);


BeEF Hook Prevention

If we try to refresh the page, we can see now the extension has blocked all access to the offending IP/domain.

Vegan blocked BeEF

If we look at our BeEF control panel, we can see that our browser did not show up as an active victim.

BeEF Control Panel does not show our browser

At this point, we can consider this method effective at blocking BeEF hooks into our Chrome browsers. It should be noted that the developers for BeEF, if they wished, could change the project to avoid detection with this extension. 

Wrapping Up

The Browser Exploitation Framework is a useful tool for offensive security researchers looking to test out attacks against browsers, as well as further gaining access during penetration testing. While this tool is well known, any protections against it are not.  As a security researcher, I wish to maintain the balance between offensive and defensive research, so even smaller defensive projects like this provide a benefit.  If more security researchers worked on open source defensive projects/research, we could, as an industry, tip the scales back into balance.