Introduction to Hacking Thick Clients is a series of blog posts that will outline many of the tools and methodologies used when performing thick client security assessments. In conjunction with these posts, NetSPI has released two vulnerable thick clients: BetaFast, a premier Betamax movie rental service, and Beta Bank, a premier finance application for the elite. Many examples in this series will be taken directly from these applications, which can be downloaded from the BetaFast GitHub repo. A brief overview is covered in a previous blog post.
In this post, we’ll cover network testing in thick client applications and how it’s performed on different architectures. BetaFast is written with a three-tier architecture.
- Tier 1: The client displays and collects data.
- Tier 2: Web requests are sent to a server where business logic is handled.
- Tier 3: A database server modifies and retrieves data for the application server.
Beta Bank is written with a two-tier architecture.
- Tier 1: The client displays and collects data.
- Tier 2: A database server handles business logic and performs data queries and modifications for the client.
One-tier architecture also exists, but it’s not applicable to this blog post because the client, business logic, and data storage are all on the same system. There can be more than three tiers, but the same methods and tools outlined below will apply.
One of the first things I like to do when I begin a thick client application test is see what’s actually happening on the network. And to do that, I use a tool called Wireshark to capture and filter network traffic.
In this example, I’m testing the Beta Bank vulnerable application. With a proper capture filter in place, I’ll typically begin by just sort of doing things in the thick client. I’ll submit forms, navigate through the app, modify data, etc. Then, I’ll look through Wireshark for anything sensitive.
- Is the database connection unencrypted?
- Is sensitive data, such as social security numbers or medical information, transmitted in cleartext?
At one point, I authenticated to the application with the username “blogger.” Searching through the packet list in Wireshark, the name “blogger” appears in a Login procedure. The fact that this is even remotely legible means that the database connection is unencrypted, and anyone with access to this network is able to read this information just as easily. Thankfully, the password appears to be encrypted, so a hacker won’t be able to access my account.
Or will they?!
Any form of a password sent from a client, whether it’s cleartext, hashed, or encrypted, should be treated as the password itself. Sure, the password is encrypted. But knowing and sending this value to the server will authenticate this user to the application. There’s no additional defense provided by only obscuring a parameter value and not securely encrypting an entire transmission. Another value observed through wireshark is the output parameter for the Login procedure – GUID. In an authenticated portion of the application, the procedures accept a GUID as a parameter.
This is what we in the business call a “session ID.” Armed with only this value, an attacker will be able to perform authenticated actions as the blogger user as long as the session remains active.
But even that is making things more complicated than they need to be.
In this example, I am the harbinger of revolution – a veteran of the computer who has had enough of the wealthy elite. While you were smelling the roses, I was sniffing the network. And I captured blogger’s username and encrypted password from that Login procedure.
Now, a tool like Echo Mirage comes in handy. Echo Mirage allows TCP traffic to be intercepted and modified. I can authenticate to the application with the username “blogger” and an arbitrary password, then intercept the packet containing the Login procedure.
The encrypted password can be changed to the value captured by Wireshark.
As soon as I send this request, I’m in. Let’s see how much money this big shot blogger has.
Hmmm. Perhaps this blogging thing is more of a hobby. Let’s see who else is banking with Beta Bank. Using the techniques from the previous post in the series, the Withdraw button can be enabled.
Wireshark shows that this function is sending a SQL query.
Echo Mirage can be used to directly modify the SQL statement. It can’t change the length of the packet, but the remaining SQL can be commented out.
The server responds with the Users table. The account connecting to the database clearly has excessive privileges, but we now have info on every user.
There’s any number of attack vectors now. There’s still much to explore and modify in the database. But The_Chairman sounds very wealthy and very elite, and their encrypted password is practically begging to be used.
Hackers – 1
Wealthy Elite – 0
Burp Suite is perhaps the tool I use most on the job. It’s invaluable for any application assessment that deals with HTTP requests and responses. If you haven’t heard of it or used it, there are going to be far more interesting guides out there than this on how powerful the tool can be.
If a thick client is built on a three-tier architecture, the network portion of the test will essentially be the same as testing a web application. First order of business is proxying the traffic. In the proxy tab of Burp, set up a listener on 127.0.0.1 and a port of choice.
Next, rather than proxying a browser through Burp, proxy the whole system.
There may be a lot of traffic that doesn’t belong to the application being tested. But this is the time for determining which requests are originating from the thick client. I only restrict the scope in Burp once I know the complete set of hosts the app is reaching out to. With BetaFast, I’ve determined the application is only sending requests to http://www.betafast.net:8080.
And now Burp can be used the same as in any web application test. Below, I sent a request to the Repeater tab and found SQL injection.
A lot of important things happen over networks, so make sure not to focus only on the client when testing thick client applications! What could Beta Bank and BetaFast have done differently to protect their systems? Well, a good amount. But here are a few examples:
- Encrypt database connections – Encrypted connections hide sensitive data from wandering eyes on a network. They also ensure that traffic cannot be modified as long as the encryption is implemented securely.
- Principle of least privilege – Since Beta Bank connects to the database as a highly-privileged user, an attacker has free rein of the database should an exploit be found. If the account connecting to the database had the least possible privilege, an attacker could not pivot beyond normal functionality.
- Salted and hashed passwords – Encryption is by its nature reversible. This will be highlighted further in an upcoming entry in this series.
- Authentication logic – The password being sent over the network should not be directly compared to the password stored in the database. Otherwise, the encrypted password doesn’t even need to be decrypted or a hashed password cracked. The password should be sent as-is in an encrypted transmission. The server then salts and hashes the password and compares the resultant value to the salted and hashed password stored in the database.
- Input validation and parameterized queries – Unlike Beta Bank, it’s not an issue that traffic can be intercepted and modified. The issue is that vulnerabilities exist in the way the application server processes input. Anything sent from the client should be validated by the server, and SQL statements should have parameterized queries.
As always, be sure to check out our GitHub for copies of BetaFast and Beta Bank. And be sure to tune in for further guides on hacking thick client applications!