 Hello, everyone. My name is Christopher Wade and today I'm going to be talking to you about custom firmware for embedded mobile chipsets. This being custom firmware built for chipsets that are found in mobile phones but are not part of the core operating system. I usually deal with certain aspects of the hardware. A bit about me. I'm a security consultant at Pentes Partners where I mainly work in hardware, automotive and maritime. But today we're mainly going to be talking about attacking mobile phones and embedded firmware. The origin of this project was that I'd found that smartphones that I'd bought and rooted contained a huge amount of closed firmware and closed hardware, which you couldn't modify even after rooting them due to signature checking restrictions or just lack of open knowledge about the protocols used by the devices. Because of this, I thought if I could break the firmware protections on some of these chipsets I'd be able to expand the functionality of my phone more. There's a few ways one can do this without having to do too much of modification of their phone and are well known, such as Wi-Fi monitor mode, which can be activated in Snapdragon chipsets by echoing 4 into a specific kernel parameter in the file system, which converts it from two Wi-Fi chipsets into a monitor mode chipset. Also, if you add custom firmware to a Broadcom chipset and modify your kernel slightly, you can get monitor mode that way on Broadcom. You can also modify the kernel on most mobile devices to use USB device emulation. By disabling the functionality of things like ADB or standard MTP and PTP for Android devices, you can enable features such as the gadget file system, which allows you to emulate any USB device you'd like, from a memory stick to anything more esoteric. Further to this, when I root mobile phones, I usually like to add a Debian route onto them, this being a Debian file system which can be built with QMU debut strap and a small script which can be used to mount up all the correct device files in that file system and set up SSH so that one can SSH directly into this portion of their phone without affecting the main Android operating system but still affect the hardware. I wanted to look at NFC on Android for this project because I'd found that there was very little research done on the firmware of NFC chips on almost any device, but mainly on phones. NFC on Android is restricted to some very low-level features such as generic reader mode, so reading from tags using certain applications, mobile payments, which are very popular nowadays, NF communication, which is slightly more complex, and host card emulation, which is emulation of NFC tags but in a very limited manner. While these are allowed for certain attacks such as relay attacks to be performed, they weren't complete in what they can be done with. NFC attack tools often have features such as reader-based attacks that's been trying to decrypt or attack NFC tags by the reader, raw tagging emulation, emulation of any NFC tag you wish, or passive sniffing of NFC communication by basically performing a man in the middle between the reader and the tag. My first target device was my Samsung S6, the SMG920F, which is an older smartphone found in the EU. There's different versions of the same phone in different countries and I found that it allowed for very amount of unlocking and deployment of custom ROMs which meant I could route it very easily and gain access to the hardware as needed. I found that it used a proprietary Samsung NFC controller but this was not used in some US versions. This NFC controller was the S3FW-RN5 developed by Samsung Semiconductor and it was used in the non-US versions of the Samsung S6 and Note 4. This chipset boasted the ability to update firmware securely, meaning that people couldn't deploy custom firmware. You sliced an ARM SC000 secure car architecture and was communicated with via I2C and GPIO on a phone. As smartphones were essentially embedded Linux devices when you get rid of the Android side, I found that the chipset was communicated with via GPIO and I2C communication which can be performed via device files in the Linux kernel. However, I found that Samsung kernel has abstracted these into a custom driver which I can access using the device file slash dev slash sec NFC. I looked into how it communicated via this and found that it used IO controls to power the chip on and off and file reason rights to communicate over I2C. NFC chips communicate with a very standard protocol called NCI. This is a protocol which is used to simplify NFC communication functionality in phones and other devices but also restricts it quite heavily. It works by sending three bytes for the group ID, the operation ID, what has been performed on that group such as core RF vendor or specific, and length, which is a one by parameter which sets the length of the payload. It supports non-standard functionality via the vendor group ID which is defined by F, which allows for non-standard functionality to be implemented. There's no restrictions in the protocol which dictate what should happen with what these functions do. The developer who creates an NFC chip can make these do things that they weren't necessarily intended to for debugging purposes or certain configurations that were specific to the chip. I found this to be used in the Samsung chip mainly for deploying firmware files to it for things like frequency, etc. post deployment of the core firmware. The SCFW-RN5 was found to support firmware updates via I2C via the same endpoint as NCI. However, I found that the firmware updates use their own custom protocol, which did not use any NCI communication. Now, this is the case in almost any NFC chip I tested. However, I found this quite interesting as a lot of them had very similar protocols to NCI to do this. These firmware files were found in the vendor partition on the file system of the phone. I enabled debug mode on this via going into these vendor configurations and slash system and modifying the .rc configs for this chip set to enable logging and force firmware updates as well as find the names and locations of the firmware files. Using this, I could now trace out any firmware updates that occurred via logcat. Doing this, I could dump all the communication out and analyse how the firmware updates were performed. It was found to use a 4-byte header followed by a payload, so address 0 being the command type, address 1 being the command itself, and 2 and 3 being the 16-bit payload size, which I found to be restricted only to 256 bytes. I also found that there was a parity bit set on every command type at the start of each update. Firmware update files can be found throughout the Android file system. I found these in the .rc configs, but they were found separately in other areas and I found this to be due to the fact that sometimes phones want to update the firmware due to software updates that occur just generally on phones. I looked through the firmware file itself and found that it used metadata highlighted in red, which was just the date, as well as some other CRCs and relevant information. I then found the signature, which is highlighted in green, which was just the cryptographic signature for the firmware, and then in blue was the start of the firmware itself, so very easy to assess how this worked. I didn't originally know that this was going to be an arm chip, so I decided to find out what the architecture was for myself. Looking through the firmware, I found that it was quite obviously going to be a thumb firmware. By running the strings command on the firmware itself, you can find that it has a large number of low-case BFKHG outputted by its strings. What this translates to is hex7047, which translates to thumbs BXLR operation branch and link. A high number of these generally means that it's going to be using arm thumb firmware, similar to a cortex arm chip. This has some interesting features, such as the fact that in the chipset, as it's processing, the PC register will always have the lowest bit set to differentiate between the thumb and arm code. To implement the thumb updates, all I needed to do was copy and paste all of them from the trace log and follow them in sequence while reading at the appropriate times as well. By setting up the IO controls to set it into bootloader mode, rather than standard power mode, I could deploy the firmware updates as needed. Head of files from the open-source kernel drivers for this chipset were very helpful for this. I used the slap depth set underscore nfc.h file to perform this, and then I could just set the appropriate configurations with IO controls using this. I found that there was a very specific sequence that was used for firmware updates every time using specific commands. I used command zero for reset, command one for boot information, command two for beginning of updates, command four for updating 4,096 bytes of the firmware, and command five for completing the update, which verified the SHA1 hash of the firmware against the SHA1 hash that was sent at the start of updates in the begin update function, which was compared to the cryptographic signature. I noticed that there was a numbered command missing from the sequence command three, and this meant that there was very likely a number of commands found. Commands in this sequence only work at certain times, so you can't start writing firmware before setting up the signatures, etc. Due to this, I brute-force my way through the entire firmware update process while trying different commands to see how they worked. I found that chips would return an error too if the command was not valid or not valid at that stage of the update process, and return nine if the payload was too small. Now, this would allow me to find any valid commands at each point in this process. I found that hidden bootload command three was the same functionality as command four, except instead of sending 4,096 bytes, it would write 512 byte blocks, so there were no real actionable weaknesses. However, I also found that there was a hidden bootloader command six. I found that this took eight bytes of parameters, two 32-bit payloads, and by setting some individual bits in these parameters and sending it across to the chip, it would start dumping memory out to me. I found that this was because I was giving it an address and a size during this process. This allowed me to dump the ram of the chip, the firmware of the chip, hardware registers, and more importantly, the secure bootloader. By stitching together the responses from this command by increasing the addresses, I could make myself a binary of that bootloader for me to reverse engineer later. This showed that it was using a standard Cortex-M firmware format starting at address zero, which was the vector table, so it started off with the stack pointer, followed by the reset vector of the chip, so that's the code that would get jumped to at the start of the firmware start-up, and found that the firmware contained no strings, so all reverse engineering would have to be done by hand. I loaded this into Ida as an armlythian in binary, as it should be, and set up a memory layout for zero at flash memory, two zero zero zero zero at ram, four zero zero zero zero and five zero zero zero for hardware profiles, and E zero zero zero zero for system addresses. This disassembled very nicely and very easily assessed. It had some interesting artifacts, such as the fact that I could now work out exactly how the firmware updates were securely implemented and how these worked post update. I found that on start-up the bootloader checked for a magic number at the start of the firmware update, this being 5af zero zero FA5, which I did not find when I looked in the firmware payload itself. This magic number was written only after the firmware updates has occurred if the signature was valid during that update, meaning that every time the chip started up it wouldn't have to verify the signature. I attempted to manually write this value into the firmware that I deployed, however this did not do anything effective. I also found the state machine which handled the commands I was sending, so you see comparisons to zero, one, two and six, which were the commands that were valid at the start of a firmware update process. I also found the RSA public key, which was in use for this chip set, which was made up of 128 high entry p bytes for by zero zero zero one, zero zero zero one, which translates to 65537, the exponent of a public key. Because I only had one phone and I didn't want to break it, I didn't want to fuzz it directly in the hardware, I wanted to do it on an emulated chip set, so what I did was use this damped bootloader and looked into ways that I could emulate it effectively on a host computer. I ended up using the Unicorn engine for this process, which is a library for emulating architectures and hooking all functionality of a firmware as needed in order to emulate certain aspects of it. You can define the architecture, memory mapping and hardware integration as needed to fit your own needs. The bootloader I was found was loaded into address zero, which was the start of the flash memory in the chip itself and the program counter was set to the reset factor that I found in that bootloader, 2BD. I mapped a flash RAM and hardware registers as needed so that it would perform as a chip as needed. Commands were found to just be received in a single thread that started from the main loop and just looped around receiving I2C commands. Because this meant that there was probably not going to be any interrupts in use, just used the size of the bootloader and this content, it would mean that emulation would be a simpler task and all I'd need to do is straight up emulate what I had. I found that execution was causing device research during the start-up process of this chip however because it was trying to access hardware registers which simply didn't exist because they weren't at being emulated. What I did was patch the bootloader image to bypass all this hardware initialisation so that the chip could then move to the next part of the process but wouldn't need to actually set up hardware in any meaningful manner. The firmware was allowed to run and continue until it hit another hardware address. So all hardware addresses started either 40000 or 50000. The address that it hit was 40022030 and I showed that I analysed the assembly at the point where this was being read and found that the firmware was checking for specific bits in this address. By making it return random data I found that it was just checking for status bits via that register and allowed me to work out that it was an I2C interface that was being communicated with. Because I implemented this it would move on to the next stage of the process. Next I made the firmware continually read bytes from a single address 40022038. This implied that it was probably reading from I2C as well but the first and first out buffer. What I did was start sending bytes that I would usually send for firmware updates via this interface in Unicorn and to see what happened. I then found that the chip started writing out responses on 40022034 so the address right next to it. I had full emulation of the I2C communication without ever having to touch my chip. What I wanted to do was find a memory correction exploit so I could bypass the signature checking. And while I did start doing some randomised fuzzing that I thought would be viable it didn't really come out with anything interesting. The commands were found to have 16 bit sizes which were larger than the entire contents of RAM which was found to be only 8K. However these were limited to only 256 bytes. I did however notice that some functions especially ones for deploying lots of data could send data in chunks like 256 byte chunks. I also found that the size of the hash and signature were defined at the start of the firmware update process right before the hash and signature were sent. I found that I could increase the size of both the hashes and signature size in order to send more data and while this would respond saying that hashes and signatures weren't valid it did allow me to increase the size and send increasing amounts of data. When I did this in my emulator I could see this made my memory go out of bounds so outside the 8K of memory I had allocated in my emulated firmware. Looking into this I found that it had also overwritten the stack with the memory that I had sent to it. Because I can now overwrite the stack I can manipulate the program counter and start doing some more memory corruption exploits. However SC000 chipsets because they're meant to be for secure applications don't let you ever execute from RAM like a traditional Cortex M chip would. And because the stack was very small at this point only about 12 bytes when I checked I wouldn't be able to do anything too complex with Rop either. What I ended up doing was making the program counter just dump directly back into the start of a bootloader pass the check for the magic number and into the part where it initialises the firmware and this allowed me to bypass all of the signature checking and deploy my own firmware. I then ran this exploit on my physical chip instead of the emulated version and found that what would happen is I'd start at my bootloader, send this exploit and it would directly boot into the main firmware. I could then send and see I command and receive them as needed with my custom firmware. What I did was first change the version number of the chip so that it was different here EEAA, BBCC and DD and meant that custom firmware had been sent and validly was running. I then disclosed this through a ability to Samsung. There were two ways they could have remediated this. Firstly they could have patched the bootloader from the main firmware removing the buffer overflow. Now while this does seem simple it would be very difficult because what would have to happen is the bootloader would have to start the main firmware and then let the main firmware patch the bootloader. Now if there is any kind of power cycling going on or any sort of deployment average during this process, the bootloader would be erased and the chip would be essentially bricked and never able to work again. One could also patch the kernels to disallow the commands that were being sent so the large hash sizes and makes them static however this would be tribly bypassed just by modifying the kernel. I looked into other NFC chips that Samsung semiconductor had developed and found that there were four main ones that were advertised on their websites. The S3NRN74, S3NRN81, S3NRN82 and SEN82AB. The most interesting of these to me was the S3NRN82 as it seemed like their latest version at the time. I decided to go through the ROMs of lots of Samsung phones. Now because this was not a US phone there were not very many tear downs online for the phone and definitions of what hardware was in use. So what I ended up doing was going to sammobile.com which has a huge number of custom Android ROMs. I dumped as many as I could and extracted them to see what firmware files were in the slash vendor partition. Occasionally these partitions are not stored in these because they are part of a special vendor partition which is deployed to the phone and can only be extracted from a phone. But it did give some insight into what chips that were being used. While the vendor directory does always contain these firmware files this separate partition does make things a bit more difficult. I found that the S3NRN82 was the latest chipset after looking through this and found that there are multiple chip versions available in different versions of the firmware that I was downloading and I decided to go with the Samsung S9 which used this chip. It was also found to be available in the Samsung Galaxy S8 and S10. But I purchased the Samsung S9, routed it using OEM unlocking and a custom ROM and started looking through how it worked. I found this firmware file to be in the same format as the S3FW-RN5 except the initial stack point was much larger moving up to 12K over the 8Ks that the last chip had and the reset vector was lower so implying much smaller bootloader. I also found that the firmware size was 32 kilobytes much larger. Looking through my previous exploit and trying to port it over found that commands 3 and 6 were removed meaning they had made some changes there and meant I could no longer read out firmware as needed. I also found a new command 7 which was identified to just reboot the chip and nothing else. The new bootloader size implies that something else had been changed in here just because it was much smaller. However, the lack of memory read out meant that I wouldn't be able to exploit this and any exploitation I did do would have to be done blind. However, signature checks now no longer use shall1-as before and I needed to work out what they were using. Because they had modified their kernel to no longer dump out data via logcat I wouldn't be able to use the same logging procedures I did before to assess the protocol. What I found however was that the sizes of commands sent during firmware pit processes were stored in slashproc slash nfc log in the file system. Looking through these I could see the commands working in sequence find the start of firmware updates and then deploy them. I found that what was happening was during the start of firmware updates when I was giving this hash it was providing 32 bytes plus 4 bytes implying that it would move from a shall1 hash to a shall256 hash. I modified my firmware update tool to reflect this and I could now upload valid firmware to the chip. I wanted to see if I could replicate the same buffer overflow I had before. I would need to work out how big the stack was before doing so to make sure I had overwritten the entirety of it. What I ended up doing was sending increasingly sized payloads to the chipset. I found that when I sent these payloads to it if I was just overflowing the stack it would still return and return data to me just to use the nature of how the stack was being set up. However, if the device crashed before sending a response to me it was likely that I had overwritten into invalid memory outside of the 12k of RAM. What I ended up doing to find out where I could find the entry point was starting my program counter at 01 and filling the stack with this. So I was filling the stack with the address 01 and seeing what would happen if the return pointers which were somewhere in the stack, I didn't know yet jumped there. I then sent NSI initialisation commands as you would at the start of the NFC setup and if I received an NSI response then I'd found a valid endpoint into the core firmware and bypassing the signature checking. If it failed, however, I restarted the chip and increased the address by 2. I found the signature bypass succeeded at address 165 as follows. So I would send my exploit and if it failed start it again and if it failed start it again and then in the next one I found that I could receive data via NCI, meaning that the entry point had been found at address 165 which worked repeatedly and didn't have any problems. I then disclosed the vulnerabilities of Samsung. I provided them an exploit and showed them how it was done and they agreed to patch all newly manufactured chipsets from April 2020 as well as patch any new chipsets that they were going to develop. However, I couldn't patch the bootloaders of all the chipsets like the ones I had in my phone. Custom firmware would still be viable. In order to patch existing firmware one needs to basically modify what they have in there. They need to add their own code into what already exists. I decided to stick with the S3NRN82 rather than the S3FWRN5 cos it was the latest chipset and would have the most power. The only method I could find accessing data for debugging this however was I2C so I would have to debug with via the same methods that I was writing data etc. What I did was go back to my dump of ROMs that I had and go to a Galaxy S8 ROM and find the oldest available firmware I could. What I'd found was that I had a huge number of FFs in the firmware file. Now the firmware files were always the size of the available flash memory, meaning FF, FF, FF is the areas where no code or no data has been deployed to the firmware. I could stick my own code in there and then jump to it as needed. C functions cos easily be compiled as needed and jumped into there just by using GCC-C. When you use your compiling code without linking or relocating or checking anything so you can get object files and binaries which can be dumped in and jumped to as if they were specific functions but you wouldn't be able to use things like standard C libraries or any complex heap etc. I also found that however that stack handling was performed is by virtue of how ARM works. Now C function calls are generated as branch and link instructions. These are instructions which jump relatively to the current program counter into code and just by jumping to the code I had which returned back to the link register after branch and links meant that all my code would run as needed. Branch and links are made up of two complement relative addresses so addresses that can be below program counter and directly patching these over branch and links that were already in the firmware meant I could jump to my own custom code without causing any trouble in the rest of the firmware and changing what I needed to. I made a small build application which compiled all my custom firmware code and also compiled did all the relocation and integration of non-standard functions for me so this would all get built so I could call functions from different areas and also patch over branch and links. I also created a firmware update tool that would deploy this code for me. My initial project was I wanted to read out memory in the same way I had in the Samsung S6. In order to do this I decided to patch the NCI command 2f24 which is a vendor specific command which I didn't find the purpose for ever. I could send repeated data to this with larger and smaller payload sizes and it would just take them as needed. I searched for move.star hash 0x24 which is regex just for searching quickly for certain instructions in IDA and found a function call which set up a response ahead of using this value. I then looked through and assessed that this was indeed the function that handled this NCI call and I overroached some 11a76 which was the last function call before it sent data back via I2C. I could then modify any data that had already been modified as needed. I did find however that writing a firmware took around 20 seconds which was a lot longer than I expected. To receive parameters however I didn't know where in RAM these were located so what I had to do was find whether they were located in RAM as my first port of call. This way I'd be able to receive commands as well as send them back in responses based on what I had sent so if I want to send an address to read data back this is why I'd use. I crafted an NCI request 2f240 for FACE which was just a placeholder value that would easily be spotted in RAM and then I searched through the entirety of RAM via this I2C call and set the response payload via I2C to be the address it was found in. This allowed me to find where this data was stored in memory and read out parameters as needed. Because I could do this I could now dump the S3NRN82 bootloader which was extremely helpful for me to modify my exploit to make it just a bit more stringent. I didn't have any problems to redeploying it several times and the exploit worked every time. However if you'll see what was happening when I returned in the stack to 1.65 was that it was loading from R0 into R0 meaning that it was loading for an address I had no control over which was slightly scary. What I did was move it to exactly the same place as I moved it into the bootloader of the SCFW-RN5 that being the address which loads the address of the firmware we're jumping to and then jumps into that firmware. Now I'd added some custom functionality. I wanted to add something a bit more NFSB specific. When I looked into the capabilities of the chip I found that it supported ISO14443A this being things like my fair classic tags my for ultralight and most things you'll see. ISO14443B which is a bit less common and several other protocols all of which were of the 13.56MHz spectrum and didn't cover anything in the 125KHz spectrum. I found that while I had access to some information regarding the I2C interface I didn't have any access to information regarding things like how NFC worked on the chip and because this was a completely custom chip I would have to do a deep dive into how this worked and what to assess all of its functionality. My initial goal was to emulate a my fair classic tag in its entirety on the S9. This is functionality that's not traditionally found in phones because it's only use really would be for exploitation as far as anyone can tell. What I did was use a Proxmark for debugging to assess any responses sent back from the chip via NFC so I could keep track of what was going on from the NFC side while also debugging from I2C. I took all the NCI commands that were sent from the phone to the chip during traditional NFC start-up and reading and just replayed them as needed. I didn't have any access to NCI documentation so everything I looked at via NCI was reverse engineered. I went through each of these commands and deleted any ones which were unnecessary. I worked out they were unnecessary by removing them, replaying and seeing if NFC still worked. I found that this worked great and found that the last command that was sent was the NCI RF Discover command which is a command that starts up either pretending to be a tag, pretending to be a reader of different types or all of the above and then modified this only to act as a tag for now. Now, initial reverse engineering of this hardware required knowledge of the functions on the hardware and quite a large amount of depth. I would have to look through how everything worked and understand it in quite a lot of detail in order to modify it and because there were no strings and no function references, everything I did I'd have to do by hand. So I know quite a lot about my fair classic and ISO 14443A and what I ended up doing was searching for a select command OX93 just by searching for a comparison using Radex and IDA and found an immediate result which was reading from a hardware address that specific value and then jumping if it found it. Placing on my phone on a reader and then dumping the entire hardware address space of that particular address found that it was indeed the NFC functionality so I dumped this while the NFC was running while the ship was running and I found that it was indeed the NFC functionality so I dumped this while the NFC was running and I was using different hardware than the traditional communication. What I ended up doing was searching for the select command OX93 just by searching for a comparison using Radex and IDA and found an immediate result so I dumped this while the NFC was running while the ship was running and found that address 200 where it was found in the hardware was all the data buffers being sent to the chip so in this instance you can see a X52 there which was a NFC wake-up command which requests starter of NFC tags. With this I can read all of the NFC read commands as well as some configuration data which would be helpful later. This also allowed for one way passive sniffing and would have allowed for it later as well in different ways. So, as I said enumeration works slightly different to traditional communication for various reasons including the size of payloads and the time it takes to respond. However, I wanted to modify specific aspects of this in order to modify how it worked. Now when it enumerates in order to define what kind of chip is being used you have to send three values that are relevant. So first thing that happens is the NFC reader either sends a wake-up or a request A which is a command OX26 and what's responded by the NFC chip is an ATQA value. Now this is a two byte value which defines what kind of chip it is and if you are the relevant details just by which bits are set in this response. The reader then sends the select command as we saw earlier which then makes the tag respond with a unique identifier. It is a unique value that is randomized except for the first byte which is 0.8. Now traditionally tags should keep these a static value just by how the standards work and the reason it's randomized is so you can't emulate specific tag types. We were going to bypass this. And lastly after selection of this UID by the reader it sends an SAK value which defines a little bit more detail about what kind of tag it is as well as saying whether the UID is slightly longer either four, seven or ten bit bytes. I found that I could set the ATQA NCI and SAK values by certain NCI commands. However I found that when I sent these specific bits were set just by the firmware to force it to always behave as a specific kind of chip. So you could never pretend to be any other type of chip apart from the ones supported by the firmware at the time. I used my patched I2C command to take a random and then look for the values I'd set. I then compared these in IDAR via the addresses in RAM to any functionality that's found. And I found one function which accessed all of the addresses that these were set for. Looking through I found that these were all accessing hardware addresses. These are on starting at 4002 and this meant that it was probably setting these in some configuration in hardware. I overrode this function and then called it within the new function I'd overridden. This meant that I would not have to modify anything about the functionality which was more complex like if any had any hardware setup which I didn't want to deal with. But all it would mean is that I would be able to override the values I wanted to. So I let that function run and then set my own UID, ATQ8 and SAK values as needed so that I could pretend to be any chip. I then put this on a proxmark again and used the reader mode to identify what data came out. I found that it had my custom UID that I'd implemented, as well as the ATQ8 and SAK values which relate to a MyFair Classic MiniTag which was the one I was emulating for this part of the custom firmware. I then wanted to move on to the more high level communication of the MyFair Classic protocol. Now, as I stated before enumerational communication is very close together however it was very likely that this would be custom inside the firmware rather than handled by hardware registers. I searched for the ATS value which returns certain configuration data about the tag and just by another comparison and found that this is very quickly jumped out. I found full results in the firmware which I looked through and found the specific one which is most likely to be related to it. You can see a load byte followed by a comparison of that byte just in the disassembly there. This meant that I got inside the state machine which handled all of the requests to the NFC chip from an NFC reader. I also noted some other commands. Further tracing from this led me to the function which sent responses including setting of the buffer address 0x100 as well as the size at address 08 and a few other settings which I couldn't work out the purpose of but were very important and if I removed them it wouldn't send responses anymore. I first implemented a basic re-command so MyFair often uses 30 and then a block as just a standard re-command. This is common throughout a lot of different MyFair chips. Sometimes it's encrypted, sometimes it's not but what this allowed me to do was using a Proxmark, read that raw data and make sure that it actually worked and I found that this worked as well. I had to set up a CRC at the end but apart from that this worked as any other re-command should in an NFC chip. I could later add inappropriate encryption if I wanted. I overwrote the entirety of the state machine function because I didn't want to touch anything else apart from one specific aspect which was the HALT command. Now this, while it's part of more of the higher level communication, is still somewhat part of the enumeration as it sets up the state of the NFC tag to not respond to certain startup requests. I just called the HALT function that was found in the state machine as needed and it ran exactly as one would want to. I then also invented the rest of the MyFair classic commands as needed as well as localization as well as writing a block data etc. I also added some debugging commands as needed so as you can see commented out there is debug command 70 which would be provided with an address and redraw memory just out of the round of the chip or any other part of the chip over NFC so I could use this to debug via the Proxmark. Because I had full control of this I could emulate any NFC tag as I wanted to. As long as it was ISO14443A now I could have expanded this to different 13.56MHz protocols but I stuck with this one for now. I implemented MyFair Classic's authentication which is quite simple just using a very weak encryption protocol and I found that while this worked with the Proxmark there was a very good reason why it wouldn't work in a legitimate reason, a reader that I would need to get past. MyFair Classic overrides a very specific part of the RF protocol used by the ISO14443A standard which is the parity bit set at the end of every 8 bits. So what happens is during all communication is that both the reader and the tag sends a parity bit after every 8 bits of the response this being one or zero depending on how many bits were set in the previous 8 bits. This is auto generated in the hardware as far as I could tell and I was really concerned because this could have been a complete stopper on this project and stopped me being able to emulate this firmware as I wanted to. However, I thought that there was probably a hardware register setting that would allow me to modify this as needed in order to put in my own parity bits. What this would mean is however I'd have to stick 9 bits into 8 bit buffers inside the firmware which would make things quite complicated. What I did was go through the hardware registers and the ones that were specifically related to configuration and modified a single bit in turn as often these used bit settings to define certain functionality and I wanted to see what each one did. Now this had some interesting outcomes like making my responses huge or adding randomised data or encrypting in weird ways or adding strange CRCs but it was all quite useless for what I wanted. I found that the parity register which I wanted was at address 400200004 by setting the bit at 0x400 4000 rather. With this set shifted down all my data so that I now required adding in the size of the data I was sending. This meant I had to change the length to be 9 bits for each byte instead of just 8 bits for each byte and also shift all the data I was sending left by one so I could add my encrypted bit. Within this in place however I could fully implement a myfair classic tag with no problems whatsoever. One thing I wanted to add was persistent storage of data so when I was emulating myfair classic I set up the I2C interface so I could send tag data directly to the chip via the host phone. What I wanted to do was be able to store any modifications back to the host phone as well and what I did was modify I2C responses so that every time a write occurred it would send that written block back to me and I could write it to the file system as needed. Here's a quick demo of this occurring so what I've done here is taken a different phone and the NXP tag info app which tries all sorts of authentication styles and tag types to work out what a NFC chip is or NFC tag is and what I did was let this run on my Samsung S9 to see if it could work out whether it was myfair classic tag or not and whether it could authenticate appropriately so what I did is I set up the myfair classic tag being emulated to have a number of different keys and authentication mechanisms in place just so I could see how that worked and as you can see some keys were found some weren't just by what I had got implemented in NXP tag info so tag emulation allowed for a spoofing of access control cards as well as more anesthetoric uses there's a lot of games and toys which use 13.56MHz tags but I also found that I could make it work so that all other NFC functionality including reader modes or standard functionality would work despite this patching meaning well I had a custom firmware it didn't damage the core functionality the chip has needed but it did mean that I would need to access it or them via my tool rather than the Android operating system I felt that this was more subtle than a dedicated tool such as a Proxmark or anesthetically medium because it is a phone and people don't generally expect them to have this kind of functionality and also expansion of this functionality could allow one to do things like use dark side attacks or myfair classic decryption attacks directly on the phone and then deploy them back again to the chip itself I found that the same emulation could be formed on any supported protocol in fact I found that the hardware registers I was accessing were the same for every protocol that was used by the chip so what was happening was it would switch between different protocols in that hardware by setting a specific setting what this also meant is that you could set up things like certain amounts of two-way passive sniffing with different protocols or implement different ones as needed and have a more working conjunction with different purposes now that a framework was in place and a lot of the reverse engineering had been done I could do this if I wanted to in conclusion all of the vulnerabilities that I found were outlined to Samsung as of April 2020 or rather they patched them as of April 2020 because of this the chips wouldn't be vulnerable going forward however all chips that are currently out in the world will be forever and we can use those to develop custom firmware as needed the vulnerability did require root access but so you could not compromise a smartphone using this interface by reflecting data back however it did fully compromise this chip in this particular we want to remember that phones are exploitable embedded devices in the same way as any IoT device however of course they're slightly higher security in some ways but they really should be treated like that the chips in there are often running old bootloaders which will never be changed and because of this bootloader vulnerabilities are very common this is not the only chip that I've broken in the same manner and it's not even the only NFC chip I've broken in this manner especially on phones developing custom firmware is a very difficult task sometimes it can take a lot of time however it can be rewarding and you can get some very interesting outcomes and lastly if an undisclosed vulnerability is found in an old chip it'll likely be in a new one thank you very much