WEBVTT

00:00.590 --> 00:05.760
Hi, I'm Trey Cowan, I'm here with Brenda So, and we're security researchers here at Red Balloon Security.

00:06.000 --> 00:15.340
For the past year and a half, we've been working on this ATM, partially as a CTF target, but later as a research project.

00:16.040 --> 00:23.180
So this was something that kind of evolved out of the CTF work that we've done.

00:23.440 --> 00:39.560
So our agenda today, first we're going to talk about this ATM, what's involved in here, what's involved in a normal ATM, then we're going to talk about setting up our own payment processor, what we had to do to get that to work, and then our two vulnerabilities that we discovered.

00:39.560 --> 00:51.720
So the first in the remote management system on this device, and the second in its implementation of the extensions for financial services component, which we'll get more into later.

00:53.340 --> 00:58.960
So one of the things to note here is that, you know, there's been a lot of talk of ATMs in the past.

00:58.960 --> 01:09.880
One of the more famous ones was Barnaby Jack's talk ten years ago, where he demonstrated a bunch of cool things, jackpotting ATMs, installing rootkits.

01:11.340 --> 01:16.780
And you know, we kind of wanted to see how things improved in over a decade.

01:18.120 --> 01:21.560
And yeah, that's one of the ways we got here.

01:22.560 --> 01:30.460
The initial spark was, we were at a conference and accidentally unplugged an ATM as we were setting up our own table.

01:31.120 --> 01:33.940
And notice something funny on the screen when we turned it back on.

01:34.600 --> 01:37.200
This is the startup screen on the ATM.

01:37.560 --> 01:43.500
And you'll see here that this is running Microsoft Windows CE 6.0, which is quite an old version.

01:44.380 --> 01:47.560
And you know, at Red Balloon, we've worked with embedded devices quite a bit.

01:47.560 --> 01:51.160
And so there are people here who know quite a bit about Windows CE.

01:51.160 --> 01:54.300
So we thought it would be an interesting target to start tearing into.

01:56.420 --> 01:59.720
Now you'll see these ATMs all around the city.

02:00.060 --> 02:02.020
Our city is Manhattan.

02:03.240 --> 02:07.700
In things like bodegas, gas stations, street corners, anywhere.

02:08.160 --> 02:09.920
They're a fairly common ATM.

02:10.780 --> 02:14.260
And you know, we thought we may as well get this one.

02:14.260 --> 02:15.540
So we did.

02:15.540 --> 02:17.760
We got our own ATM shipped to our office.

02:18.480 --> 02:22.780
In fact, we're up to, I believe it's five ATMs now.

02:23.320 --> 02:27.680
Three of this larger ATM, this is the Halo 2.

02:27.680 --> 02:34.940
And then two of a smaller ATM that is actually able to go on a flight with some modifications.

02:35.100 --> 02:37.480
So it's easier to take around to conferences.

02:38.800 --> 02:44.240
So one of the things we want to do on our CTF was teach people about, you know, card technologies.

02:44.240 --> 02:49.460
We got people to interface with the EMV chip, magnetic stripes on the card.

02:50.580 --> 03:00.140
And just any way that you can think of to interface with this device in ways that you wouldn't normally be able to interface with something.

03:00.140 --> 03:05.800
So that was cool to be able to, you know, create a ecosystem around that.

03:06.100 --> 03:09.680
So we actually had this at the IoT Village last year.

03:10.080 --> 03:12.400
This is the leaderboard, the final leaderboard.

03:13.540 --> 03:15.180
And those are real cash payouts.

03:15.180 --> 03:17.240
So we paid everyone in $2 bills.

03:17.520 --> 03:19.680
It was quite a fun experience.

03:21.200 --> 03:26.500
So this is the smaller ATM that we took around, the MX4000W.

03:28.460 --> 03:32.540
So it's almost able to be taken on a flight, but not quite.

03:32.540 --> 03:36.080
You have to take out the cash dispenser in order to get it to be underweight.

03:37.820 --> 03:40.860
This is the case we took it in.

03:41.320 --> 03:45.900
There's actually a number of times we've taken it on flights for quite a bit of money.

03:46.680 --> 03:48.800
And also across international borders.

03:48.800 --> 03:56.300
So we took it to Canada one time, which was quite a struggle to get through border security.

03:57.060 --> 04:00.240
And it ended up not being the thing they gave us the hardest time about.

04:00.240 --> 04:04.940
They were more concerned about the T-shirts we were importing into the country to give away.

04:04.940 --> 04:08.440
So we registered as importers.

04:09.140 --> 04:14.500
So there was a lot of people that I want to thank for the work in the CTF that we did.

04:15.160 --> 04:21.740
Alex, Alex, our CEO Ong, Brian, Jatin, James, Rafi, and Tim.

04:22.780 --> 04:26.720
This was a lot of people helping, a big group effort.

04:26.720 --> 04:28.580
So thank you guys for that.

04:31.170 --> 04:36.230
One thing you need to be able to understand about the ATM industry is there's generally two market segments.

04:36.230 --> 04:38.930
The first being retail and the second one financial.

04:38.930 --> 04:51.430
Retail is generally more focused on cost and being appealing to people who just want an ATM on their property to be able to give to their customers, let them get cash out of it.

04:52.430 --> 04:56.050
Just any time you need cash to appear out of thin air.

04:56.350 --> 04:58.150
The second one is financial.

04:58.150 --> 05:03.770
That one's generally more focused on being more secure and more up to date.

05:03.770 --> 05:10.170
Those are much larger ATMs often, and you generally won't find those except in a bank.

05:10.470 --> 05:18.550
Most of these ATMs run Windows, and there's a number of manufacturers, but this is one of the most common ones that we found.

05:19.870 --> 05:21.550
So how does an ATM work?

05:21.550 --> 05:25.210
You insert your card, some magic happens, and then cash comes out.

05:26.170 --> 05:28.310
Well, there's a lot of moving components here.

05:28.870 --> 05:35.890
Firstly, it's a vault with some holes in it, notably the Ethernet cable coming out the back, though not all ATMs have that.

05:36.850 --> 05:38.890
Some actually use a cellular connection.

05:40.010 --> 05:41.630
So this is our ATM.

05:42.190 --> 05:46.410
There's two components to it, two compartments.

05:46.650 --> 05:54.090
The top section, which is a little bit lower security in terms of the lock, and the bottom section, which actually contains the cash.

05:55.270 --> 06:07.810
The top section, you'll see, has the receipt printer, card reader, pin pad, and also the main CPU and any network connections in it.

06:07.810 --> 06:14.250
The bottom component has the cash dispenser, which works with the cassettes.

06:14.250 --> 06:21.010
So the cassettes will actually hold all of the cash, and the cash dispenser obviously dispenses that.

06:21.010 --> 06:23.710
So there's two separate sections there.

06:24.610 --> 06:35.110
And in fact, the key for the top section, as Barnaby Jack mentioned 10 years ago, all the keys for the tops of the ATMs are the same.

06:35.110 --> 06:49.170
So you can't trivially get to the bottom of the ATM where the vault is, because there's different keys there, and then there's also an electronic lock, which has a numeric code.

06:49.170 --> 06:55.470
However, the top section only has a key that's commonly available.

06:55.470 --> 07:08.310
So when we originally got the ATM, one of the problems we had was our intern actually locked the key inside of the ATM, which is possible to do, because this thing automatically latches when it's closed.

07:08.310 --> 07:23.250
So we went and actually 3D printed a key that we used in the top of the ATM, because all the keys are the same, and we were able to open it, retrieve the real key, and continue on our way.

07:25.070 --> 07:27.550
Again, most of these devices run Windows.

07:27.550 --> 07:34.470
This one specifically runs Windows CE 6, which is quite old in terms of operating systems.

07:35.410 --> 07:39.030
This was released before Barnaby Jack's talk.

07:39.030 --> 07:46.650
There's a lot of modern protections missing from it that you would expect in a device that literally holds thousands of dollars.

07:49.490 --> 07:55.110
So when we opened up the ATM, we were greeted with this main circuit board.

07:55.570 --> 08:04.110
It has an HDMI, USB, Ethernet, and interestingly, a dial-up connection, so you can hook this up to a phone line and set things up that way.

08:04.550 --> 08:07.750
And then connections to the cash dispenser and receipt printer.

08:08.710 --> 08:16.030
So immediately looking at it, there's HDMI and USB, so can we just hook up a monitor and keyboard and get something going with it?

08:16.390 --> 08:20.230
Well, unfortunately, there's no Explorer shell that pops up with this.

08:20.650 --> 08:25.110
It's all in this kiosk mode application, winatm.exe.

08:25.410 --> 08:31.170
So our initial attempts to interface with it through a keyboard actually completely failed.

08:31.510 --> 08:33.530
The keyboard didn't work at all.

08:33.870 --> 08:36.050
Even caps lock didn't work.

08:36.050 --> 08:51.650
And the reason that that would happen is there's actually no driver for the keyboard built into this operating system image, which is actually very smart, because there's no situation really where you'd need a keyboard on this device.

08:51.810 --> 08:54.510
The pinpad is not treated as a keyboard.

08:54.510 --> 09:02.810
It's all about reducing the attack surface area there, so you can't just hook up a USB rubber ducky and run some bad scripts.

09:04.130 --> 09:13.390
So I'm going to hand it off to Brenda now to talk about, since we couldn't interface with it through a keyboard, what we actually did to work with this device initially.

09:16.240 --> 09:17.020
All right.

09:17.020 --> 09:24.100
So on the main port, we found these very suspicious pads, and on the back, around the same location, there are these resistor pads.

09:24.100 --> 09:27.280
So we suspect that this might be JTAG.

09:27.380 --> 09:28.760
And it turns out it is.

09:28.760 --> 09:31.300
It is a standard 10-pin ARM connector.

09:31.300 --> 09:35.140
We do need to solder some pull-up, pull-down resistors on the back.

09:35.140 --> 09:44.400
But after we do that, we're able to connect it with JTAGulator, identify it as JTAG, and use a JTAG debugger afterwards to interface with the ATM.

09:44.920 --> 09:46.260
So that's good.

09:46.380 --> 09:50.980
The next step is to dump the flash in order to get the firmware from the ATM.

09:50.980 --> 09:53.920
Now, on the ATM, the firmware is stored on the NAND flash.

09:53.920 --> 09:58.560
As you can see inside the little red box, it's 48 pins and a service mount.

09:58.560 --> 10:01.300
So it's pretty painful to rip out from the board.

10:01.300 --> 10:08.880
But we did desolder it at one point, and we used the SuperPro, which is a flash reader-writer, to read and write to the flash.

10:09.000 --> 10:12.200
We did it a couple of times, but eventually the board died.

10:12.300 --> 10:19.620
The board just can't handle that many times of soldering and desoldering, and we did rip out some pin pads, and we cannot recover it afterwards.

10:20.260 --> 10:22.020
So at that point, we're kind of panicking, right?

10:22.020 --> 10:23.860
Do we need to buy a new ATM?

10:24.040 --> 10:32.720
No, not really, because we found out that we can just go online and buy the main board at $400 a pop at atmpartmark.com.

10:32.720 --> 10:39.600
So we bought a few main boards, and they did work, but we don't want them to break again.

10:39.700 --> 10:42.900
So this time, second try, let's be more resourceful.

10:42.900 --> 10:46.660
We think maybe there is someone who did some reverse engineering and put them online.

10:46.660 --> 10:51.660
Maybe the firmware is already online packaged nicely, but it could also be behind some paywall.

10:51.660 --> 10:52.700
We don't know.

10:52.820 --> 10:57.420
But with enough Googling, we found out that the firmware is actually publicly available.

10:57.500 --> 11:01.020
Now, Trey mentioned the two versions of ATM that we got.

11:01.020 --> 11:04.460
It turns out that they both share the same firmware update.

11:04.460 --> 11:08.800
So we only need to download it once, and we start looking at it.

11:08.800 --> 11:11.260
So in the firmware update, there are three main files.

11:11.260 --> 11:21.680
The bootloader, nk.bin, which is where the kernel and other kernel libraries are stored, and most importantly, a master.zip file, where all the application binaries are.

11:21.680 --> 11:32.180
This is where the ATM executable is, it's where the libraries that the executable uses are, and it's where all the audio files, the JPEG that is used by the ATM are.

11:33.080 --> 11:35.060
And we look at the application binary.

11:35.060 --> 11:41.060
The exported entry in the application binary still has their names on it.

11:41.060 --> 11:46.120
So from a reverse engineer's perspective, it gets pretty easy to figure out what each function does.

11:46.120 --> 11:53.440
So for instance, if you want to figure out the dispense money functionality, you just find a function that is called dispense.

11:53.440 --> 12:00.320
Or if you want to figure out how the receipt printer works, you find another function called printReceipt.

12:00.380 --> 12:02.720
So that's a win for us, right?

12:02.720 --> 12:07.420
So with this firmware update, we tried our first firmware modification attempt.

12:07.420 --> 12:13.780
We didn't do anything fancy, we just tried to change the please wait while loading screen to please wait while pwning.

12:13.780 --> 12:18.120
However, when we changed that one character, we got stuck on the boot up screen.

12:18.580 --> 12:20.120
Now why does that happen?

12:20.120 --> 12:26.580
That's because in this firmware update, the manufacturer enabled Microsoft code signing.

12:26.600 --> 12:31.200
It is used to ensure that the software has not been corrupted by third parties.

12:31.200 --> 12:37.800
And in our case, our application binary is assigned with a certificate that is named MX5300CE.

12:38.260 --> 12:45.040
Now, at that point, we don't really know where the certificate is, and we don't really know how the verification process works.

12:45.040 --> 12:50.240
So in order to figure out the digital signature, we have two ways to do it.

12:51.500 --> 13:04.280
Either we take the time, reverse engineer the code signing algorithm, create our own certificate, resign everything, or we just find where the certificate verification function is and return true.

13:04.780 --> 13:10.260
So in order to do that, we need to take a deeper dive into how the kernel files and the kernel is structured.

13:10.900 --> 13:15.980
As mentioned before, there is this file called nk.bin where the kernel is.

13:15.980 --> 13:24.480
So that file is packaged in something called a bin.fs format, and within a bin.fs format, there are these records.

13:25.100 --> 13:29.560
In one of the records, that's where the kernel and the libraries are.

13:31.020 --> 13:36.980
We took out the record, and we started trying to figure out how that binary works.

13:37.020 --> 13:40.020
In that binary, there is the Windows CE header.

13:40.020 --> 13:40.940
It's pretty standard.

13:40.940 --> 13:51.060
You have your magic byte, you have your start address, and more importantly, there's a pointer to the ROM HDR structure inside a binary.

13:51.060 --> 13:54.320
This structure has some very interesting information.

13:54.780 --> 14:02.040
It has the physical start address, it has the physical end address, number of files, but more importantly, it also points us to the module entries.

14:02.620 --> 14:10.660
With that table of contents, with the ROM HDR structure, we figure out where nk.exe, which is the kernel, is.

14:10.660 --> 14:17.240
We figure out where the library is inside the binary, and we're able to parse out the kernel and the libraries.

14:17.240 --> 14:21.620
We use a tool called eimgfs to extract the files.

14:21.620 --> 14:33.180
And we figure out that although the application binaries are signed, since in this version of Windows CE, the kernel is used to verify the application binary, the kernel itself is not signed.

14:33.320 --> 14:38.920
We found a file called filesys.dll, which checks for certificate verification.

14:39.280 --> 14:44.200
Now, this is part of the control flow graph of the certificate verification function.

14:44.200 --> 14:48.320
We figured that out because there's a string, literally, that says, search verify.

14:48.640 --> 14:56.840
And as we're analyzing the control flow graph, we realize that every successful operation would return a number 4 to the caller.

14:57.620 --> 14:58.820
So, here's what we do.

14:58.820 --> 15:07.180
Instead of returning an error code on other paths, we just modify to always move the number 4 to r0, which is the return register in ARM.

15:08.060 --> 15:14.560
And after we patch filesys.dll, we package the whole thing, we successfully bypass signature verification.

15:14.980 --> 15:20.340
And from then on, we're able to modify our firmware and add our own custom code to the ATM.

15:21.080 --> 15:25.780
So, here's a video of the ATM having custom code on it.

15:25.780 --> 15:34.800
As you can see, we press a button and we printed out a small receipt, like a portrait of the ATM, so we think it's kind of cheeky.

15:34.800 --> 15:36.140
So, that's why we did it.

15:36.380 --> 15:37.480
So, that's good, right?

15:37.480 --> 15:43.800
We got firmware modification working, but now it really has to work as an ATM.

15:43.960 --> 15:47.200
And throughout this process, we found some very interesting stuff, right?

15:47.200 --> 15:50.460
So, firstly, this is a very old device.

15:50.460 --> 15:51.740
It's a pretty slow device.

15:51.740 --> 15:53.900
And each update takes around 20 minutes.

15:53.900 --> 15:58.840
We have to sit there and babysit the ATM as it's updating and manually punching the settings.

15:58.980 --> 16:01.620
We also found a lot of peculiar commands.

16:01.620 --> 16:10.060
So, for instance, within 5 seconds of the loading screen, if you hit clear, left, right, clear, clear, cancel, you can clear the settings on the NVRAM.

16:10.340 --> 16:19.440
Or if you hit enter, clear, cancel, 1, 2, 3, it would bring you to a password prompt, which brings you to the operator screen where you can change the settings on the ATM.

16:20.560 --> 16:22.740
So, we figured out the firmware update process.

16:22.920 --> 16:23.880
We're pretty good now, right?

16:23.880 --> 16:25.120
We have JTAG.

16:25.120 --> 16:28.420
We have the firmware itself with some debugging symbols.

16:28.560 --> 16:31.980
We have an understanding of how the firmware update process works.

16:31.980 --> 16:35.280
We are able to modify, add, and remove executables.

16:35.760 --> 16:37.060
One last hurdle.

16:37.060 --> 16:39.760
It keeps on getting stuck on the whole screen.

16:39.760 --> 16:42.080
Like, we got stuck on this screen for a while trying to connect something.

16:42.080 --> 16:44.140
What is it trying to connect to exactly?

16:44.820 --> 16:52.640
So, we did some digging, and it turns out that the ATM is actually trying to connect to a service called the payment processor.

16:52.960 --> 16:55.620
Now, there are these big card networks that issue a card to you.

16:55.620 --> 16:59.460
So, for instance, it could be your MasterCard or Amex or Visa.

16:59.460 --> 17:08.820
And when you put in your debit card into the ATM and try to draw money out, there is a middleman called the payment processor that would help the ATM connect to these card networks.

17:08.880 --> 17:15.180
So, there are different kinds of protocol for communication between the ATM and the payment processor.

17:15.180 --> 17:18.360
But the one that we looked at is called the Triton Protocol.

17:19.300 --> 17:23.280
Now, the Triton Protocol is a request-response communication protocol.

17:23.280 --> 17:30.480
There are four different types of communication pairs, but the most common ones are the configuration pair and the transaction pair.

17:30.540 --> 17:32.920
We did find the documentation online.

17:32.980 --> 17:38.660
However, it is a preliminary specification, and it is very out of date, so some of the information is wrong.

17:38.660 --> 17:42.880
And we needed to use Wireshark to figure out the correct request-response format.

17:43.300 --> 17:44.380
So, this is how it works, right?

17:44.380 --> 17:48.880
When you first boot up the ATM, it tries to connect to this payment processor.

17:48.880 --> 17:59.980
And the payment processor, once it receives a request, it sends back a response having some important information in it, such as the surcharge amount that it is going to take on the ATM.

18:00.540 --> 18:07.720
And for subsequent transactions, it would send a balance inquiry or withdrawal transaction code.

18:07.720 --> 18:15.140
So, the ATM would send a packet to the payment processor, having the card number, encrypted PIN, withdrawal balance if you are withdrawing money.

18:15.140 --> 18:26.460
The payment processor takes that packet, talks to the network, talks to different card networks, and returns whether you can successfully withdraw money or not with a success-slash-error code.

18:26.840 --> 18:29.680
So, you might think, this information is pretty important, right?

18:29.680 --> 18:31.720
So, is that information encrypted?

18:31.720 --> 18:33.560
And the answer is yes.

18:33.560 --> 18:36.140
It is encrypted with SSL or TLS.

18:36.140 --> 18:44.260
However, this is an option, which means that operators can actually opt out not to use encryption for Triton traffic.

18:44.260 --> 18:47.500
However, the PIN numbers do have an extra layer of protection.

18:47.760 --> 18:51.280
And most use triple DES for encryption.

18:51.900 --> 18:53.220
It is pretty standard triple DES.

18:53.220 --> 18:55.900
It uses two keys, K1 and K2.

18:55.900 --> 18:59.760
So, the PIN would be enclosed in its own padding.

18:59.760 --> 19:04.700
The ATM encrypts it, sends it to the server, so the server would decipher it.

19:06.240 --> 19:08.380
So, triple DES is a block cipher.

19:08.380 --> 19:10.120
It is a shared key protocol.

19:10.160 --> 19:12.260
And the setup is actually pretty interesting, right?

19:12.260 --> 19:18.980
So, when a technician comes to your store or restaurant to set up the ATM, it would punch in two keys.

19:18.980 --> 19:22.140
And these two keys are XORed together to form a master key.

19:22.320 --> 19:27.520
Now, the server also has knowledge of this key, but it is not the final keys used to encrypt the PIN.

19:27.920 --> 19:29.300
So, this is how it happens.

19:29.300 --> 19:35.560
Once the technician punches in the key, both the ATM and the payment processor would have a copy of the master key.

19:36.320 --> 19:39.940
The ATM would tell the payment processor, hey, I'm using triple DES.

19:40.780 --> 19:51.500
The payment processor would acknowledge it and encrypt two other keys, which is the final K1 and K2, with the master key, and send the encrypted pair of keys back to the ATM.

19:51.780 --> 20:00.180
The ATM decrypts K1 and K2 with the master key, and those two keys would be used to encrypt your PIN number.

20:00.460 --> 20:14.720
So, when someone enters their PIN on the ATM, the PIN is encrypted with K1 and K2, and that encrypted PIN gets sent over, and the payment processor would decrypt it with K1 and K2.

20:15.500 --> 20:28.940
So, after we understand the Trident Protocol, how the PIN encryption scheme works, we wrote a server, a Trident Protocol server, put it on a Raspberry Pi, and connect it to the ATM, and the ATM is finally functional.

20:38.970 --> 20:46.710
So, one of the first things you want to do on a device like this that's hooked up to a network is to see what surface area it exposes in terms of open ports.

20:48.150 --> 20:49.870
So, that's what we did.

20:49.870 --> 20:53.030
We actually found eight open ports on this device initially.

20:53.230 --> 21:03.870
The first two are the Windows CE web server, the default web server that's built into all Windows CE images, if that option's enabled, running on this device.

21:03.910 --> 21:10.510
When you actually pull it up, it's just the default web page that gets returned.

21:10.510 --> 21:17.970
So, likely this was something that just wasn't removed from the image as it was being built.

21:19.630 --> 21:24.690
Interesting aside is that you'll find a lot of Windows CE devices on the Internet.

21:26.690 --> 21:44.930
There's a couple of queries you can run to look that up, but especially something as old as Windows CE 6.0 on the public Internet would be a concern, ATMs, I haven't seen many, if any, ATMs on the public Internet.

21:45.450 --> 21:47.150
Mostly other devices.

21:48.690 --> 22:01.870
So, this second port, or I guess third port that we found here, the 5555, was a bit puzzling at first, but we realized it was the remote management system default listening port.

22:01.870 --> 22:11.030
So, that's something that you use to update the ATM, to administrate it, to check balances, that sort of deal.

22:11.530 --> 22:13.270
So, that's what that port was.

22:13.710 --> 22:15.950
And then we had these last five ports here.

22:15.950 --> 22:20.930
So, these were ones that we didn't quite know, ones that we weren't able to figure out easily.

22:22.110 --> 22:35.770
So, we tried connecting to them, but for quite a while we just weren't able to get any results from it, or send any data and have it be acknowledged.

22:36.710 --> 22:44.670
So, we'll come back to that in a bit, but first I'm going to hand it off to Brenda to talk a little bit more about RMS and what remote management system does.

22:46.810 --> 22:49.010
All right, so what is RMS?

22:49.010 --> 22:54.550
So, RMS stands for Remote Monitoring System Service, Remote Management System Service.

22:54.650 --> 23:00.390
However you want to call it, it is a service that lets customers control the collection of ATM remotely.

23:00.530 --> 23:09.310
So, the customer can use this service to update the firmware on a bunch of ATMs, check the amount of money left, download the transaction history from the ATM.

23:09.790 --> 23:14.630
Now, this is an optional service, meaning that users can enable or disable it.

23:14.630 --> 23:20.630
The default port for RMS is 5555, which corresponds to Trey's port scan.

23:21.990 --> 23:28.510
So, in RMS it uses the ATM's ID and the custom password for verification.

23:29.530 --> 23:34.690
So, when we were reverse engineering it, we realized there was close to no documentation on RMS.

23:34.730 --> 23:42.930
So, at the end we needed to use a combination of Wireshark, Ghidra, and AIDA to figure out a communication protocol, and the process took around two weeks.

23:42.930 --> 23:45.930
But we eventually got it, right?

23:45.930 --> 23:51.810
So, the RMS packet is pretty standard, you know, you have a start by a terminal, but there's like an LLC at the end.

23:51.810 --> 24:01.270
The more interesting part is like the encoded data, where that part is actually obfuscated with an extra table hard-coded in the binary.

24:02.490 --> 24:05.970
And this is actually not the first time someone looked into RMS.

24:05.970 --> 24:12.190
In fact, in Barnaby Jack's talk in 2010, he jackpotted an ATM via a vulnerability in RMS.

24:12.190 --> 24:18.670
And since then, and we looked at his report, it turns out that the RMS packet structure is still the same.

24:18.710 --> 24:21.210
Obfuscation techniques didn't really change.

24:21.650 --> 24:29.590
And in his talk, he found out that a malformed packet can lead to authentication bypass and eventual firmware modification.

24:30.150 --> 24:33.430
So, the service should be secure now, right?

24:33.730 --> 24:35.290
Well, let's put it to the test.

24:35.290 --> 24:42.070
We want to use a fuzzer to fuzz it, but we don't want to set up memory or emulate some Windows CE functions.

24:42.070 --> 24:45.250
So, we used BooFuzz, which is a network fuzzer.

24:45.290 --> 24:55.070
It takes a lot of heavy work out of it, so we only needed to define the protocol in code, and BooFuzz would take it, test different inputs, and do the rest.

24:55.590 --> 24:58.250
So, we did get around five to six crashes.

24:58.290 --> 25:09.390
And when we're analyzing the crashes, we see that every time when we send a really large packet, so any packet more than 10 kilobytes, the device would crash and reboot.

25:09.390 --> 25:15.190
Interestingly, this happens regardless of whatever password or ID you send to the device.

25:15.590 --> 25:24.770
And with JTAG, we figured out that a crash happened in this function called RMSProcessTCP in the library that controls the RMS communication.

25:25.530 --> 25:29.770
So, let's take a deeper dive into this function and how it works.

25:29.930 --> 25:44.090
So, at first, the function accepts any incoming connections via TCP, receives the packet, decrypts it with the XOR table, verifies the ID and the password, parses the command, closes the connection.

25:44.350 --> 25:50.850
And the problem happened at this stage, where it received the RMS packet and decrypts it with the XOR table.

25:51.450 --> 25:54.250
So, what exactly went wrong?

25:54.290 --> 25:57.690
Well, it turns out it's basically a buffer overflow.

25:57.690 --> 26:05.150
In the function that received the RMS packet, it copies the TCP packet over to a global buffer without any bounce check.

26:05.550 --> 26:11.730
And what it did is that this eventually overrides a function point it has called when the application exits.

26:11.950 --> 26:16.290
And this copy happens before any kind of terminal ID or password verification.

26:16.710 --> 26:28.670
So, the consequence is, as long as you understand the packet structure, as long as your packet structure is sound, the buffer overflow could happen, and you can write shellcode in your packet to lead to arbitrary code execution.

26:29.930 --> 26:32.010
Now, what can the attacker do?

26:32.010 --> 26:40.470
We were investigating it, and we realized that most DLLs are paged out as the application exits, except for the functions that control the NVRAM.

26:40.610 --> 26:47.530
And in this device, in this ATM, NVRAM is pretty important because it basically controls anything on the admin screen.

26:47.530 --> 26:50.250
It stores all the settings on the ATM.

26:52.210 --> 27:02.450
So, for instance, an attacker can point the ATM to the malicious server because within the NVRAM, it stores the IP of the payment processor.

27:02.450 --> 27:04.970
You can change the denomination of the ATM.

27:04.970 --> 27:13.370
So, for instance, if your ATM is supposed to have $20 bills, you can change the denomination to $1 bills in order to extract more money from the ATM.

27:13.670 --> 27:18.970
And let's go to a demo of the RMS vulnerability.

27:20.030 --> 27:22.510
All right, so we have our ATM here.

27:22.510 --> 27:26.570
It has RMS running on the background.

27:26.650 --> 27:31.890
So, now Trey is going to send a packet over to the ATM.

27:31.950 --> 27:35.610
And as you see here, it says remote monitoring system is in progress.

27:35.650 --> 27:39.870
Trey sends a malformed packet over, but it still looks fine here, right?

27:40.050 --> 27:44.510
So, now let's say I'm the operator, and I need to perform a firmware update.

27:44.510 --> 27:52.750
So, I will do and declare cancel 1, 2, 3 in order to go into a password prompt.

27:52.850 --> 27:56.050
And then I put the operator password in.

27:56.270 --> 27:58.750
That brings me to an administration screen.

27:58.750 --> 28:00.610
You can change a bunch of stuff here.

28:00.610 --> 28:08.010
But right now, since I'm doing a firmware update, I'll go into system setup, system control, software update.

28:08.010 --> 28:10.510
Yes, I want to do a software update.

28:10.630 --> 28:13.830
So, this is where the shellcode gets executed, right?

28:13.830 --> 28:24.130
Because as the application exists cleanly, the function pointer that we overwrote would be called, and that would execute our shellcode.

28:25.590 --> 28:30.670
In this specific demo, we set the shellcode so that it would point...

28:30.670 --> 28:42.830
instead of pointing to the Raspberry Pi with the Triton protocol running, it would point back to Trey's laptop, which has the Triton server running.

28:43.970 --> 28:44.490
Right .

28:44.630 --> 28:51.770
So, as you see here, it just updated successfully, and we needed to wait a few seconds to reboot.

28:52.030 --> 28:54.430
Once again, this device is pretty slow.

28:54.430 --> 29:03.090
As you can see here, it's going to take a while for it to go past the boot screen and go back into normal operation again.

29:03.090 --> 29:10.490
So, one interesting thing to note is that as we're writing the shellcode, we need to figure out where the functions are.

29:10.630 --> 29:21.910
And as Trey said, since this is a pretty old device, it's a pretty old version of Windows CE, a lot of the modern protections against... a lot of modern protections and binaries are implemented.

29:21.910 --> 29:27.670
So, for instance, we don't see any ASR implemented in the binary through JTAG.

29:27.670 --> 29:46.330
So, what we're able to do is that once we use JTAG to figure out where all the libraries are in one boot process, the next time we rebooted those libraries, the executables would be loaded back into the same location, which makes the process of writing shellcode easier.

29:47.070 --> 29:57.210
And as I mentioned before, the shellcode would point the ATM to Trey's computer, and how it does is modify some settings on the NVRAM.

29:57.210 --> 30:00.630
The NVRAM controls all the settings, right?

30:00.630 --> 30:02.950
It controls whether SSL is turned on or off.

30:02.950 --> 30:07.390
It controls where the ATM is pointing to.

30:07.490 --> 30:11.490
And it's also a pretty simple function to reverse engineer.

30:11.490 --> 30:18.350
It takes two numbers, and each pair of numbers would point to, for instance, whether SSL is turned on or not.

30:18.350 --> 30:26.010
It would point to the IP string of the payment processor host.

30:26.810 --> 30:30.650
So, as you see here, now it's initializing.

30:30.970 --> 30:31.990
It takes a while.

30:31.990 --> 30:35.690
It's loading, and it's trying to interface with the peripherals.

30:36.470 --> 30:39.510
It prints out a receipt whenever it reboots, right?

30:39.510 --> 30:47.890
So, it's just saying, oh, test printing, okay, and it prints out a version of the printer within the ATM.

30:51.230 --> 30:53.530
It takes a while to initialize.

30:53.530 --> 31:08.510
But after initializing, you would see that instead of pointing to the payment processor on the Raspberry Pi, it would point to the Triton server that Trey is running on his computer.

31:09.170 --> 31:10.610
It makes a lot of noises, right?

31:10.790 --> 31:12.170
It's trying to print something.

31:12.170 --> 31:14.950
It's trying to make sure the cache dispenser works.

31:15.650 --> 31:18.210
All right, now it's trying to connect to the host.

31:18.210 --> 31:26.270
And as you can see on Trey's computer, our malicious payment processor is working.

31:26.270 --> 31:27.690
It's interfacing with the ATM.

31:28.130 --> 31:30.290
So, I have a card here.

31:30.490 --> 31:33.430
It's one of the cards that we printed in-house at Red Balloon.

31:33.590 --> 31:35.250
So, it has track 2.

31:35.250 --> 31:41.270
So, it has tracks here, and track 2 is where the interesting information is stored, is where your card number is stored, in fact.

31:41.490 --> 31:44.850
So, let's say I'm a customer, and I wanted to check my balance.

31:47.750 --> 31:50.150
It takes a while.

31:50.650 --> 31:52.650
I hit English.

31:53.110 --> 31:54.490
It asks me to enter a PIN, right?

31:54.490 --> 31:55.910
It can be anything.

31:56.950 --> 31:57.910
Enter.

31:58.510 --> 32:02.050
And let's say I want to inquire my balance on the ATM.

32:03.710 --> 32:06.530
Let's say I want to check my checking.

32:06.530 --> 32:08.330
No receipt, thank you.

32:08.550 --> 32:14.630
And it is connecting to the host, although it says an ineligible account on Trey's computer.

32:14.630 --> 32:20.610
So , you can actually see the expiration date of the card and the card number itself.

32:22.710 --> 32:23.610
All right.

32:23.830 --> 32:24.930
Back to you, Trey.

32:33.160 --> 32:33.680
Cool.

32:33.680 --> 32:35.280
So, we just saw the RMS demo.

32:35.660 --> 32:49.540
And now I want to talk a little bit more about interacting with this device and what we had to do to actually get things to work on it, since we didn't have a keyboard or any HRD device to really interface with it.

32:49.540 --> 32:53.400
So, we kind of had to actually take a look at this.

32:53.400 --> 32:56.440
So , there's an ActiveSync, probably, port on here.

32:56.440 --> 32:58.280
But we couldn't quite get that working.

32:59.040 --> 33:06.180
ActiveSync is the way you would work with Windows CE devices to interface with them on a desktop computer.

33:06.400 --> 33:11.800
But we couldn't get that working, so we actually compiled our own tool.

33:12.440 --> 33:13.500
This is Windows CE.

33:13.500 --> 33:14.860
It's a standard platform.

33:14.860 --> 33:20.480
How difficult should it be to be able to just compile something to work on it?

33:21.580 --> 33:24.080
Well, the caveat here is that it's Windows CE 6.0.

33:24.080 --> 33:27.540
So, this was released in 2006, initially.

33:28.140 --> 33:33.620
So, we actually had to go all the way back to Visual Studio 2008 to get this really going.

33:34.900 --> 33:39.800
It's quite an old IDE, but we knew it worked well under Windows XP.

33:39.800 --> 33:50.740
So, what we were able to do with this IDE was actually build some C-sharp applications, get them to run on the .NET Framework, which is actually on this device.

33:50.740 --> 33:53.160
It has a .NET Compact Framework on here.

33:54.560 --> 34:07.020
However, it's fairly old, so a lot of examples for C-sharp code, if you're not incredibly familiar with it initially, you can't just copy-paste off of Stack Overflow to get things working on here.

34:08.220 --> 34:10.260
A lot of useful features are missing.

34:10.480 --> 34:14.600
But, in the end, we did get an application working on here.

34:14.820 --> 34:23.680
So, we really wanted an application for our CTF to be able to have a web server that people could connect to, to interface with the ATM.

34:25.080 --> 34:26.440
So, this was the start of that.

34:26.440 --> 34:29.120
We actually popped a dialog box here.

34:31.340 --> 34:39.820
And, you know, we could have used the built-in web server on this device that you saw in the port scan earlier.

34:39.820 --> 34:46.780
However, there wasn't any DLL or any capabilities for any sort of dynamic content or scripting.

34:46.900 --> 34:49.700
So, that would have been a bit difficult to actually get up and running.

34:49.700 --> 34:59.500
So, instead, we created our own web server, which was difficult in its own right, because HTTP primitives aren't in the .NET version we're using.

34:59.500 --> 35:04.140
So, we had to build things on top of just straight TCP sockets.

35:04.140 --> 35:11.540
But , with some good examples, we fast-forwarded a bit and had a web server working, which is what you see here.

35:11.980 --> 35:15.580
So, this is our test setup.

35:15.580 --> 35:24.760
This is a device emulator running the .NET code and displaying our CTF web page there.

35:26.940 --> 35:30.800
So, for launching on Startup, there's a number of ways we could have gone about this.

35:30.800 --> 35:41.280
But, again, we didn't quite have any way to interface with the ATM at this point, since we are trying to compile our own tool.

35:41.660 --> 36:02.280
So, in order to be able to launch that tool, to be able to probe how the device works, we actually used the debugger every single time we wanted to run it, and hijacked the startup process, the call and create process, and pointed that towards our custom server.

36:02.920 --> 36:09.640
So, we could reverse the startup procedure and do the proper way through registry edits, which can be a bit difficult on Windows CE.

36:09.640 --> 36:36.340
But, what we ended up doing was actually just taking the executable that was on here, that would normally be launched, called winatm.exe, renamed it to something else, and then named our own executable winatm.exe, and then launched the original process that would normally be launched as a child process of our server.

36:37.720 --> 36:45.560
So, we've got this C-sharp code running, it's all good, but what would it take to get some native code running?

36:45.560 --> 36:47.480
So , let's actually dig into it here.

36:49.940 --> 37:00.800
What we ended up needing to do was use Visual Studio 2005, going even further back, and install a number of different packages to actually get this to work.

37:02.040 --> 37:20.300
It was quite a pain, but in the end it was actually quite worth it, because in one of the most amazing Microsoft things I've ever seen, you can click through a wizard and, from scratch, build an OS image, which is a pretty amazing concept.

37:20.300 --> 37:28.320
You're clicking little checkboxes to enable or disable different features, and change how things are built into it.

37:28.800 --> 37:38.360
So, from that we were able to actually see different DLLs that would normally be on the ATM, like the keyboard driver and things like that.

37:39.600 --> 37:44.860
But by this point, we had already gotten our web server up and running.

37:45.440 --> 38:02.570
We've got it launching every boot, and so we built all these commands to be able to interface with the device, check out what processes we're running, how to remove registry keys, how to remove files, any sort of thing we'd need to really dig in and research it,

38:02.880 --> 38:05.520
and have fun diversion while we did it.

38:05.520 --> 38:12.560
So, this was actually... we found a build of Doom for this device, and we actually got it up and working here.

38:12.560 --> 38:19.260
This was an Easter egg in some of our earlier CTF challenges to be able to find this.

38:21.400 --> 38:30.160
But it ended up... I'm not sure if it was eating up all the memory, but the system would just randomly reboot partway through after Doom had been launched.

38:30.160 --> 38:37.960
So, we had to remove that for further CTF challenges, but it was fun to get it up and running while we had it.

38:37.960 --> 38:43.680
And despite being a fairly slower and older ARM core, we were able to run this.

38:46.000 --> 38:56.760
So, one of the things we did next was take a look at the registry, see how things were configured, and look for any clues of things that might be interesting on this device.

38:57.360 --> 39:12.100
So, one of the things that we initially found that was kind of familiar were some of these keys, and you might take a look at them and recognize those numbers from some of the ports that were open earlier.

39:13.280 --> 39:30.840
And even more interesting, if you take a look at the key name, it's a little concerning, because you start to think, maybe this cache dispenser is somehow related to this open port on 8004.

39:31.140 --> 39:32.920
So, what is this?

39:32.920 --> 39:34.520
What are we taking a look at here?

39:34.520 --> 39:35.780
Well, here's a hint.

39:36.160 --> 39:38.520
XFS is what this is.

39:39.060 --> 39:42.640
Not the file system, the money one.

39:42.740 --> 40:05.400
And XFS is this standard platform for financial devices that exposes this sort of middleware, where you can have a Windows application send a command that gets passed through these layers of abstraction, and go to the service provider, the service provider being the thing that actually is able to interface directly with the devices.

40:05.800 --> 40:16.860
So, this allows you to build things in sort of Lego's fashion, so you can swap out different components of your system, theoretically.

40:17.440 --> 40:24.400
You know, swap out different cache dispensers, swap out different card readers, and there are all these standard different devices that you can put on here.

40:25.460 --> 40:35.620
So, you'll see the cache dispenser, you'll see the ID card unit, which is reading your card, pin pad, things of that nature are all in here.

40:37.060 --> 40:38.560
So, what is XFS?

40:38.560 --> 40:39.860
Where does this come from?

40:40.040 --> 40:47.040
It started out as a Microsoft thing, where they wanted to create the standard platform for Windows for financial devices.

40:47.680 --> 40:59.120
They seem to have really succeeded, because this is, you know, kind of one of the industry standards for how you would set up an ATM or any other financial device.

41:00.020 --> 41:16.260
And so, Microsoft handed it off to SIN, the European Committee for Standardization, who is actually the maintainers of the standard now, and you can go on their website and find all of these documents detailing how devices are hooked up in XFS.

41:17.140 --> 41:25.520
So, for example, this is the cache dispenser device description document here.

41:25.660 --> 41:28.360
So, this is great for people building these devices.

41:28.360 --> 41:59.980
It creates a fairly open ecosystem that allows manufacturers to be able to swap out different things and have that, which also causes an issue in terms that it's a fairly homogenous platform that allows people with very little understanding of ATMs to actually be able to create some fairly portable malware to be able to use on these different devices.

42:00.200 --> 42:07.420
That takes advantage of the XFS interface, and we've seen a number of different pieces of malware that use this.

42:08.620 --> 42:12.880
So, going back to the ports, again, this is something XFS-related.

42:13.300 --> 42:20.940
So, we see those numbers there, and what I did was go through and map out.

42:21.640 --> 42:33.940
You can see that after logical services, there's auxiliaries, card reader, cache dispenser, and then there's also the device class, which is what XFS would call that device.

42:33.940 --> 42:38.500
IDC and CDM for the cache dispenser.

42:38.700 --> 42:47.980
And created this mapping showing which registry key corresponds to which device class, which corresponds to which port.

42:48.860 --> 42:57.940
So, you can see here again that this is, you know, the device classes are the standard XFS designations for these types of devices.

42:58.820 --> 43:01.200
So, what does this tell us?

43:02.200 --> 43:03.520
There's open ports.

43:03.740 --> 43:05.720
They're related to XFS somehow.

43:06.900 --> 43:09.900
Can we make it dump out some money?

43:11.060 --> 43:16.240
Well, the problem again is, you know, we can connect to these ports, but we can't get anything out of them.

43:16.240 --> 43:19.260
We don't see any traffic, and we don't know what to send into them.

43:19.760 --> 43:20.920
So, let's sniff it.

43:20.920 --> 43:39.760
You know, let's see if there's anything on these ports, even on the local network interface on here, that's listening and sending messages to see if we can take that and use it to build our own messages or replay them.

43:39.760 --> 43:52.460
The problem here being that this is a Windows CE device, and you can't just download Wireshark for Windows CE because, as this very helpfully points out, there is no Wireshark for Windows CE.

43:53.980 --> 44:08.320
So, Windows CE does have packet capture capabilities, but it's not built into this ATM image, and I didn't really want to take the time to try and figure out how to port it to this ATM image.

44:08.320 --> 44:11.660
So, the easiest way to do this ended up being JTAG.

44:12.460 --> 44:31.780
And the way, the plan of attack here was to intercept the socket create calls, get the handles for them, and then map those handles to the different services, intercept socket sending receive calls, and look at the buffers, and save all that traffic, and then acquire some cutlets.

44:31.780 --> 44:50.360
So, what we did was went through, found where these registry strings were being read, and from that we were able to figure out which socket creation call corresponded to which different device class.

44:50.900 --> 45:09.080
And here you'll see that this is where we're hooking the send and receive functions in Winsock to be able to look at the buffer and take the data that is either being sent or the data that has been received, save that to a file, and take a look at it.

45:09.080 --> 45:15.380
So, this is all in Ladderbock, this is a JTAG debugger that we use, and it's great for scripting like this.

45:16.620 --> 45:19.980
So, as you can see here, we have a number of packets that came in.

45:19.980 --> 45:21.920
Some of these are send, some of these are received.

45:21.920 --> 45:27.640
So, it's just a bunch of binary blobs, and there's not very much that we can easily recognize in there.

45:27.940 --> 45:34.780
There is the US dollars string in the packet in the lower right, but it's nothing immediately obvious.

45:34.780 --> 45:39.240
So, first thing we tried was, can we just replay one of these packets?

45:39.660 --> 45:50.140
Because we know, we were doing actions on the ATM as we were capturing these packets, so we can roughly correlate what might have been sent to the cache dispenser to cause it to dispense cache.

45:51.080 --> 45:59.080
So, yes, we can just replay and send out some cache from the cache dispenser.

45:59.080 --> 46:05.860
It was actually fairly straightforward to be able to do that, and then you can see we dumped out some cache here.

46:07.040 --> 46:14.100
It was no need to learn how all the structure works, no need to learn how to work with these fields.

46:14.100 --> 46:22.360
You can literally just take this packet that you've seen, replay it to dispense cache, and that was fairly straightforward.

46:23.660 --> 46:33.500
So, that worked in the case where we just wanted to dispense the same amount of cache, but what if we wanted to dispense as much cache as possible over and over?

46:33.940 --> 46:50.080
Well, after looking at this dump for a while, we were able to figure out some patterns and see the structures in there, especially after looking at the XFS documentation, and we created some scripts that allowed us to parse these packets and then see what was in there.

46:50.080 --> 46:59.880
So, for example, here we have a packet where it's the result of reading card that's been put in the ATM.

46:59.880 --> 47:06.180
So you can see the card number there is 555555555555555555555555.

47:06.180 --> 47:07.980
That's the track 2 data.

47:10.560 --> 47:18.020
And we have these fields here that might not be immediately obvious, this command code, notably.

47:18.220 --> 47:28.360
So if you look in the XFS documentation, you can see that there is this concept of a device class, or service class, and then a service offset.

47:28.360 --> 47:35.660
So the service class being 2, that's multiplied with 100 to get the service offsets, which is 200.

47:36.720 --> 47:42.420
And then all of the commands are some offset from that base number.

47:42.420 --> 47:54.080
So 207 is this specific command for idcard read raw data, which corresponds to what we saw here, which is 207, which is hex cf.

47:54.320 --> 47:57.640
You can see the result of that read raw data there.

47:59.060 --> 48:11.000
So we modified this to work with the structure for the cache dispenser packet and, you know, pumped up the amount of cache that we're dispensing.

48:11.340 --> 48:21.140
And yeah, we were able to run that and we can actually run any XFS command on this device if we send it to the appropriate port.

48:21.140 --> 48:31.440
So kind of in retrospect here, you know, pro tip, if you're using TCP sockets for IPC, don't listen on 0.0.0.0.

48:31.540 --> 48:38.140
And if you're creating a networked device, at least do a port scan before you ship it.

48:39.340 --> 48:46.680
So we want to run through the XFS demo here and show you this machine spitting out some cache.

48:48.840 --> 48:49.420
Cool.

48:49.420 --> 48:50.820
So we have the ATM here.

48:50.820 --> 48:53.520
And I'm going to run the script we wrote for XFS.

48:53.520 --> 48:59.040
And you should see that the command is being injected directly into the XFS middleware.

48:59.040 --> 49:02.180
So none of this will actually show that cache is being dispensed.

49:02.740 --> 49:05.880
So if I run the command,

49:12.660 --> 49:14.680
it's going to dump out some cache.

49:15.540 --> 49:17.620
So this is just going to continually happen.

49:17.620 --> 49:20.620
It's going to keep dumping out $2 bills over and over again.

49:21.140 --> 49:26.640
And yeah, this is the result of a computer just being on the same network.

49:26.640 --> 49:34.900
You know, you can grab the Ethernet cable behind it and send a single packet to the ATM and it will dump out a load of cache.

49:43.030 --> 49:43.470
All right.

49:43.470 --> 49:45.250
Thank you for coming to our talk.

49:45.250 --> 49:48.490
And be sure to join us in our Q&A afterwards.

