Saturday, July 21, 2012

SQLi with Web Services

Good old SQL injection is coming back... with Web Services.

A Web Service is a method of communication between two devices using SOAP messages.
SOAP relies on XML for its message format. It can be transferred over FTP, SMTP or HTTP.
In this way, Web Services are independent of the underlying network protocol!

Why using Web Services? With a Web Service it is possible to convert your 'older' application into a web application, which can publish its function or message to the rest of the world. Nice!

A Web Services Description Language or WSDL is used to describe the interfaces of a Web Service. It is an entry point based on the XML language. The WSDL point contains all the information your application needs to know to start communicating with the Web Service.

What to hack? Most of the web vulnerabilities are coming back with Web Services. Over the last years web developers have done a lot of effort in sanitizing all code going through their web applications. Maybe they just forgot to check their Web Services?!?

Using a search engine like Google you could find some Web Service WSDL entries:

inurl:wsdl site:example.com


The following URL could be a result of our search query:

http://www.example.com/soap/service.asmx?WSDL


Now we can explore the WSDL entry using a browser or a SOAP parser. After exploring the entry we know all the interfaces of the Web Service. We can start communicating with it!

In the next screenshots I'm illustrating this with WebGoat, a test platform for security testing.

The WSDL entry:

http://127.0.0.1:8080/webgoat/services/WsSqlInjection?WSDL


We can explore it with our browser:



With a SOAP parser we can generate the following request:



We found a very interesting operation getCreditCard, accepting a string as input and returning a string as output. The output string is the credit card number. What could be the input string?

After analyzing the web application source code we found the following SQL statement:

"SELECT * FROM user_data WHERE userid = " + accountNumber;

(by the way, this is a very dangerous SQL statement)


The underlying database engine is receiving a number (accountNumber) and giving us back all the records for the specific number. The accountNumber is definitely our input string that we will send with a SOAP request.

As a valid account number we can use 101.

The results from our SOAP parser with account number 101:



We have two valid credit card numbers for account number 101.
Do you want all the credit card numbers for all the accounts? Really?

We could enter the following:

101 or 1=1


Our database will interprete this as:

SELECT * FROM user_data WHERE userid = 101 or 1=1;


This will probably display all the records because we adjusted the SQL statement with our OR expression:





We have all the credit card numbers. This is jackpot!

We can conclude that our Web Service does not sanitize malicious code.
In the same way we could start other more advanced attacks using SQL injection, command injection or even Cross-Site Scripting (XSS),...