Reverse engineering your mobile banking app

to make a PHP script that automates checking your balances

Posted by Christian Haschek on 2018-04-05
Never miss a post by liking this blog on Facebook

Our Austrian banks (seemingly) hate developers as they don't give you an API to check banking statements or balances. Soon there should be the new PSD2 Standard which will force all european banks to have an API but I didn't want to wait so long.

As a small business owner I always have to check by hand if customers have paid an invoice which is really annoying and error prone. I recently vented this to my brother in law who works for a (different) bank as a developer and he said:

"Does your bank have an App? Because if they do, they must have some kind of API which you might be able to use".

-- Brother in law

The Easybank.at app

I checked the Google play store for an app to Easybank and surely enough: They have one.

Screenshot of the easybank App

They have a very weird dial-like menu but when I log in I can see my statements so when my brother in law is right, they might have some kind of API (unless they just send JS and HTML. Let's see..

Man-in-the-middle attacking my own phone

MitM attack explanation by Norton
So now I want to log all requests coming from my phone and to the banking servers. The traffic is encrypted using standard HTTPS, that I'm sure of. I just need a method to bypass this.

This is where Burp comes in

The Burp Suite

Burp Suite logo
Burp Suite does exactly that. I use the community edition which lacks many features but will be enough for this project.

What's the plan? Burp creates a local proxy server that we'll connect our phone to and then Burp can read all traffic. Then we'll check for API calls and see if we can clone them with PHP.

But won't this just make certificate errors since we don't own the bank's SSL certificate? No, we'll get around that with our own CA certificate :)

After downloading and starting Burp with default settings, go to the Proxy tab, click on the sub tab "options" and edit the "Proxy Listener" to listen on all interfaces.

Setting the Burp proxy to listen on all interfaces

Step 1: Connect your phone to your proxy

First you'll need to know the IP address of your proxy server. On Linux/Mac type "ifconfig" in a terminal to find it. It will probably be something like "192.168.X.X" or "10.X.X.X.".

Next to to your wifi settings, edit the currently connected network and add the IP of your proxy in the field "proxy ip" and the port 8080 to the "port" field.

If your phone is different you might have to google around how to set the proxy on your version.

Step 2: Install Burps CA certificate

On your phone open your browser and go to http://burp/cert this this will lead you to Burps internal web server where you can download the certificate. On my phone after downloading I had to reneame it to "burp.crt" before I could open it.

Screenshot from the Infosecinstitute

I then was asked where to install this new certificate and what it will be able to sign for. I Chose "apps and browser" which will allow the certificate to be recognized by all Android apps (that don't validate certs themselves).

If that didn't work, ask Google how it will work on your version of Android

Step 3: Burp around to gather data

Now you're connected to your proxy and you have the proxy's certificate. Time to open the app and log in!

While doing something on your phone you might see that pages keep loading forever. That's because in Burp you'll have to allow every single request to pass to your phone.

Check the Proxy -> Intercept tab in Burp. It should turn orange to notify you that there is a request waiting. Just click on "Forward" for all requests until you're signed in, we'll check the logs later.

Do this until you're logged in the online banking and you're seeing some banking statements.

Let's check the data for API calls

In Burp go to Proxy -> HTTP history and check the data.

In my case I was very surprised to see this:

API call to the banking servers

Awesome they really have an API and it just sends XML to some SOAP connector and this is the response of the Server

Response of the Server

Awesome there is a field called "ServerSessionID" which then is added to every new call they make.

Could it really be that simple?

Yes it really was. I wrote this small PHP wrapper in 20 minutes. This enables you to get all your financial info form the servers and you could even implement generating payment requests that you just have to sign once with your TAN

Finished a script that can use the API for me

What about security problems?

Problem 1: Un-resettable ServerSessionID

The only thing that could remotely be called a security problem is that even after you log out, your ServerSessionID will stay active for at least 2 days (didn't test after that, might be longer).

But the damage you could do with this is still very limited since you can't use it to steal money but it might enable session hijackers to check your balances.

Problem 2: What I just did shouldn't have worked

The technique I was using with Burp and a custom CA shouldn't have worked because all banking apps and others that work with highly sensitive data shoud use certificate pinning where the app itself checks if the server has a valid certificate, and not the system.

This should have resulted in error messages when opening the app via the proxy. I tested it with other banking apps and all others I have tested showed me error messages and didn't let me log in.

Either way I now have the ability to automatically check my statements so I count is as a win :)


Tags: php | banking | reverseengineering | app | android | easybank
2.768

There are no ads on this (https enforced) blog. Please help me to keep it that way
1ChrisHMgr4DvEVXzAv1vamkviZNLPS7yx
0x1337C2F18e54d72d696005d030B8eF168a4C0d95