Making it right, not just making it work Quality

How to Check Your Web App for Security Vulnerabilities

Learn how to pick locks with soapUI — so that your own web applications can be made more safe.

The day of release has arrived; everyone is happy. All reported bugs are fixed, all tests passed, and the servers are configured. The application starts its new life on the grid. Users enter their data, new content is being created. New features are added; new users are coming. Success!

Then, one sunny day, all hell breaks loose. The database is deleted, users identities are being sold, e-mails are missing, servers are not responding… You have been hacked. Your application’s security has been compromised.

It isn’t that your development team doesn’t care about making software secure. It isn’t that fancy new features are more important than mystical security. It’s that many developers don’t know how to go about checking their applications for security vulnerabilities.

Happily, some development tools can provide the expertise that developers and testers personally lack. Among them is the open source soapUI, a functional testing tool. The Pro version’s features include security scans that probe your Web services and web applications with the most common attacks – to ensure that your software is not a hacker’s toy waiting to happen. In this article I show you how to use soapUI to prevent the most common and most dangerous attacks as described by OWASP.

Our Scenario

Our target, for the purpose of this example, is McAfee Foundstone’s Hacme Casino, which the company calls “a learning platform for secure software development.” The (intentionally insecure) web application is a good candidate for a soapUI demonstration.

casino app

Analyze The Target

To begin with, let’s check out the casino site as it presents itself online by doing a View Source of this webpage:

view source

The highlighted part of this code is the login form. The user name and password are sent to the server as plain text with POST HTTP method to server action /account/login:

<form action="/account/login" method="post">

The Input parameters for username and password are user_login and user_password:

<input id="user_login" size="30" value=""/><br/>
<label for="user_password">Password:</label><br/>
<input id="user_password" size="30"/>

This is enough for a start. Now we can get to business.

Preparing Probing

Start soapUI and create an empty project; I named mine HackCasino. Add one test suite and one test case, with an HTTP test request to the login form:

I tried one dummy username and password, but as you can see it results in the response, “Login unsuccessful. Please try again.” Notice that the URL is http://localhost:3000/account/login which I set as the request URL. The method is set to POST. Also, I added two parameters: user_login and user_password.

It would be possible to use brute force to guess a username and password. I could use functional testing in soapUI for that, but it would require setting data sources, property transfers, looping, etc. Instead I use security testing in soapUI. Just create a security test and add Custom Security Scan:

Okay: Now lets configure it:

I used the option for auto parameter extraction to get username and password parameters, than added a small Groovy script to read passwords and usernames from my dictionary:

if ( context.getProperty("passwords") == null ) {
  context.setProperty("passwords", new File("passwords.txt").readLines())
  context.setProperty("passCnt", 0)
}
if ( context.getProperty("users") == null ) {
  context.setProperty("users", new File("usernames.txt").readLines())
     context.setProperty("userCnt", 0 )
}
def passwdList = context.getProperty("passwords")
def userList = context.getProperty("users")
def passwdCnt = context.getProperty("passCnt")
def userCnt = context.getProperty("userCnt")

parameters.user_login = userList.get(userCnt)
parameters.user_password = passwdList.get(passwdCnt)
if( ++passwdCnt >= passwdList.size() ) {
  context.setProperty("passCnt", 0 )
  context.setProperty("userCnt", ++userCnt )
} else
  context.setProperty("passCnt", passwdCnt)
if( userCnt < userList.size()  )
  return true
else
  return false

What does this do? It reads two files, usernames.txt and passwords.txt.  For each username it probes a password. Now all you need is a huge dictionary for usernames and passwords. Press play and relax.

Note that, unless you have some automatic way to recognize that you are logged in, you are doomed. You need to check each response manually. For this example it would be enough just to add an assertion that contains:

Script Understanding

The object context is available in most soapUI Groovy scripts, but only during test runtime. You can add or set the object properties to it with context.setProperty(<property name>, <property value>) and read its property with context.getProperty(<property name>). In this script it explicitly returns true or false as the result purely for readability reasons. The script should return true if there is more iterations to be done, otherwise false.

XPath and SQL injection

Almost always, web applications have a data tier in back. It happens, quite often, that inputs from text fields are directly put in SQL/XPath queries or the input is not checked correctly. The common scenario is like this:

SELECT * FROM our_secret_table WHERE field=<input_field>

If the application directly enters value from input_field without any checking or the checks do not do what they should, any string could be inserted there, even those which modify the SQL statement in a way that lets you gain access to the whole table. Perhaps this example is not the best, but wait — let’s see how this works on our casino.

First add SQL injection:

Notice that in the Advanced tab you see some common SQL injections. You can modify, delete, or add new ones to test for. Also add the same assertion as in the Custom Security Scan.

We can run SQL injection with the default configuration:

Notice that after the second request, the application stops responding. What happens is that the casino web application dies when for user_login ‘—is sent. This is a very serious flaw in the casino application (which is one reason it is a good one to experiment with). You can find more values in the default SoapUI configuration that break the casino.

When you remove all the injection strings that break the casino web application, the SQL test passes.

Now you can add some new options, your own injection strings. Lets add one more SQL injection string in the configuration: ‘) or 1=1-- :


As you can see from the log, when ‘) or 1=1—is inserted in the login name field, we do not get the expected response; something happened. Double click on this message to see details and to inspect the response:

It looks like we managed to login. To verify that this works, go to your browser and insert ‘) or 1=1— for the login name:

Wow, fancy hairstyle.

This means you can login as Andy even if you do not have his password. But what does that mean, exactly? I’m guessing from this behavior that when the username and password is passed to the application the SQL query appears like this:

SELECT * FROM users_tb WHERE (username=’<user_login>’
  AND password=’<user_password>’)

And when the injection is done it look like this:

SELECT * FROM users_tb WHERE (username=’) or 1=1-- AND password=’)

And that returns Andy. This is a very common and a very serious security flaw.

Cross Site Scripting Candidate

Before we talk about Cross Site Scripting (XSS) let’s investigate the page for transferring chips and money. Click on Options. You should see:

If you look at the page’s code, you see two interesting forms: transfer chips and cash out. In the same manner we used for the login screen you can easily compose requests for both of them:

http://localhost:3000/account/transfer_chips?transfer=<amount
  >&login[]=<user_name>&commit=Transfer+Chips

and

http://localhost:3000/account/cash_out?amount=<money>&account=
  <account number>&commit=Cash+Out

If you are logged in, you can click on any on those two links and they will be executed.

Ok, but now you wonder what to do with this? I now have access to Andy’s casino account. If other players transfer chips to Andy’s account, I could than transfer those chips to my account or send its value to my off shore account. Or maybe it would be better if they directly transfer money to my account?

Just make users click on these links:

http://localhost:3000/account/transfer_chips?transfer=1000
  &login[]=bobby_blackjack&commit=Transfer+Chips

Or:

http://localhost:3000/account/cash_out?amount=1000
  &account=11111-1111-111-111&commit=Cash+Out

Now I’m rich!

The first link works if Bobby is logged in and only if he clicks on it. The second one just needs that user to be logged on — and that can be accomplished if someone plants those links on proper places, such as in an e-mail scam. All you need is to send e-mail to Bobby with some appealing text (“Grand Casino Opening: Free nights at our five star hotel. Please confirm.” ).

The second link is a great candidate for a Cross Site Scripting Attack (XSS), a security flaw when an application allows malicious users to insert a script into its web pages. That script is executed when those infected pages are executed. So, if this casino application has some forum or an attacker knows about forums where these users hang out, the evildoer  could try to inject this URL or script that executes this URL.  Suppose the existence of forums or web applications where these users discuss casino topics. I would create a dummy user and post a message which would have a hidden script that transfers the cash.

To find a proper target for this I would use XSS Security Scan in soapUI:

In similar fashion, like the two previous security scans, SoapUI has predefined insertions but you could add your own. What is different from other attacks is that attacker goes after the server users, not the server itself. A response for request in that inserted attack will not necessarily have attack itself and you do not want to target yourself. That is why this Security Scan has a special assertion Cross Site Scripting Detection:

What is so special is that not only it checks response, but also you could enter a list of URLs that should be checked, or write a Groovy script that generates those URLs.

Tools

Share with your friendsJoin and Stay Current with the Community
JOIN RSS
About Robert Nemet
  • Steven Baker

    Good article. The email XSS is probably the most common risk these days IMO. Rarely people fall for the SQL anymore. Taking advantage of people’s authenticated sessions with XSS is certainly an easy one. There are ways of avoiding this (tokens combined with confirmation pages come to mind).

  • Daniela Vieira

    Great article! I liked a lot!

  • Anonymous

    effdsf

  • Anonymous

    I think application security is the last thing that developers think about when they are asked to work on a project… we have spoken on several points including security in software as part of its quality.

    If only enough developers would be educated on the OWASP top 10, we would probably have fewer incidents of complete databases being exposed on the net.

  • http://www.mazero.com/ Optimisation

    A useful guide. This kind of guidelines and teachings can help us to save more time to check the vulnerabilities of the security. Thanks for the post.

blog comments powered by Disqus