How to ride the bus for free (hackers need not apply)

Mon 01 May 2017 By Rumyana

Mysterious button on bus-ticket machine

(Image by Cory Doctorow licensed under CC BY 2.0)

It's another sunny Scottish morning at CriticalBlue and we're having a chat about the latest and trendiest of Android vulnerabilities and the fundamental security flaws that have come up in our pentesting activities. Every now and again they might be enabled by a race condition that's been in the Linux kernel for nine years but more often than not, they lurk in the apps themselves, storing secrets in plain text on devices or sending unencrypted data over the network. We all know we shouldn't be doing it, and if we didn't, we could learn how to equip our code with basic security in a few stack overflow questions' time, so why do embarrassing things keep happening?

My theory is we're too busy. It seems to happen by definition: a development team never has the time. They always want to improve on something and add some more features and migrate to the latest versions of their tools and refactor and automate everything they can. The various methodologies that the software community has been trying to apply have led to some progress, notably hours of giffy entertainment such as this piece:

Fixing a bug in production.

Now try and apply this to security.

Quick quiz: when was test-driven development first introduced?
a) The year the Java 2 standard came out
b) When buying Google for one million dollars sounded like a bad idea
c) 1999
d) All of the above

It's 2016 and we're getting to it. The future is now, stand-ups are old news, in with the daily plank meeting, and teams have started talking about security-driven development. Can we afford to wait until it comes into fashion?

Sure, the battle for security will always be about one side catching up with the other. We know there are hackers, we know there will always be hackers, but I think we can all agree that the important question here is: how much of a hacker do I need to be to get free bus tickets for my trip home from work?

Do I need to know networking?

The ā€˜sā€™ at the end of an https isn't enough. It's a good first step. It will stop everybody and their grandmother from being able to listen in on all traffic. Say your bus ticket app sends sensitive information over just http: install mitmproxy on your computer and ProxyDroid on your phone, give it your computer IP, click "enable proxy". Buy a ticket and read all those juicy secrets in the request. Sometimes the app developers will have saved you some time by calling them things like "secret". Maybe they didn't realise their quick prototype has ended up in production because someone else was deploying it. Maybe they committed some files they didn't mean to. Maybe they neglected to thoroughly check yet another new version of one of the many frameworks they use. Or maybe they're just really nice people.

But maybe it's all encrypted: oh no, they're using https!

Do I need to know cryptography now?

Probably not. Go to on your phone and tap on the little blue Android. Any secrets in the clear now?

Https will make an app more secure than some; apps that apply SSL certificate pinning are miles ahead. Unless the server you're contacting verifies the app's certificate, it's relying on the Android device to verify it with the help of its trusted certificate authorities - and those can be replaced. We want to know what the app and server are talking about, but it's all jibberish. All we need to do is convince the server that we are the app, sniff the information we need, then pass it on to the real app so that normal operation can continue. We want an authority that will certify, falsely, that we are indeed the app. We're in it for the free ride so we don't mind installing mitmproxy's root certificate to our phone in order to read some juicy secrets.

Now that you've managed to steal some secrets, you can put them to good use letting you ride the bus for free. Secrets might be used for simple request authentication that will spit out a valid ticket number or image of some sort. Yes, that happens. But what if your bus app is a little bit more sophisticated and you can't get to a valid ticket by sending back what you've just received? Maybe your app uses server responses to generate tickets, or the rest of what you need to send to receive tickets. Good news everyone - you can get to the app's code and inspect it. It's running on your phone after all.

Your phone stores the app's apk somewhere that probably is /data/app/ All you need now is a usb cable and the adb tool. Install the Android Sdk, find the app name, then pull it out from the device onto your computer. A non-rooted phone will pretend you can't look there but will still allow you to get the app, you'll just need to find its name via the Android package manager. Now you have a shiny new apk which will tell you everything else you need to know, as soon as you decompile its executable (the dex file inside it).

Oh no, do I need to know bytecode?

Not really. Bytecode just makes more sense to decompile to, as these are the actual instructions used by Android's JVM during execution. You can get very similar results straight into Java by using unzip + dex2jar + jd-gui.

Do I need to know how to root my phone?

The things we talked about do not necessarily require a rooted phone, but you'd have a much jollier time with one. If you think anything is stopping you from rooting your Android device, please enjoy this minute and a half instructional video with 10 seconds of intro and 20 seconds of like comment and subscribe:

Some apps will try to check if a phone is rooted and refuse to work on one, but you can double-bluff them: there's an app for that. And if it doesn't help, something else sure will, as we've recently uncovered our true potential in the limitless supply of human ingenuity when faced with wanting to play Pokemon Go.

Do I need to know how to read?

Funny you should ask: No, there's video tutorials for that.

But none of this works!!

Maybe the app that's selling you tickets uses Approov. We have free trials (wink wink).

I can't be bothered to do any of this!

Fear not, for someone on the other side of the world may have done it for you. The same technology supports the travel smartcards in San Francisco, Turin and Vancouver, and the same framework may be in your app's backend that is in any other app that has been compromised.

It takes a day for two security researchers on the San Francisco subway in 2012. A year later, it is a slightly longer timeframe for two italian teenagers because the smartcards they're interested in are not quite the same as the first ones. These are white-hat investigations whose results were disclosed to the involved parties and carefully detailed to the larger community, contrary to any intention of enabling anyone to ride the bus for free.

Four years on and journalists are interested to know if the same hack would work in Canada - hint: the answer is yes. The minister responsible for transport expects that technological solutions are being applied as soon as an issue is discovered. Transit authority spokespeople are unconcerned because of the relatively small number of fraudulent tickets that have actually been detected.

And here is where the free-riding opportunity really lies, in the benefit-cost ratio that poked those security holes in the first place. For various reasons, security is often not quite as difficult to break as the people that have put it in place wish it were; but it's in sharing and collaboration that knowledge thrives, and ride-the-bus-for-free knowledge is no exception. With the ticketing app of the local bus company on your phone the possibilities are endless, and vulnerabilities abundant. Chances are that someone will eventually decide it's worth releasing an app that does it for you, so you can probably wait until it comes out. Or have they done so already and been more successful in staying low-key than you've been in finding them?

Category: General