Application security

Web Services Penetration Testing Part 5: Manual Testing with soapUI

Nutan Panda
November 27, 2013 by
Nutan Panda

In the previous article, we discussed the importance of manual web services penetration testing, how to perform a manual test using SOA Client, how SOA client helps us in most cases, and what the restrictions are that require us to choose other options.

In this article, we will find the solution to those problems that we discussed in the previous part.

The scenario was: What if we are performing a black box test and the sample request is not disclosed to the public? What if, in the same scenario, this SOA Client is unable to parse one of our requests properly? In that case, we need other options to perform the test, and nothing is better than an open source specialist web services testing tool.

Yes, it is soapUI. As we discussed in one of the previous articles, "Web Services Penetration Testing, Part 2: An Automated Approach With SoapUI Pro," SoapUI by SMARTBEAR (http://www.soapui.org) is the only one popular tool to test for soap vulnerabilities. It comes in two versions: 1. SoapUI (which is open source) and 2. SoapUI Pro (the commercial version). We have already learned how to use SOAP UI Pro, now it's time to learn about how to use the open source version, i.e., SoapUI (http://www.soapui.org/Downloads/latest-release.html).

Testing Web Services with soapUI

Although the initial process of creating a project is same in both soapUI and soapUI Pro, I just want to quickly cover all of those again. To create a project, open your soapUI. You will see the initial window, as shown in Figure 1.

Figure 1: soapUI start window

Click on "File" and "New SOAP Project" to open another window, as shown in Figure 2.

Figure 2: New SOAP Project window

Fill in all the details. Name the project anything you want and the initial WSDL should be either the WSDL file URL or the local path if you have the WSDL file locally. I will use the http://www.testfire.net/bank/ws.asmx?WSDL URL for testing, as shown in Figure 3.

Figure 3: New SOAP Project window with data

Then click "OK" to load all the definitions and you will get all the definitions in your soapUI, as shown in Figure 4.

Figure 4: soapUI window with imported definitions

A similarity between soapUI and soapUI pro is that you can edit the interface properties, as shown in the left bottom corner, but in soapUI we can't add new properties. And the most important thing is that the security automation feature is only present in soapUI Pro but, apart from that, in the case of manual testing, soapUI is as powerful as soapUI Pro.

Now click on any method you want to test. Let's say we were facing a problem in the TransferBalance method in SOA Client, so we will start from there to check whether or not we will face something like that here. The request editor window is shown in Figure 5.

Figure 5: Request editor window

Unlike soapUI Pro, the request editor window of soapUI contains only two tabs:

  1. XML
  2. RAW

Mostly we will use XML and, unlike the SOA Client, soapUI parsed the method successfully, so we don't have a problem generating proper requests.

Though soapUI is an excellent tool, it has a major disadvantage in the case of black box testing: It won't show you the data type required to test a particular request. In this case we have three options:

  1. You need to guess or fuzz all types of data types in different parameters. But this is not a smart way of testing and also very time-consuming.
  2. You can get help from some other tool, such as SOA Client, to get these details.
  3. Read the WSDL file and understand the requirements of the request (to understand different elements of WSDL go through Web Services Penetration Testing Part 1)

Let's start with the first option to guess the values we need to understand the request properly. We can see the request in Figure 6.

[xml]

<soapenv:Envelope xmlns_soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns_ws="http://www.altoromutual.com/bank/ws/">

<soapenv:Header/>

<soapenv:Body>

<ws:TransferBalance>

<!--Optional:-->

<ws:transDetails>

<ws:transferDate>?</ws:transferDate>

<!--Optional:-->

<ws:debitAccount>?</ws:debitAccount>

<!--Optional:-->

<ws:creditAccount>?</ws:creditAccount>

<ws:transferAmount>?</ws:transferAmount>

</ws:transDetails>

</ws:TransferBalance>

</soapenv:Body>

</soapenv:Envelope>

[/xml]

Figure 6: transferBalance Request

Here we have four parameters; let me guess the data type by its parameter name.

  1. transferDate(this must be in date format) = 2013-11-11
  2. debitAccount (this must be integer type) = 112233
  3. creditAccount (this must be also of integer type) = 445566
  4. transferAmount (this must be double) = 100.00

As it is black box testing and we don't have a clue for the data types, we will use what we have guessed. After inserting all those data, the request looks like Figure 7.

Figure 7: transferBalance request with data

Let's send this request by clicking the green button in the top left corner of the request window, as shown in Figure 7, and we will get the response as shown in Figure 8.

Figure 8: showing response of transferBalance request

We got the response, "Transaction failed - debit account does not exist," but we don't know whether it's a successful response or error response. To check that, click on the RAW tab of the response window as shown in Figure 9.

Figure 9: Raw response window

Two things we get from that response:

  1. Our request executed properly.
  2. We got a vulnerability, i.e., a header version disclosure.

The SOAP response header discloses the following version details:

Server: Microsoft-IIS/6.0

X-Powered-By: ASP.NET

X-AspNet-Version: 2.0.50727

Everything worked fine, but we still don't know whether the data types we assumed are correct or not, so let us move to the next option, i.e., collecting data type information from SOA Client.

We learned how to test using SOA Client in the "Web Services Penetration Testing Part 4: Manual Testing with SOA Client," so, without taking much time, I will directly show you where to collect this information. Just check it in Figure 10.

Figure 10: SOA Client showing parameters with required data type

It's a very simple process. Open SOA Client. In "URL," provide the WSDL URL. Click on "Parse WSDL" and in the result window you can find the parameters with data types. But sometimes it is unable to parse a WSDL properly; in that case, there is nothing to worry about; just go below and, in the "Raw WSDL Data," you can find the parameters as well as the data type needed under the particular method or operation name.

As you can see from Figure 10, the required parameters with needed data types are:

  1. "transferDate"(date-time)
  2. "debitAccount" (string)
  3. "creditAccount" (string)
  4. "transferAmount" (double)

As we discussed earlier, the same can be also found at the WSDL, as shown in Figure 11.

Figure 11: WSDL showing parameters with required data types

We can get these details in both ways discussed above, but I personally feel that it's better to understand the WSDL file and better to be tool-independent. But both the options are in front of you. You can choose whichever one you are comfortable with.

So, as we now have all these details, we can easily fill the appropriate data types and send the request in soapUI. The data we are going to use are:

  1. transferDate(date-time) = 2013-01-01T00:00:00
  2. debitAccount (string) = 1001160140
  3. creditAccount (string) = 1001160141
  4. transferAmount(double) = 1.0

Let's send the request with these data. It will look like Figure 12:

Figure 12: transferBalance request with data

Let's send this request by clicking the green button on the top of the left corner and we will get the result shown in Figure 13.

Figure 13: response window after successfully executing the request

Voila, we successfully sent the request and got the response that "$1 was successfully transferred from Account 1001160140 into Account 1001160141 at 11/16/2013 2:15:47 PM". Some might think how exactly I got these numbers correct; yes, this is a question but the other major question is how you can get all these data correct. It's simple by fuzzing the parameters.

We have four parameters here, of which two are independent, i.e., transferDate and transferAmount. And now we are left with two parameters. debitAccount and creditAccount. As there is no anti-automation we can fuzz both the parameters and enumerate the account number.

Now, since we successfully executed this request and collected some genuine data, we can use them to test some other test cases. Since it is a banking application and it allows us to send money from one account to another, let's check whether a negative balance transfer is allowed or not.

We will use the same data that we used in the previous request, just changing the transferAmount value from 1.00 to -1.00. The data used:

  1. transferDate(date-time) = 2013-01-01T00:00:00
  2. debitAccount (string) = 1001160140
  3. creditAccount (string) = 1001160141
  4. transferAmount(double) =- 1.0

And let's check the result, as shown in Figure 14.

Figure 14: response window after successfully executing the request

Yes, we are able to transfer a negative balance. This is one of the critical business logic vulnerabilities in any banking application or service. And this is the power of manual testing. This kind of vulnerability can never be detected by any auto scanner.

Let's now look at another test case. We will use the same data used in the previous request, but this time with a $2.00 transferAmount. The only other thing we will change is that we will use the same account number for both debitAccount and creditAccount. Here we will check whether this web service validates the uniqueness of debitcardAccount and creditcardAccount before executing the service or not. The data used:

  1. transferDate(date-time) = 2013-01-01T00:00:00
  2. debitAccount (string) = 1001160140
  3. creditAccount (string) = 1001160140
  4. transferAmount(double) = 2.0

And let's check the result, as shown in Figure 15.

Figure 15: response window after successfully executing the request

This is again a critical business logic vulnerability. A banking service must validate that the sender's account and receiver's account are not the same.

Similarly, you can think out of the box according to your scenario; understand the functionality of the web service first and then experiment with different approaches to get new nontraditional vulnerabilities.

Now it's time to try some very popular test cases. The data we will use are:

  1. transferDate(date-time) = 2013-01-01T00:00:00
  2. debitAccount (string) = 1001160140'
  3. creditAccount (string) = 1001160141
  4. transferAmount(double) = 2.0

The result is shown in Figure 16.

Figure 16: response window showing error message.

In this case we found:

  1. System.Data.OleDb.OleDbException (we got a DB Exception or possible SQLI)
  2. d:downloadsAltoroMutual_v6websiteApp_CodeWebService.cs:line 146 (server path disclosure)

Though we found some good business logic vulnerabilities, it's not possible every time to find the same. Most of the time, the common vulnerabilities that we find on a web service are information disclosures, such as header version disclosure, private IP address disclosure, database error pattern found, etc. Apart from that, authorization-related vulnerabilities are very common in this case. Some other common vulnerabilities, such as SQL Injection, can also be found. But we need to focus most on information disclosure, as web services are being used in complex enterprise level applications and those applications contain a huge number of vital, private and important information.

Conclusion

In this article, we focused on how to perform manual web services penetration testing using soapUI: How to get information regarding the data type needed for different parameters and how to generate different test cases according to the given scenario to test different business logic vulnerabilities. So, as I mentioned in the Web Services Penetration Testing Part 1, the testing approach of web services is quite similar to the testing approach used in web applications. You will agree with me after completing this article.

The only problem here is that it is very difficult to execute each and every request independently in soapUI. Let's say I want to fuzz a parameter: It is very difficult for me to do so just using soapUI. So, in the next installment, we will discuss how to integrate soapUI with other tools to automate the testing process.

References

http://www.soapui.org

11 courses, 8+ hours of training

11 courses, 8+ hours of training

Learn cybersecurity from Ted Harrington, the #1 best-selling author of "Hackable: How to Do Application Security Right."

https://addons.mozilla.org/en-US/firefox/addon/soa-client/

Nutan Panda
Nutan Panda

Nutan Kumar Panda is a Security Analyst, with expertise in the field of Web Application and Network Penetration Testing. He is an Infosec and OSINT enthusiast and has been involved into corporate training besides his hobby of Open Vulnerability Disclosure.