Cross Context Scripting with Sage


I would often keep abreast of new vulnerabilities and exploits via my RSS feeds. Visiting page after page was just never fun. RSS allowed me to categorise, organise and track the security mayhem on the Internet. What was the point of employing a security analyst who was outdated and outgunned?

I decided to play with Sage, which is a popular RSS extension for Mozilla Firefox. It had a friendly interface and a nice option to turn HTML tags on and off. This was a feature I was certainly interested in. It meant I could prevent a number of attacks outlined by SPI Dynamic’s recent RSS Injection whitepaper. The recommendation given in this paper was the typical recommendation given to XSS attacks. Escape “<>” to “&lt; &gt;”

I turned off HTML tags and continued on as normal. However, something odd happened. When rendering my whitepaper “Awakening the Sleeping Giant” an insert of JavaScript was executed in my browser. How bazaar I thought. The security enabled feature makes me vulnerable. Sage was vulnerable to XSS! I immediately contacted pdp (architect). We worked on it for 30 minutes and for those 30 minutes all you could hear were sinister laughs.

First: Sage rendered “&lt,&gt” as “<>”. This means JavaScript can be executed when HTML tags are turned off (not the default).

Second: Logical mental progression put forward the question, what if we reversed it? “&lt, &gt” became “<>” when HTML tags were turned on (THE DEFAULT). This means we can effectively hack the latest version of Sage via RSS Injection regardless of which mode is set.

Thirdly: Sage converts the feed into an HTML file and stores it on the local system. This means we were now in the browser’s local zone policy. From here we could read any file from the local system.

See GNUCITIZEN more proof of concept example.

RSS Injection in Sage part 2

2 months ago, both pdp any myself released a vulnerability Cross Context Scripting in Sage. This issue was resolved in Sage release 1.3.7 (see: I found a new vulnerability which affects the latest version, Sage 1.3.8. In addition to the XSS vulnerability, it should be noted (as in the previous vulnerability) that this issue occurs within the Local Browser Context.

A number of popular online RSS readers allow images to be embedded within Feeds. It has been known for some time now, that the amount of people subscribed to your feed can be determined by using the image src functionality. This is interesting from an anonymity point of view. I was curious to know just how well these applications would prevent and/or restrict the img onload features.

Ironically, Sage seems to handle this quite well. It removes any onload attribute within an IMG element. Sage also completely removes offending JavaScript code. However, it fails to remove the script tags when inserted within the IMG element. In addition to this, it will actually end the IMG element for us. For example:

<img src= <script>alert(blah);</script> ></img>
<img src= > <script>alert(blah);</script> </img>
Notice the trailing > is removed and added before our JavaScript code.

A proof of concept feed can be found here.
This feed will open /etc/passwd for Linux users and ./etc/hosts for MS Windows users. Please note I have not tested the Windows feed.

Adobe Universal XSS Just Got Worse

Some had a good nights sleep last night. Generally it will be those who heeded our suggestions given last year September with Backdooring PDF Files, while others most likely didnt get any sleep at all.

I woke up this morning and started getting ready for work. As usual, I turned on my laptop and cruised over to Michael Daws SecNews and then to my RSS feeds. There is alot of talk regarding the new Adobe Universal XSS and its just got worse!

Rsnake was playing (he says for 5 minutes, I bet it was longer), and verified that this XSS attack can be extended to the local browser context. This makes this attack even worse! Not only is this attack universal but it can now exploit localhost too! Nice find RSnake.

If your interested in some of the attacks with local browser context issues check out our RSS Injection in Sage exploits.

This has got to be one of the worst and most widespread XSS attacks that I can ever remember. If your running Adobe <= 7 your most likely in trouble. Check my previous post for fix suggestions.

Proof of Concept


ASP Auditor v2 BETA

ASP auditor v2 BETA

purpose: Look for common misconfigurations and information leaks in
ASP.NET applications.

# Changelog:
# --v2.2-- 20/Apr/07
# * Added additional support for Anti-XSS Validation detection.
# * Added ASP Source Directory Leak Check
# * Added Apr/07 ASP.NET Validation Bypass Check
# --v2.1-- 25/Sep/06
# * GET /Trace.axd often leaks ASP.NET version when other methods fail.
# * Fixed "?" bug in JavaScript Validate test
# * Added Version into usage()
# --v2.0-- 16/Sep/06
# * Version plugin allowing specific ASP.NET versioning.
# * Version brute force capabilities using JavaScript validate
# directories.
# * Check if global ASP.NET validate is being used.
# * Added brute force function and option in usage()

This tool is based on H D Moores Dot Net Application Scanner
Author: H D Moore <>

HDM thanks for the feedback.

$ ./

Usage:   ./ [http://target/app/file.aspx] (opts)

            -bf brute force ASP.NET version using JS Validate

--example 1
$ ./ http://www.*hidden*/index.aspx
[*] Sending initial probe request...
[*] Sending path discovery request...
[*] Sending ASP.NET validate discovery request...
[*] Sending application trace request...
[*] Sending null remoter service request...

[ .NET Configuration Analysis ]

  Server   -> Microsoft-IIS/6.0
  Application   -> /
  FilePath   -> D:\VirtualServers\*hidden*
  ADNVersion   -> 1.1.4322.2300

  matches -> 1.1.4322.2300 Version 1.1 Post-SP1 (Windows Server 2003 SP1)  Mar 2005

--example 2
$ ./ http://www.*hidden*/index.aspx -bf
[*] Sending initial probe request...
[*] Sending path discovery request...
[*] Sending ASP.NET validate discovery request...
[*] Sending application trace request...
[*] Sending null remoter service request...

[ .NET Configuration Analysis ]

    Server  -> Microsoft-IIS/6.0
    AppTrace  -> LocalOnly
    Application  -> /
    FilePath  -> D:\inetpub\*hidden*
    ADNVersion  -> 1.1.4322.2300

    matches -> 1.1.4322.2300 Version 1.1 Post-SP1 (Windows Server 2003 SP1)  Mar 2005

[*] Sending brute force discovery requests...
        Found -> /aspnet_client/system_web/1_1_4322

The tool can be downloaded here:

Bypassing ASP.NET XSS Filters

pagvac from ProCheckUp released an advisory on how to bypass ASP.NET XSS validation.

This attack is only possible with Internet Explorer users as it exploits the old IE CSS comment hack; a very creative find indeed from the guys at ProCheckUp.

Proof of Concept:

Alert box injection - simply provided for testing purposes
(may cause DoS issues on Internet Explorer)

ASP.NET will also escape double quotes(“), so although a number .NET servers are vulnerable to this, it is somewhat mitigated by this fact.

ASP Auditor (with a little mod) could be used to test if your web server(s) are vulnerable. Let me know if your interested. I hope to add this check to the tool shortly.

Writing Secure WordPress Plugins


WordPress has become one of the most popular blogging packages on the Internet; this is largely due to its ease of use and its object oriented design which allows the user to easily extend its capabilities in the form of WordPress Plugins.

Unfortunately, “ease of use”, and “security” are to often like lemon and milk. This article is a desparate attempt to try and educate WordPress Plugin developers to some of the common security problems that can occur. The reality is, that this article is a bit to late, and unfortunately countless plugins are vulnerable to the attacks discussed here.

What does this mean? Well, it means that an attacker could potentially gain access to your WordPress Admin Panel, or take control of areas of your blogs such as your Google Adsense ads – maybe the attacker wants a little extra pocket money.

On the positive side, WordPress itself, does support a number of built in security functions to help combat these issues.

Rather then tackling all the problems in one go, this paper introduces 2 common pitfalls developers are making when writing WordPress plugins. After going through this article I hope developers of plugins (especially popular ones) will begin immediately working to resolve these issues. When this occurs, we’ll look at part 2 of this article.

I am hesitent to release this information as I know just how many plugins these vulnerabilities affect. For this reason, I will try not discuss to much on the exploitation side (although both are fairly trivial to exploit), but rather give guidelines to follow.


Right lets get into it… the functions we will be discussing are “attribute_escape” and “wp_nonce_field”.

Firstly, the attribute_escape function is defined as follows:

applied to post text and other content by the attribute_escape function, which is called in many places in WordPress to change certain characters into HTML attributes before sending to the browser.

You should use this function everytime you intend to echo back data to the user. This generally means all strings from $_GET and $_POST. Lets have an example to illustrate this (this vulnerable code is actually taken from a plugin):

if( isset($_POST['name']) && $_POST['name'] != ''
           && isset($_POST['code']) && $_POST['code'] != '' ){
            $desc = $_POST['comment'];

Now can you spot any problems in the above snippet of code? The problem here, is that the plugin is accepting any value that the user chooses as part of the POST variable named desc. This is not good, as any input including HTML entities will be echoed back to the users browser – Note, this also applies to $_GET as well (it even extends to other global variables supported by PHP, but that is beyond the scope of this paper). So lets secure this using the WordPress attribute_escape function:

if( isset($_POST['name']) && $_POST['name'] != ''
           && isset($_POST['code']) && $_POST['code'] != '' ){
            $desc = attribute_escape($_POST['comment']);

Notice how simple it is to implement this function.

Lets have a $_GET example (also taken from a plugin):

if ( isset($_GET['mode']) ) {
      $mode = $_GET['mode'];

Again, we see that we fail to escape our request from the user with add_attribute. So lets add it:

if ( isset($_GET['mode']) ) {
      $mode = attribute_escape($_GET['mode']);

Applying attribute_escape will greatly increase the security of your plugin. Remember the basic rule, if your plugin echoes back data to the user, ensure that attribute_escape is being used before this occurs.


Our next security feature to our script is to add a random nonce value when using forms. The WordPres definition is as follows:

allows a filter function to define text to be used to explain a nonce that is otherwise not explained by the WordPress core code. You will need to define specific verb/noun filters to use this. For instance, if your plugin defines a nonce for updating a tag, you would define a filter for “explain_nonce_update-tag”. Filter function arguments: text to display (defaults to a generic “Are you sure you want to do this?” message) and extra information from the end of the action URL. In the example here, your function might simply return the string “Are you sure you want to update this tag?”.

There is typically three parts to this:

1st, we check to see if this functionality exists and set it at the top of our plugin:

if ( !function_exists('wp_nonce_field') ) {
        function myplugin_nonce_field($action = -1) { return; }
        $myplugin_nonce = -1;
} else {
        function myplugin_nonce_field($action = -1) { return wp_nonce_field($action); }
        $myplugin_nonce = 'myplugin-update-key';

2nd, we declare our newly generated random nonce into our POST form:

<form action= ...>
      <?php adsense_nonce_field('$myplugin_nonce', $myplugin_nonce); ?>

Finally, we check the nonce is correct in our $_POST request:

if ( isset($_POST['submit']) ) {
      if ( function_exists('current_user_can') && !current_user_can('manage_options') )
      die(__('Cheatin’ uh?'));

      check_admin_referer( '$myplugin_nonce', $adsense_nonce );

Each POST request will now contain a random number that is required in order to make the POST request. It is slightly more difficult to implement then the previous one, but not at all complicated when thought through.

You may have noticed that this addresses POST, but what about GET requests?

$delete_url = wp_nonce_url($get_url . "mode=del", '$adsense_nonce' . $myplugin_nonce);

The above will provide our nonce into the URL, now we just need to have it confirmed in our $_GET function:

if($mode == 'del' ){
    check_admin_referer('$myplugin_nonce', $myplugin_nonce);

And your done… now make sure to test it ?


It is vital for the security of future WordPress plugins that attribute_escape and wp_nonce functions be used to prevent critical vulnerabilities which currently affect many such plugins.

I encourage developers to modify their plugins to reflect these changes. Forgive me if their are blatent errors in the paper, I wrote it quite late while fixing a vulnerable plugin…well I’m off to bed.


Michael Daw Anthology is pleased to announce the first “Michael Daw Anthology” award.

For those of you curious, anthology is a collection of published works. The original idea behind the website was to build stories upon a fictional hacking icon named, Michael Daw, as well as to host other security related material. As a close friend pointed out to me, the name is very relevant “when pondered upon”. Some believe that the archangel Michael holds the keys to the doors of Heaven.

Use cutting-edge security wizardry, use sci-fi… write a hacking story centered around Michael Daw and be 1 of 6 to stand the chance of winning.

The full details of the competition will be provided soon. We are currently seeking sponsors to donate towards the winnings. For more information please contact us.