 Hi, I'm Trey Cowan, I'm here with Brenda So and we're security researchers here at Red Balloon Security. 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. So this was something that kind of evolved out of the CTF work that we've done. So our agenda today, first we're going to talk about this ATM, you know, 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. So the first and the remote management system on this device, and the second and its implementation of the extensions for financial services component, which we'll get more into later. So one of the things to note here is that, you know, there's been a lot of talk of ATMs in the past. One of the more famous ones was Barnaby Jack's talk 10 years ago where he demonstrated a bunch of cool things jackpotting ATMs installing root kits. And you know, we kind of wanted to see how things improved in over a decade. And yeah, that's one of the ways we got here. The initial spark was we were at a conference and accidentally unplugged an ATM as we were setting up our own table. And notice something funny on the screen when we turned it back on. This is the startup screen on the ATM. And you'll see here that this is running Microsoft Windows CE 6.0, which is quite an old version. And you know, at Rebellion, we've worked with embedded devices quite a bit. And so there are people here who know quite a bit about Windows CE. So we thought it'd be an interesting target to start tearing into. Now you'll see these ATMs all around the city. Our city is Manhattan. And things like bodegas, gas stations, street corners, anywhere. They're fairly common ATM. And you know, we thought we may as well get this one. So we did. We got our own ATM shift to our office. In fact, we're up to, I believe it's five ATMs now, three of this larger ATM. This is the Halo 2, and then two of a smaller ATM that is actually able to go on a flight with some modifications so it's easier to take around to conferences. So one of the things we wanted to do on our CTF was teach people about, you know, card technologies. We got people to interface with the EMV chip, magnetic stripes on the card. 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. So that was cool to be able to, you know, create a ecosystem around that. So we actually had this at the IoT Village last year. This is the leaderboard, the final leaderboard. And those are real cash payouts. So we paid everyone in $2 bills. It was quite a fun experience. So this is the smaller ATM that we took around the MX-4000W. So it's almost able to be taken on a flight, but not quite. You have to take out the cash dispenser when we're ready to be underweight. This is the case we took it in. There's actually a number of times we've taken it on flights for quite a bit of money and also across international borders. So we took it to Canada one time, which was quite a struggle to get through border security. And again, not being the thing they gave us the hardest time about, they were more concerned about the t-shirts we were importing into the country to give away. So we register as importers. So there was a lot of people that I want to thank for the work in the CTF that we did. Alex Alex, our CEO, Ong, Brian, Jotun, James, Rafi, and Tim. This was a lot of people helping a big group effort. So thank you guys for that. One thing you need to be able to understand about the ATM industry is there's generally two market segments, the first being retail and the second one, financial. 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, just anytime you need cash to appear out of thin air. The second one is financial. That one's generally more focused on being more secure and more up-to-date. Those are much larger ATMs often. And you generally won't find those except in a bank. 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. So how does an ATM work? You insert your cards, some magic happens, and then cash comes out. Well, there's a lot of moving components here. Firstly, it's a vault with some holes in it, notably the Ethernet cable coming out the back. Though not all ATMs have that. Some actually use a cellular connection. So this is our ATM. There's two components to it, two compartments. The top section, which is a little bit lower security in terms of the lock, and the bottom section which actually contains the cash. 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. The bottom component has the cash dispenser, which works with the cassettes. So the cassettes will actually hold all of the cash dispenser. Obviously dispenses that. So there's two separate sections there. And in fact, the key for the top section, as Brigadier Jack mentioned 10 years ago, all the keys for the tops of the ATMs are the same. 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. However, the top section only has a key that's commonly available. 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. So we went and I'm actually 3D printing 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. Again, most of these devices run Windows. This one specifically runs Windows CE6, which is quite old in terms of operating systems. This was released before Barrington Jack's Talk. There's a lot of modern protections missing from it that you would expect in a device that literally holds thousands of dollars. So when we opened up the ATM, we're greeted with this main circuit board. It has an HDMI, USB, ethernet, interestingly a dial-up connection so you can hook this up to a phone line and set things up that way. And then connections to the cash dispenser and receipt printer. 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? Well, unfortunately, there's no Explorer shell that pops up with this. It's all in this kiosk mode application, winatm.exe. So our initial attempts to interface with it through a keyboard actually completely failed. The keyboard didn't work at all, even caps lock didn't work. 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. The pin pad is not true, it's a keyboard, 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. 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. All right, so on the main port we found these very suspicious pads and on the back or on the same location there are these resistor pads. So we suspect that this might be JTAC. And turns out it is, it is a standard 10-pin arm connector. We do need to solder some pull-up, pull-down resistors on the back, but out of the way, do that we're able to connect it with JTAGulator, identify it as JTAC and use a JTAC debugger afterwards to interface with the ATM. So that's good. The next step is to dump the flash in order to get the firmware from the ATM. Now on the ATM, the firmware is stored on the NAND flash. You can see inside the little red box is 48 pins and a service mount. So it's pretty painful to rip out from the board. But we did this solder at one point and we used the Super Pro, which is a flash reader writer to read and write to the flash. We did it a couple of times, but eventually the board died. 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. So at that point, we're kind of panicking, right? Do we need to buy a new ATM? No, not really, because we found out that we can just go online and buy the main board at $400 a pop at atampartmark.com. So we bought a few main boards and they did work, but we don't want them to break again. So this time, second try, let's be more resourceful. We think maybe there is someone who did some reverse engineering and put them online. Maybe the firmware is already online packaged nicely, but it could also be behind some paper, we don't know. But with enough googling, we found out that the firmware is actually publicly available. Now Tray mentioned the two versions of ATM that we got. It turns out that they both share the same firmware update. So we only need to download it once and we start looking at it. So in the firmware update, there are three main files, 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. That is where the ATM executable is, is where the libraries that the executable uses are, and is where all the audio files, the JPEG that is used by the ATM are. And we look at the application binary, the exported entry in the application binary still has their names on it. So from a reverse engineer's perspective, it gets pretty easy to figure out what each function does. So for instance, if you want to figure out the dispense money from the functionality, you just find a function that is called dispense. Or if you wanna figure out how the receipt printer works, you found another function called print receipt. So that's a win for us, right? So with this firmware update, we tried our first firmware modification attempt. We didn't do anything fancy, we just tried to change the please wait while loading screen to please wait while pawning. However, when we changed that one character, we got stuck on the bootup screen. Now, why does that happen? That's because in this firmware update, the manufacturer enabled Microsoft code signing, it is used to ensure that the software has not been corrupted by third parties. And in our case, our application binary is assigned with a certificate that is named MX5300CE. Now, at that point, we don't really know where the certificate is, and we don't really know how the verification process works. So in order to figure out the digital signature, we have two ways to do it. 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. So in order to do that, we need to take a deeper dive into how the kernel files and the kernel is structured. As mentioned before, there is this file called nk.bin where the kernel is. So that file is packaged in something called a bin FS format. And within a bin FS format, there are these records, right? So in one of the records, that's where the kernel and the libraries are. So we took out the record and we started trying to figure out how that binary works. So in that binary, there is the window CE header. It's pretty standard. You have like your magic file, you have your start address. And more importantly, is where there's a pointer to the wrong HDR structure inside of binary. So this structure has some very interesting information, right? It has the physical start address, it has a physical address number of files, but more importantly, it also points us to the module entries. So with that table of contents, with the wrong HDR structure, we figure out where nk.exe, which is the kernel is, we figure out where the library is inside the binary and we're able to parse out the kernel and the libraries. We use a tool called EIMG FS to extract the files. And we figure out that although the application binaries are assigned, since in this version of window CE, the kernel is used to verify the application binary, the kernel itself is not signed. We found a file called file sys.dll, which checks for certificate verification. Now this is part of the control flow graph of the certificate verification function. We figured that out because there's a string, literally there does say cert verify, right? And as we're analyzing the control flow graph, we realize that every successful operation would return a number four to the caller. So here's what we do, right? So instead of returning an error code on other paths, we just modify to always move the number four to R0, which is the return register in ARM. And after we patch file sys.dll, we package the whole thing, we successfully bypass signature fabrication. And from then on, we're able to modify our firmware and add our own custom code to the ATM. So here's a video of the ATM having custom code on it. As you can see, we press a button and we print it out a small receipt. Like that portrait of the ATM is something we think is kind of cheeky. So that's why we did it. So that's good, right? Like we got firmware modification working, but now it really has to work as an ATM. And throughout this process, we found some very interesting stuff, right? So firstly, this is a very old device, it's a pretty slow device and each update takes around 20 minutes. We have to sit there and babysit the ATM as it's updating and manually punching the settings. We also found a lot of peculiar commands. So for instance, within five seconds of the loading screen, if you hit clear left, right, clear, clear cancel, you can clear the settings on the NVRAM. Or if you hit enter clear cancel one, two, three, it would bring you to a password prompt, which brings you to the operator screen where you can change the settings on the ATM. So we figured out the firmware update process. We're pretty good now, right? Like I have JTAG, we have the firmware itself, with some debugging symbols. We have an understanding of how the firmware update process works. We are able to modify and remove executables. One last hurdle, it keeps on getting stuck on the whole screen. Like we got stuck on this screen for a while, trying to connect something. What is it trying to connect to exactly? So it does some digging, and it turns out that the ATM is actually trying to connect to a service called the Payments Processor. Now there are these big card networks that issue a card to you. So for instance, it could be your Mastercard, or Amix, or Visa. 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. So there are different kinds of protocol for communication between the ATM and the Payment Processor, but the one that we looked at is called the Triton Protocol. Now, the Triton Protocol is a request response communication protocol. There are four different types of communication pairs, but the most common ones are the configuration pair and the transaction pair. We did find a documentation online. However, it is a preliminary specification, and it is very out of date. So some of the information is wrong, and we needed to use Wireshark to figure out the correct request response format. So this is how it works, right? When you first boot up the ATM, it tries to connect to this Payment Processor, and the Payment Processor, when they receive the request, would send back a response, having some important information in it, such as the third charge amount that it's going to take on the ATM. And for subsequent transactions, it would send a balance inquiry or withdrawal transaction code. So the ATM would send a packet to the Payment Processor, having the card number and cryptic pin withdraw a balance of the withdrawing money. The Payment Processor takes that packet, talks to the network, talks to the different card networks, and returns whether you can successfully withdraw money or not with a success slash error code. So you might think, these information is pretty important, right? So is that information encrypted? And the answer is yes. It is encrypted with SSL or TOS. However, this is an option, which means that operators can actually opt out not to use encryption for Triton traffic. However, the pin numbers do have an extra layer of protection, and most uses triple desks for encryption. It's pretty standard triple desks. It uses two keys, K1 and K2. So the pin would be enclosed in like its own padding. The ATM encrypts it, sends it to the server, so the server would decipher it. All right. So triple desks is a block cipher, it's a shared key protocol, and the setup is actually pretty interesting, right? So when a technician comes to, like your store, your restaurant, to set up the ATM, it would punch in two keys. And these two keys are extra to get it to form a master key. Now the server also has knowledge of this key, but it is not the final keys used to encrypt the pin. So this is how it happens. Once the technician punched in the key, both the ATM and the payment processor would have a copy of the master key. The ATM would tell the payment processor, hey, I'm using triple desks. The payment processor would acknowledge it and encrypt two other keys, which is the final K1 and K2 with the master key, and sends the encrypted pair of keys back to the ATM. The ATM decrypts K1 and K2 with the master key, and those two keys would be used to encrypt your pin number. So when someone enters their pin on the ATM, K1 and K2 is encrypted, sorry, 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. 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 connected to ATM, and the ATM is finally functional. So one of the first things you wanna 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. So that's what we did. We actually found eight open ports on this device initially. 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, and when you actually pull it up, it's just the default web page that gets returned. So likely this was something that just wasn't removed from the image as it was being built. Interesting aside is that you'll find a lot of Windows CE devices on the internet. 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, but ATMs, I haven't seen many, if any, ATMs on the public internet, mostly other devices. So the 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. So that was something that you used to update the ATM to administrate it, to check balances, that sort of deal. So that's what that port was. And then we had these last five ports here. So these were ones that we didn't quite know, ones that we weren't able to figure out easily. So we tried connecting to them, but for quite a while we just weren't able to get any results from it, or sending data and have it be acknowledged. So we'll come back to that in a bit, but first I'm gonna hand it off to Brenda to talk a little bit more about RMS and what remote management system does. All right, so what is RMS? So RMS stands for Remote Monitoring System Service, Remote Management System Service. However you want to call it, is a service that lets customer control the collection of ATM remotely. 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. Now this is an optional service, meaning that users can enable or disable it. The default port for RMS is 5555, which corresponds to trace port scan. And it uses, so in RMS it uses the ATMs ID and the custom password for verification. So when we're reverse engineering it, we realize there's close to no documentation on RMS. So at the end we needed you to use a combination of Warrant Shard, Ghidran, Ida to figure out a communication protocol and the process took around two weeks. But we eventually got it, right? So the RMS packet is pretty standard, you know you have to start by a terminal, buy this like an LROC at the end. The more interesting part is like the encoded data where that part is actually obfuscated with an extra table hard-coded in the binary. And this is actually not the first time someone looked into RMS. In fact, in Barnaby Jack's talk in 2010, he jacked part of the ATM via a vulnerability in RMS, right? And since then, and we looked at his report, turns out that the RMS packet structure is still the same, obfuscation techniques didn't really change. And in his talk, he found out that a malformed packet can lead to authentication bypass and eventual firmware modification. So with the service should be secure now, right? Well, let's go to the test. We want to use a fuzzer to fuzz it, but we don't want to set up memory or emulate some Windows CE functions, right? So we used Bufuzz, which is a network fuzzer. It takes a lot of heavy work out of it, so we only needed to define the protocol in code and Bufuzz would take it, test different inputs and do the rest. So we did go around five to six crashes 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. And interestingly, this happens regardless of whatever password or ID you send to the device, right? And with JTAG, we figured out that a crash happened in this function called RMS process TCP in the library that controls the RMS communication. So let's take a deeper dive into this function and how it works, right? So at first, the function accepts any incoming connections via TCP, receive the packet, decrypt it with the XOR table, verify the ID and the password, process the command, close the connection. And the problem happened at this stage where it received the RMS packet and decrypt it with the XOR table. So what exactly went wrong? Well, it turns out it's basically a buffer overflow. In the function that received the RMS packet, it copies the TCP packet over to a global buffer without any bounce check. And what it did is that this eventually overrides a function point it has called when the application exits and this copy happens before any kind of terminal ID or password verification. So the consequences, as long as you understand a packet structure, as long as your packet structure is sound, the buffer overflow could happen and you can write shell code in your packet to lead to arbitrary code execution. Now, what can the attacker do? We were investigating it and we realized that most DLLs are paged out as the application exits except for the functions that controls the NVRAM. And in this device, in this ATM, NVRAM is pretty important because it basically controls anything on the admin screen is controlled. It stores all the settings on the ATM. 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. You can change the denomination of the ATM. So for instance, if your ATM is supposed to have $20 bills, you can change your denomination to $1 bills in order to extract more money from the ATM. And let's go to a demo of the RMS vulnerability. All right, so we have our ATM here. It has RMS running on the background. So now Trey is going to send a packet over to the ATM. And as you see here, it says remote monitoring system is in progress. Trey sends a malformed packet over but it still looks fine here, right? So now let's say I'm the operator and then I need to perform a firmware update. So I will do enter clear cancel one, two, three in order to go into a password prompt, right? And then I put the operator password in. That brings me to an administration screen. You can change a bunch of stuff here. But right now, since I'm doing the firmware update, I'll go into system setup, system control, software update. Yes, I want to do a software update. So this is where the shell code gets executed, right? Because as the application exists cleanly, the function pointer that we overwrote would be called and that would execute our shell code. In this specific demo, we set the shell code so that it would point, 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. So as you see here, it just updated successfully and we needed to wait a few seconds to reboot. Once again, this device is pretty slow. 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. So one interesting thing to note is that as we're writing the shell code, we need to figure out where the functions are. And as Trey says, since this is a pretty old device, the pretty old version of Windows CE, a lot of the modern protections against, a lot of modern protections and binaries are implemented. So for instance, we don't see any ASR implemented in the binary through JTAC. So what we're able to do is that once we use JTAC to figure out where all the libraries are in one boot process, the next time we reboot it, those libraries, the executables would be back into, would be loaded back into the same location, which makes the whole shell, like which makes the process of writing shell code easier. And as I mentioned before, right, the shell code would point the ATM to Trey's computer, and how it does is modify some settings on the NVRAM. The NVRAM controls, it controls like all the settings, right? Like it controls whether it was turned on or off. It controls where the ATM is pointing to. And it's also like a pretty, it's also a pretty simple function to reverse engineer. It takes two numbers, and like each pair of number would point to, for instance, whether SSL is turned on or not, it would point to like this IP string, the IP string of like the payment processor host. So as you see here, now it's initializing, right? It takes a while, it's loading, and it's trying to like interface with the peripherals. It prints out a receipt whenever it reboots, right? So it's just say, oh, test printing okay, and it prints out like a version of like the printer within the ATM, all right? It takes a while to initialize, but after initialize, you would see that instead of pointing to the ATM on the Raspberry, sorry, instead of pointing to the payment processor on the Raspberry Pi would point to the tracking server that Trey is running on his computer. Makes a lot of noises, right? Like it's trying to print something, it's trying to make sure like the cache just spends through works, all right? All right, now it's trying to connect to the host, and as you can see on Trey's computer, our malicious payment processor is working, it's interfacing with the ATM. So I have a card here, right? It's one of the cards that we were printed in-house at Rebeloon, so it has a track too, so it has tracks here, and track too is where the interesting information is stored, is where your card number is stored, in fact. So let's say I'm a customer, and I wanted to check my balance. Takes a while, all right. I hit English, it asked me to enter a pin, right? It can be anything, enter, and let's say I want to inquire my balance on the ATM. You know, and then let's say I want to check my checking, no receipt, thank you, and it is connecting to the host, although it says in eligible account on Trey's computer, you can actually see the expiration date of the card and the card number itself. All right, back to your Trey. Cool, so we just saw the RMS demo, and now I want to talk a little bit more about, you know, interacting with this device, and what we had to do actually get things to work on it since, you know, we didn't have a keyboard or any HID device to really interface with it. So we kind of had to actually take a look at this. So there's an active sync probably port on here, but we couldn't quite get that working. Active sync is the way you would work with Windows CE devices to interface with them on a desktop computer, but we couldn't get that working. So we actually compile our own tool. You know, this is Windows CE, it's a standard platform. How difficult should it be to be able to, you know, just compile something to work on it? Well, the caveat here is that it's Windows CE 6.0, so this was released in 2006 initially, so we actually had to go all the way back to Visual Studio 2008 to get this really going. And it's quite an old IDE, but knew it worked well under Windows XP. So what we're 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. It has a .NET compact framework on here. 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. A lot of useful features are missing, but in the end, we did get an application working on here. 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. So this was the start of that. We actually popped a dialog box here. And, you know, we could have used the built-in web server on this device that you saw on the port scan earlier. However, there wasn't any DLL or any capabilities for any sort of dynamic content or scripting, so that would have been a bit difficult to actually get up and running, 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, so we had to build things on top of just great TCP sockets, but with some good examples, we fast-forwarded a bit and had a web server working, which is what you see here. So this is our test setup. This is a device emulator running the .NET code and displaying our CTF webpage there. So for launching on startup, there's a number of ways we could have gone about this, 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. 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 we pointed that towards our custom server. So we could reverse the startup procedure and do the proper way if you're like registry edits, which can be a bit difficult on Windows CE, 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. So we've got this C-sharp code running, it's all good, but what we could take to get some native code running, really dig into it here and 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, but 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, clicking little checkboxes to enable or disable different features and change how things are built into it. 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. But by this point we had already kind of gotten our web server up and running. 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 were running, add or remove registry keys, add or remove files, any sort of thing we'd need to really dig in and research it and have fun diversion while we did it. So this was actually, we found a build of Doom for this device and we actually got it up and working here. This was an Easter egg in some of our earlier CTF challenges to be able to find this, 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. So we had to remove that for further CTF challenges, but it was fun to get it up and running while we had it. And despite being fairly slower and older ARM core, we were able to run this. 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. 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. 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 cash dispenser is somehow related to this open port on 8004. So what is this? Where are we taking a look at here? Well, here's a hint. XFS is what this is. Not the file system, the money one. And XFS is this standard platform for financial devices that exposes this sort of mid-aware 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. So this allows you to build things in sort of Lego's fashion so you can swap out different components of your system theoretically, swap out different cash dispensers, swap out different card readers. And there are all these standard different devices that you can put on here. So you'll see the cash dispenser, you'll see the ID card unit, which is reading your card, pin pad, things of that nature are all in here. So what is XFS? Where does this come from? Well, it started out as a Microsoft thing where they wanted to create the standard platform for Windows for financial devices. And it seemed to have really succeeded because this is kind of one of the industry standards for how you would set up an ATM or any other financial device. And so Microsoft handed it off to Sen, 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. So for example, this is the cash dispenser device, kind of description document here. So this is great for people building these devices. It creates a fairly open ecosystem that allows manufacturers to be able to swap out different things and have that, but it 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 that takes advantage of the XFS interface. And we've seen a number of different pieces in malware that use this. So going back to the ports, again, this is something XFS related. So we see those numbers there and what I did was go through and map out. You can see that after logical services, there's auxiliary arrays, card reader, cash dispenser, and then there's also the device class, which is what XFS would call that device. So IDC and CDM for the cash dispenser. And created this mapping showing which registry key corresponds to which device class, which corresponds to which port. So you can see here again that this is, the device classes are the standard XFS designations for these types of devices. So what does this tell us? There's open ports that are related to XFS somehow. Can we make it dump out some money? Well, the problem again is, we can connect to these ports, but we can't get anything out of them. We don't see any traffic and we don't know what to send into them. So let's sniff it. Let's see if there's anything on these ports, even on the local networking 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. 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 hopefully points out, there is no Wireshark for Windows CE. 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. So the easiest way to do this ended up being JTAG. 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. 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 and here you'll see that this is where we're hooking the sending 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. So this is all in Laderbach. This is a JTAG debugger that we use and is great for scripting like this. So as you can see here, we have a number of packets that came in. Some of these are sent, some of these are received. So it's just a bunch of binary blobs and there's not very much that we can easily recognize in there. There is the US dollars string in the packet in the lower right but it's nothing immediately obvious. So first thing we tried was can we just replay one of these packets? Because 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. So yes, we can just replay and send out some cache from the cache dispenser. It was actually fairly straightforward to be able to do that and then you can see we jumped out some cache here. It was no need to learn how all the structure works. No need to learn how to work with these fields. You can literally just take this packet that you've seen, replay it to dispense cache and that was fairly straightforward. 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. 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. So for example here, we have a packet where we... It's the result of reading card that's been put in the ATM so you can see the card number there is 5555, 5555, 5555, 5555. That's the track two data. And we have these fields here that might not be immediately obvious, this command code, noably. So if you look in the XFS documentation you can see that there is this concept of a device class and then a service class and then a service offset. So the service class being two, that's multiplied with 100 to get the service offsets which is 200. And then all of the commands are some offset from that base number. So 207 is this specific command for ID card read raw data which corresponds to what we saw here which is 207 which is hex CF. You can see the result of that read raw data there. So we modified this to work with the structure for the cache dispenser packet and pumped up the amount of cache that we're dispensing. 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. So kind of in retrospect here, pro tip, if you're using TCP sockets for IPC don't listen on 000 and if you're creating a networked device at least to a port scan before you ship it. So we wanna run through the XFS demo here and show you this machine spitting out some cache. Cool, so we have the ATM here and I'm gonna run the script we wrote for XFS and you should see that the command is being injected directly into the XFS middleware so none of this will actually show that cache is being dispensed. So if I run the command it's gonna dump out some cache. So this is just gonna continually happen. It's just gonna keep dumping out $2 bills over and over again. And yeah, this is the result of a computer just being on the same network. So 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. Thank you for coming to our talk and be sure to join us in our Q&A afterwards.