Hey everyone! My name is Niclas Hilgert and today I would like to talk about forensic analysis of micromobility solutions. And in case you’re wondering, what exactly is the micro mobility solution? Something like this: an e-scooter, for example, or an e-bike or a bike. And we’re going to talk about the solutions which you can rent, not about the personal things which you can buy, but about the things you can rent, which you can find on the street anywhere.
And usually if this was a real event, I would actually ask who of you has already used such an e-scooter, and I would guess the majority has, maybe just to try it out once, but they’re probably also some people who have not. I certainly have over the past years: this as an example. And in my hometown, there are even multiple providers of these scooters.
There’s for example Spin, there’s Lime, there’s Tier, there’s Next Bike for bikes, as I mentioned, and you can find these scooters and bikes almost anywhere, on the street, maybe sometimes even in strange places: I think the last one was pulled out of a river. But there are of course more providers than the ones mentioned so far, and I don’t even think that this list is complete, but in the paper and during the rest of the presentation, we’re going to focus on Lime, Voi, Tier, Next Bike, and there’s going to be a little bit of Spin. It’s not in the paper, but we included it here. And for all of you who have never used such an e-scooter, don’t worry, we’re going to follow this roadmap today which will explain the steps that it takes during a ride of such an e-scooter and how you can successfully hopefully finish such a ride!
And while we follow this road map, we’re gonna also take a look at these steps from a forensic point of view and take a look at what kind of data may be interesting for us. What kind of…what thoughts we can make during these steps.
So if you want to get started, the first thing you actually need to do is register for one of these providers and almost all of them offer the possibility to register by phone number. So you get an SMS code and then you’re registered. Lime and Spin for example, also offer you to register by email address. And after you’ve done that, you can put in maybe some other kind of personal information, and this is what is interesting for us: the first thing is user data. So it could be the phone number or the email address of a user (or if we’re talking about the forensic context, the suspect), maybe some username or real name. This is definitely some kind of information, which is interesting for us. And this is also the first step on our way to ride an e-scooter.
The next thing would be: enter some payment information. Because almost all of the solutions we took a look at require payment information even if you have some voucher or other kind of stuff you need to put in some credit cards, PayPal information. This is also interesting for us because this is of course linked to a person. And you can also check if the credit card has been used for such a transaction for Tier, Lime, or whatsoever.
Those are our first two kind of artifacts: user data and payment data. And if we want to get to these artifacts the first thing would be: we’ve got the phone, we take a look at the local storage of the phone. So during this presentation, there’s not enough time to take a closer look at each of these categories and steps for each of the providers, so we’re just going to take a look at some of these as an example.
And our first example is Lime. So on the left side, you can see the directories Lime has when it is run on an iPhone (or an iOs device) and we’re not going to focus on caches or cookies because they are basically operating system dependent, but we’re going to talk about the app-specific data that we found. That doesn’t mean that there is not any information and caches, there probably is, but we did not focus on this this time. Now the interesting files in this case are the LimeBike.sqlite database, and also we included the property list .plist file at the bottom because it also contains mainly app-specific data.
Now let’s take a closer look at the database. We can see a bunch of tables and now we’d like to find the information about the user and the payment, so we will take a closer look at the user and payment method table. And as you can see here there’s one entry for our user, which includes the mail address, the phone number, the username (which is “Lime Rider”: it’s always by default “Lime Rider” for Lime), and some internal identifiers. But also the currency used by the user.
And in payment method, we can find one entry for PayPal. There’s not a lot of information here, it just says PayPal. But during our tests, we have found out that even deleted methods in some cases, stayed inside of the database even if they disappear within the app. So this was as an example, Lime. The other providers did not really have much kind of user or payment data stored on the phone. At least they did not have any database like Lime did. But if you want to know more about this, you can of course read it in the paper!
But because of this, because the local storage was a little bit disappointing, we thought about, okay, where else can we get data from? And of course then these providers require some kind of possibility that you can log in from any device, they have some cloud storage. And if you want to access the cloud storage, you need to identify yourself and perform some kind of authentication. So there has to be some kind of maybe token that you need to authenticate yourself also to say, log in.
We then took a look at the local storage and tried to find out where to find these kinds of tokens. Now Next Bike as an example also has a .plist file on iOS, and this .plist file, if you decode it this way contains a so-called login key. It also contains the phone number as you can see here, but we are now interested in the login key. And this is actually the thing for Next Bike, which you need to access the user’s data, as we will see later.
Voi, for example, does it in a different way on iOS, they make use of the apple keychain, which developers can use to store some data as passwords, cryptographic keys and stuff like this. And luckily there is the so-called keychain dumper, which you can find on GitHub, which can be used to extract data from the keychain. Of course, if your iPhone is jailbroken.
For Voi the interesting entry looks like this. At the bottom, we can see adjacent that token (if you’re interested on the right side, you can see it decoded as well). And this is what you need to log in, or authenticate against the Voi API. Now I would like you to focus on the – what is it called? – accessible attribute in purple now, which says in this case “accessible always”, which is pretty interesting because this actually means that you can access this keychain item without unlocking the phone. So you actually just need to jailbreak the phone in that case. Lime on the other hand stores their information and the keychain as accessible after first unlock. This was just an interesting fact.
Now that we know where we can find some tokens, yeah, we can actually just get them and create a connection to the API and see what kind of information is stored there. Sometimes as I just said, you need a jailbroken phone or root access on Android devices, and sometimes this is just not possible. So there’s also the possibility to generate a new token. As we’ve seen at the beginning, most people register, or most providers offer the registration by using your phone number. And if you’ve got access to a person’s SIM card, for example, you can easily just generate a new token and then you can access the cloud storage. So you do not need any password and…access the data.
And what kind of data can you access? So we’re going to take a look at the user data we’ve seen before, but now we’re going to access it using the API. And this can be done with using this endpoint, for example, and you get a bunch of information back, which of course includes your mail address, and in this case also my first name and also my last name (which is not marked in orange) but also my phone number and maybe some additional information, which you may not see directly in an app, for example, a number of verified or that I provide a payment and stuff like that. Same for payment data, there’s also for Tier an API for that which contains information about PayPal, the mail address, and also the provider, which is used, maybe this is also some useful information during an investigation. Again, this was only an example, all of the information in more detailed way can be found in the paper.
Okay, now we registered, we put in our credit card details, we would like to ride a scooter. Next step would be: we need to find one. And this is a pretty basic feature of these apps that you can see a map and see where the scooters are, or bikes are, located right now. And for us, it may be interesting if a user used this feature to see: what were some nearby scooters? Where was this person moving? Maybe when was the last time they searched for scooters and stuff like that? Unfortunately I have to disappoint you, this is some real time information. So usually this is not stored on the device, that wouldn’t make a lot of sense. And we found it in caches, but as I said, we did not put our focus there. But there’s no database which stores the scooters you’ve seen in the past.
So this is usually done using an API and for Tier, for example, it is this, and then you get a list of all the scooters around you. And this contains, for example, the code, we’re going to see this later as well, it is stored on the handle, it’s something like a scooter ID, and it also contains the license plate of the scooter, at least here in Germany (I’m not sure about other countries). And there’s also this interesting attribute called state, which is active for all of the scooters returned by Tier, it is active, which makes sense, because you don’t want to see any out of order scooters on your map.
Now, if there’s an active state, that’s probably also a state, which is not active and we found another API, which enables you to just query a scooted by its identifier. And this identifier as you’ve seen is just a six digit number, but actually this API returns the same information, but you can also use it for scooters, which are not active. Now, if you just use a for-loop and query all of these possible six digit numbers, you end up with a whole lot of data and you can use this data for various purposes, for example, create such a table which tells you: how many scooters of Tier’s fleet are right now in an active state or have been stolen? And after 10 months you can repeat this and then you end up with a table, which you can interpret by yourself.
Anyway, the actual only local data we found about this was also again with Lime in its database and the table “bike”. And that had exactly one entry, which was of a scooter, which we had used previously during a ride. It was the same information returned by the API, if you get an overview, but just only for the bike we used at that time, which also include the coordinates the bike had, and also I think, Lime only includes the last three numbers of the license plate (is what they call it, it’s not really the license plate which is physically attached to it, just some kind of identifier as well).
Now we found a scooter and we would like to unlock it and start our ride, which is our next step. You’ve already seen the picture of the QR code on Tier scooters, and usually all of the providers use QR codes and some kind of identifier underneath the QR code. And then it depends, maybe you can only scan the QR code, or maybe you can enter the ID in order to start the ride. And what we are interested in is the so-called “physical presence”, is what we call it, which is actually the fact, do I need to be next to the scooter or bike in order to start the ride? Or is it possible for me, for example, to start a ride in Sydney? Or to activate a scooter in Sydney?
Actually, if you take a look at this summary, you can start the ride by using the QR code or the vehicle code. And you can just, if you already own a database of QR codes, which you’ve used maybe previously then you can of course unlock the scooter as well. Same holds true for any other kind of ID you may enter. So if you’ve at least used the scooter once you can, of course unlock this specific scooter all over again. But the more interesting question is if I haven’t used the scooter before, is that maybe possible? And for most of these, it was possible. I think Lime was the only one which used some kind of obfuscation on the map, so you couldn’t really find the same scooter again, because it only had the last three digits of the license plate, so that it could be a different one. But of the others use their unique identifier for a scooter, so you could unlock them after you’ve used them once, or maybe not at all. In some way, for example, to get such an ID, maybe not how to do it: if you use the Spin app, you can see the last four digits of the scooter. So this means you cannot unlock it if you don’t go to the scooter, but if you take a look at the actual data, which is returned by the API, you can see that there is the attribute “last4”, but there’s also the vehicle ID, which is “last4” plus the other numbers I need to unlock the right. So for Spin as you see, this is pretty easy to unlock the ride without any physical presence.
Now we’ve unlocked our ride, and we would like to do the most fun part: ride the scooter! This may not be information which is completely interesting during a forensic analysis because this usually happens after the ride happened, but we thought it’s interesting to include it here. So things that may be interesting are: locations during the ride, or speed or, other things. And if you remember, we saw the API request for Tier for specific scooter ID, and it also included, like GPS coordinates. Now this makes sense because you need to see where a scooter is on your map, when you want to find it during the overview step. The thing is these coordinates are also accessible when a scooter is being used, and they even update in real time. So what you can do is pretty easily track any scooter and track any person which passes you, for example. You can also do this over a longer period of time and create some kind of heat map of your city to see where most of the people ride or park their bikes or whatsoever. And this was actually not only possible for Tier, it was possible for all of these providers, except for Next Bike: they did not provide any real time data of their bikes.
Okay. Now, we had fun, and we would like to now lock and end the ride, which is the last step, and it’s pretty similar to the unlocking phase: it may require physical presence. Now all of the scooter providers we took a look at did not require that, so you could also lock the scooters using the app or API from anywhere. And as you can see the Next Bikes in our city have this kind of frame lock, which you need to close after you’re finished your ride, so you need to be there to finish it. And then we finished our ride, now you’re a successful…what is it? I wanted to say “Lime rider”, but you’re a successful micromobility solution rider! And now maybe after some months, when you did a few trips, you want to take a look back and see what you’ve done.
And this is possible because all of these solutions offer some kind of ride history to show you your trips of the past. And this is actually in our opinion one of the most important information during a forensic investigation, because it actually tells you where somebody was at which time, at which point in time and also what vehicle was used. Yeah, as I said, all of these providers offer this kind of ride history, but with different kinds of information. Lime, for example, if we use the API to get the data returns a lot of data about the the trip. In orange, you can see temporal information like start and end time, in green, the last three digits of the of the bike that was used, and in red you can see a link to an image, which basically I hope everybody can see: it shows you the path which I rode, which is pretty accurate, so the GPS data’s pretty good. The problem here is you cannot really tell what is the start and what is the end point. So to solve this problem, we can use the polyline. It’s a Google polyline, which is simply a way of encoding some kind of coordinates. And if you decode it, you get the buff result. And in yellow, now you can restore the order of the coordinates. And in yellow, you can see now the start point of the trip.
This image of the trip can also be found on local storage (again, thank you, Lime). For Tier, for example, it’s a bit different: if you use the app, you can only see at which time was the ride. And if you also click on the link you get an invoice, because Germans like invoices and Tier is a company based in Berlin! But you do get any overview about the places you visited, but if you use the API to do so, it’s actually an API end point, which is not in the app. It is…I really forgot how we found it, but it is there. And if you use it, you can get almost the same information as we saw with Lime: temporal information and information about the vehicle use and also GPS coordinates. If you take a closer look now, you may notice that there are two kinds of locations: ne of them is the customer location, and one of them is the vehicle location. And then we asked ourselves, what exactly is the difference? Like, is there data provided by the customer? And is this also maybe true for other providers, like the GPS data, which we can see in the ride history? Where does it come from?
So for Tier, we tested this and it actually is, as it says: there’s a location sent by the phone, and there’s a locations sent by the vehicle. And you can see them both here. So if there was some kind of fake GPS use on the phone you would be able to detect this kind of mismatch. For Next Bike, which only stores start and end location of a ride, this data comes directly from the bike itself, so you cannot really spoof it. For Voi, the user can actually provide the end location of a ride and the start location is the location where the scooter was on the map. And while we took a closer look at this, we found out that there is an API end point for Voi (I hope they fixed it) which enables you to actually put scooters anywhere you like. So you can also fake the start and end location of a Voi trip, and for Lime you can actually fake everything: we saw that there’s like the complete trip start, and you can fake all of these coordinates, they all can be user provided, so this results in something like a world trip for €1.20.
So in short, Tier and Next Bike are more or less reliable: you cannot really spoof the data. And Voi and Lime, not really reliable, you can spoof the data, so you should be careful where you see it.
Now, as a conclusion during our ride on the micromobility solution roadmap (and now it’s finished) what have we learned? We’ve seen that there’s not really app-specific data in the local storage of devices or at least not exclusive data. You can also find it and get it using the API. And also it’s pretty hard to maybe jailbrake the phone and access this data. So it may be a better way to access data by using the API, and this can be done by somehow getting the token, and this could be having SMS access or mail access, generating a new token, accessing the API and then access the data without using the phone.
And the last thing we learned is that you should definitely know the origin of your evidence as we’ve seen with the GPS data, because in some cases, may be pretty easy to spoof this. Now, thank you very much for your attention. The code we used to access and extract data from the micromobility providers APIs will be published on GitHub, and if you’ve got any question, feel free to ask. Thank you very much.