Attacking web services Pt 2 – SOAP
In the previous article, we discussed forming a SOAP request based off the operations listed in a WSDL file and automating this task with Buby and Burp Suite. Additionally, we covered how to understand the content of the WSDL file. In this article we begin to iterate thru testing and exploitation of various security vulnerabilities in the SOAP service. Not all attacks are specific to SOAP and really, this is an important distinction to make early on.
There is often a belief from newcomers to web security that attacking web services requires some mystical, super difficult set of advanced attacks to break. The reality is that web services suffer from many of the same types of vulnerabilities that plague traditional browser-based applications.
For instance, you’ll notice that Broken authentication and Sessions Management flaws are included under our list of weaknesses below. Look familiar? It should, this is an OWASP Top Ten vulnerability that affects both web applications and web services alike.
The categories of vulnerabilities we explain and then exploit are:
- SOAP Injection
- SQL Injection
- Default Content
- Broken Authentication and Session Management
While some security flaws in web services are very similar or even identical to well known and documented web application vulnerabilities and may required medium to low skill-sets to exploit, SOAP Injection does not fall under this category. This particular weakness is often very hard to detect and even harder to exploit.
How does this occur? The XML parsing engine on the server-side component which receives input from the client, whether that client be a browser, data from a web application, a mobile device or some other manifestation, fails to properly validate input and may even provide errors that assist in exploitation.
Due to the fact we are approaching SOAP Injection from the standpoint of an attacker we are going to assume no prior knowledge or insight into how the SOAP request is processed on the server. This requires us to have error messages that are overly verbose (sounds a little like a security misconfiguration maybe?).
Take the following request:
The request appears normal. We send our first and last name and a password. Now, if the request is sent normally then it is parsed normally and we are either granted access or not depending on what we’ve submitted.
Now let’s form the same request but this time omit the <lname></lname> tag.
It appears we have broken something. The following is the response from the server:
This error actually shows us code! We can see a short circuit statement, which tells us that if the lname variable is missing then the code should use a loginid parameter instead. Now this is interesting. In this case we want to omit the lname tag to trigger the short circuit statement (“||”) and submit a loginid tag instead.
Here is our new request:
Now we are greeted with the following message:
This tells us that we need to start performing actions with the credentials or information that we’ve gleaned (submitting the <loginid>1</loginid> tag).
This is a relatively simple attack and is really playing off the poor parsing engine written in the background along with errors to submit requests as an administrative level user.
For this portion we will use some of the code we had created in Part 1 of this series. Lets fire up burp with the buby script we’ve written called attack_soap.rb
Lets send a request to the WSDL file, intercept in burp, form the request and then complete the sequence by sending to intruder for fuzzing and analysis.
As in Part 1, this will automatically form a SOAP request based off the operations and parameters within the WSDL file we are requesting. Inside the attack_soap.rb script we’ve coded the formed SOAP request to pass through the Burp proxy. Once this request is formed and intercepted we will send it to intruder.
Navigate to Intruder > Positions. We are going to define where we would like to insert fuzzing strings.
Take notice that we have wrapped 101 in between insertion points. This is so our fuzzing string will replace the integer “101”.
We now need to choose payloads. Fuzzdb is an excellent source of fuzzing strings and can be found here: http://code.google.com/p/fuzzdb/ however for the purposes of this tutorial we can leverage Burp’s built in payloads for this tutorial.
Choose the preset list drop down; add from list drop down and finally the “fuzzing-full” payload.
Start the attack like so:
Now we need to review the responses from the application. Notice that while the majority of the responses are a byte length of 634 the string “1 or 1=1–” returns a byte length of 1662.
This could be interesting. Let’s peek at the response.
The application has responded to SQL statement by dumping a list of Credit Cards! We’ve successfully exploited a SQL Injection vulnerability presented in a SOAP service.
Default content discovery
The point of this categorization of vulnerabilities is to remind the reader that just as traditional web applications leave default content exposed that can be dangerous in nature, so can servers hosting web services.
As an attacker, you should make every effort to discover any hidden or unlinked pages that the developers or administrators may have forgotten to remove. It is common that you can find code that hasn’t been properly tested or coded and contains critical vulnerabilities. Additionally, you may discover files containing credentials or other resources that host sensitive information of some kind such as text documents or excel spreadsheets.
Typically you should run “at least” the following Google Queries (not all inclusive, you should experiment):
This query returns all files that match this extension for the site we’ve provided. When dealing with SOAP, it is highly recommend to add “filetype: wsdl” as a means to discovering additional WSDL files on the site.
Let’s not stop there. SVNDigger is a large list of directories and files that can be leveraged to discover default content. You can download the wordlists from – http://www.mavitunasecurity.com/blog/svn-digger-better-lists-for-forced-browsing/ and much in the same way that we’ve used intruder to load fuzzing lists we can do the same with the SVNDigger wordlists.
You may also choose to use the OWASP sponsored tool “DirBuster” and load the wordlists that way.
To reiterate, default content left exposed can lead to serious compromise depending on the sensitivity of the data discovered. Take care to spend time attacking this category of vulnerability. It may pay off in big ways.
Broken authentication and session management flaws
This category of vulnerability is the same for web services as it is traditional web applications. In fact, with the rise of mobile devices and web services stood up to support them, we are seeing these vulnerabilities present themselves in ever increasing numbers.
Per-request username and password submissions
Take for example SOAP requests that require basic authorization as seen in the requests to the WSDL above. The standard interaction between applications and user’s browsers when it comes to authorization is as follows:
- The user submits credentials
- The application validates credentials and sends a cookie
- The user’s browser stores this cookie value for that application
- Upon subsequent requests to the application from the user’s browser the cookie is sent.
With this model, even if the cookies are stolen there should be a finite amount of time before the cookie expires and if additional information is required to view or change a password the attacker may be out of luck.
Now take the plethora of mobile applications using basic authorization to communicate with a web service. Often you will see these mobile applications sending the basic authorization credentials with every single request to the web service!
If the user’s phone is on and connected to publicly accessible Wi-Fi and the web service isn’t using HTTPS this is the equivalent of sending credentials in plain text. Let’s observe how easy it is to decode basic authorization credentials.
Send the basic authorization string to Burp’s decoder
As you can see, the username is guest and the password is guest. Again, this is happening all the time in numerous of mobile applications.
Lack of account lock-out
A lack of account lockout after a certain number of incorrect password submissions is another very common weakness in web services that allows an attacker to guess a username and password combination. This weakness unnecessarily exposes the service to account compromise and should be taken seriously.
Weak password complexity
When you factor in vulnerabilities such as the one previously mentioned (lack of account lock-out), a weak password complexity requirement wherein a user can set their password to something as easy as the actual word “password”, you have a recipe for unauthorized account access.
As you can see, vulnerabilities already present and well documented in web applications are exposed in web services as well. The flavor or method for attacking may be slightly different but at the heart of the exploit lays the same root cause. Insecure coding practices coupled with a lack of secure design.
Hopefully this article has demystified the techniques used to identify and subsequently exploit weaknesses in not only web services but also SOAP web services for you.
Thank you for reading,