 So, welcome to the first day of the 34C3, today the French translation is proposed by Irolic and Arthem. Next to the fact that he's... I will spell it. Earning a nice amount of money, probably, at a lab that's quite renowned in the world. And from that point on, he's not just looking in this lecture to explore development for Cisco stuff. We all suffered from this last year, or we all heard about it and don't know the impact maybe, but he's going to explain us the work he did on that field. So, please, can I ask you all a warm, welcoming cause for Arthem? You got almost right. Please give him a warm applause and start! Hello everyone, so excited to finally be able to attend KS Communication Congress. Very happy to see you all. So, without further ado, let's jump into some practical iOS exploitation. So, a few words about myself. My name is Arthem. I do stuff, mostly security related stuff, but mostly my areas of expertise are penetration tests, both internal and external. So, I'm going to recap what happened this year. So, 2017 has been marked by several vulnerabilities in Cisco iOS devices. So, we had three main vulnerabilities. The first one is about Cluster Management Protocol. So, the authentication by Telnet of the remote code execution. The second one is the SNMP part. And these are the two vulnerabilities that we're going to cover in this presentation. And the third one, which concerns DHCP, is not yet in research. So, I'm going to be able to show you a live demo, for the use of this SNMP vulnerability. But first, let's start with the first one, the fight and net. So, on March 26, 2017, we had a Cisco announcement. Like what? A lot of models of Cisco Switch were touched by a security fight, and we haven't had a resolution for the moment. So, the first aspect of the vulnerability was like this. So, we can create a cluster with Cisco Switches, and there's a management protocol of the cluster, which is based on Telnet protocol. So, the Telnet option is part without considering if the switch is in cluster mode or not. So, the incorrect management of this protocol is overflowing with switch. So, what's interesting about this vulnerability is that the search for Cisco was done by Wikileaks. Most of the information is out on Wikileaks. And showing that Cisco systems were also impacted. So, you can go and see Wikileaks to read the particular information. And here are the notes of an engineer who was testing this exploit. So, we have the information here on Wikileaks. So, we have several modes of interaction. For example, a heart can connect to the Telnet on the Overflow service, and it can be presented to a shell to connect to it. And the second mode is all the connected connections to the Telnet. So, all the connected connections to the Telnet will be done without using the credentials. So, the complete search has been presented to Defcon 25 on the Cisco Catalyst 2960 as a target. And we have presented the information on the exploit and the way in which you can debug it. You can watch my YouTube video and my blog post as well as my GitHub to see how I have the code executed to exploit this vulnerability. But I would like to talk to you more in detail about the second vulnerability that concerns the SNMP protocol. So, the main motivation that I had is that by creating a ScanNMap, a community by default was available on a Cisco switch. So, the goal was to have access to the internal network. So, the hacker needs to access Ridonly in SNMP to be able to access the switch. So, we have a Cisco 2911, a router, a typical device presented in a lot of networks. We have a MIPS, an architecture MIPS Big Indian. We don't have any debugging tools available. And it's interesting that the firmware is relatively recent for this router. So, it can be interesting to look at the internal defense mechanisms used by Cisco iOS. When I say relatively recent, it's not supported. So, the last time for it was in 2016. And to remind you, the advisory for SNMP or Flow appeared in June 2017. But nonetheless, this is still widely used devices. It remains a device that is relatively used in an extremely short time. Finally, at least 3,000 devices with SNMP service available with default public string. We have at least 3,000 devices available on the public community for this device. So, all these devices are vulnerable to SNMP overflow. And can we use a remote execution code for these devices? So, the challenge is accepted. And we'll see how we can do that. So, SNMP comes with a lot of abbreviations like MIPS for management information based. And it's a kind of collection of options that can be monitored by SNMP on a device. So, the management of MIPS has identifiers for the objects. For example, you all know that a printer uses SNMP to monitor the level of ink in the cartridges. So, that's the percentage of ink available in your cartridges. It's an example of how it works. Management information based looks like a tree. So, it looks like a tree. So, we have the main elements at the top. And then, we have all the objects and the group of objects that can be interrogated. And that is why we're going to look at the request for SNMP. So, you only have to know the only community string. To be able to do the requests, you just need the community read-on-lead and the string community read-on-lead to be able to get the information. Here, for example, we have the router version, the description version of it. And you can also run it through the description. And we can also use a simple Linux command like SNMP get. So, we will build an exploit. We have a starting point. So, how do we look for... First of all, before creating an exploit, we have a starting point. So, what information do we have? So, we know that we have nine vulnerabilities at the level of MIPS. And we just need the community read-on-lead. For the fuzzing, to be done, I'll be using Scapi. The fuzzing, I use Scapi. It's a tool, a toolkit that allows you to work with protocol reasons. And here, I create a valid object identifier that responds to a certain description, to an object of the identifier. And then, I create a UDP package inside of the SNMP community with an identifier object. And this will not trigger the overflow because this... Of course, it won't trigger the overflow because the object is perfectly correct. Our object identifier is that our router will respond to. So, basically, the router... We want the router to respond to this object. So, we have several possibilities. We can take the firmware and extract all the values of the firmware in text files. It's very easy to grab. Another way is to look at MIPS that are vulnerable. And that are specified in the advisory on the website. And we can see all the identifiers affected on the website, on MIPS. So, the protocol doesn't concern us because it's not a part of our exploit. So, we have our OID, our object identifier. This is the rocket that crashed the router. So, if we connect to the switch with a serial cable to check, and we have a crash, we will see this trace here, this information. We have a broken program counter. And here, we also see the information on the record keys that appeared at the crash. So, here we see that we have the control of the record counter and the program. S0, S3, S4, S7. So, we have 60 spare bytes on the stack to work with. But before, we need more problems issues to be solved. And that is, yes, we do control the program counter. But what do we try to do? It takes a lot of time. And can we have some shellcode directly on the stack? It's stack-accountable directly on the stack. So, on it, is there a caching? Can we just patch the code? Is the code section vital? Can we write code, section of code? Can the integrity of the code be verified or not? But what is the most important? Is it that we can send code of execution to the SNMP process? If you have an error or something that happens at the level of the iOS, the Cisco iOS can crash. One of the indicators of compromising the system will cause and affect the device to reload. We will build an exploit. We will try to build an exploit that will not crash the SNMP service on it. So, we will have to create a vulnerability that will not crash the SNMP service. Where I want to reference previous researches on this matter, this is by no means a complete list. But this researches actually helped me a lot and seemed interesting and very polite. I will talk about previous researches that were done at the level of iOS. So, it's not an exhaustive list, but you can verify, for example, the exploitation of the routers that were done by Fx, Felix Linder, and Cisco iOS Shell Code All In One by George Nocenko, which shows you exactly how iOS works at the level of the exploits. And the third resource is how to cook Cisco, development of exploits and vulnerability for Cisco iOS by George Nocenko as well. So, if we were to talk about how iOS works in memory, iOS works as a unique binary in memory. It's a unique file from Elf that is loaded at the start. No API, no symbol, nothing at all. It's a library at the end of firmware, but it's also kind of hard to use it because you have so many different versions of firmware and the offsets jump and you don't know the location of the offset. So, with static analysis, you can probably copy firmware from the router and copy the router, use the copy command. It supports TFTP and FTP protocols. You can use a copy command to load a firmware, when the router starts loading it, it has an initial step that does the unpacking. The first step is to decompress the package that we're going to upload. We'll do the unpacking for you. You load the result of unpacking with the bin walking to your private property. The process will be applied. We know that this is MIPS because we saw the registers tell us that it was indeed MIPS architecture. One thing I want to note, the actual firmware gets loaded into address 800F00, but the program counter is located at address 4. And this is because iOS, when it loaded the firmware, it maps the memory to 400F00. And that's important because to have the corresponding references, you have to have all correct string cross-references. And then behind, you can have the correct Xrefs compared to different rockets. But to create a vulnerability, it's not enough to use all these references, etc. So it's important to create a debugging environment. That iOS can be debugged via a serial port. iOS can be debugged easily by a port series. And there's a command, a JDB kernel, which allows you to access the JDB server on the device. But it was, in any case, because the functionality was deleted in the new versions of iOS. But there's a way to activate JDB. And this way is to reboot the device, send a serial, a serial, a serial, a serial, a serial, a serial. And it will take you to the ROM monitor, the ROM monitor shell. And ROM, you can manually boot your hardware which will allow you to manually boot your firmware. With the flag, it will allow you to launch the entire firmware on the GDB. Once the firmware is loaded, the GDB will work. And now we can reuse our GDB, our favorite GDB, and debug iOS by the port series. So iOS uses a different command subset for GDB. We have a GDB server-side, but the... We don't have... We don't have any debugging tools for Cisco clients. Publicly. This is Cisco engineers, Cisco support, who have to take care of it. Even if there was a lot of effort in the community to create tools or processes to debug iOS. And if you're looking for a way to debug Cisco to iOS, there are a lot of tutorials available, like patching an old version of GDB that still supports iOS, but it doesn't work. And I tried it, but the only thing I could do was to read the memory, to do the tracing, but it doesn't work. Another way is to use a nice tool called iodid. It's a graphic debugger that we see on the screen. It really works, it's a great tool. But the problem is that it only supports PowerPC architecture. So there's probably a lot of patching for a specific device to make it work. And the last possibility is to create your own debugger. And for that, you have to know the commands that Cisco supports. So we can make a read memory and write memory. So we can make a read memory, read memory, write memory, list the instructions, read and write the recording commands. So we have command examples. It's pretty simple to create a debugger because all the commands are sent in text, in readable, through the connection series. So in this way, I was able to create a Python script with Capstone to be able to debug iOS. We can inspect the records, there's a breakpoint management. So we can move forward, back and possibly empty the memory. So to find the SMMP overflow in the code, basically you can follow, since we have all the string cross-references, you can follow the strings that reference them. You get a request and just step until you enter the code. But a more efficient method is just to do it. And to crash the device. And to inspect the stack, once the machine has already crashed. Some of them will return addresses, and you will even get your hands on them. And you will find the crash. In fact, the crash took place somewhere between the addresses 0 and 6. And we had the value in the RA register. You have to know that almost all the functions in MIPS return a value. So we had the space in the stack. And to place a shell code, and to execute it, maybe. This problem is that the stack is something unpredictable. There is no space to normally load in the stack in the firmware. There is no instruction in the stack that allows you to address a particular space. No instruction at LSR. This means that we would not know what address to jump to execute the code. The data part is divided into several sets. And we could crash as soon as we would start executing the code. So, this is the first time I encountered an ASLR. It's the first time I saw this randomization at the iOS level. In the vulnerability I saw before and the problems we were talking about the diversity of firmware. So there were so many versions of firmware and to exploit a vulnerability, we could not go directly to the code because of all these firmware versions that were made by many different people. But here we have the ASLR with the text and the data part which are loaded with two different offsets after each reboot. The second thing after the offset is the cache part of the data. Everything is written in the cache. We have the garbage instruction part that is sent to the cache so this is basically a data execution prevention. Well, it's not, it's a cache, but... It's not a problem of execution of the code, it's a problem of cache use. But unfortunately we still have ASLR so we can't really jump to anything because it's not... So we can't really jump to anything because of the offset. The ROM monitor, I was talking about, helps our rescue. So this little piece of software that gets loaded before the actual firmware might actually help us. This little function could help us. It's a function of the ROM of the firmware. And the interesting feature of this ROM monitor is that the ROM-mon show is actually allowing you to disassemble all the true memory parts. And darken the disassembly and then there's the address. You will get a stack trace revealing the actual address of the ROM monitor. And what's the most interesting thing is that the ROM-mon is located at DL00s or you can just search the internet for the most important part about this from where... is that the ROM monitor is located at the same address system across reboots. And it's really great because we can use it for building ROM chains. It turns out that ROM-mon is always located at the same place in memory despite the different reboots. That means that it can be used to create a European chain. We can go to ROM-mon at a fixed address, an offset fixed. We use a code reuse. We cover the stack to allow the SNMP service to reuse. This is really important because we will be writing only four bytes. And then we will be able to use the code reuse to make the SNMP service use the code. It's important because we will only be able to use four bytes. So it's important that we won't be able to reuse the entire firmware. And once we have rewritten that in memory, we will be able to use the code reuse. So that's how it works. We overhaul the return address, so we jump to the ROM monitor. Then we do the overflow at the ROM-mon. Then we go to the ROM-monitor part. Then we do the writing of four bytes just before the text section. We can restore the legitimate SNMP to be able to recover SNMP information. We see here the flow of how we write our experience. What is return-oriented programming? The basic idea here is to not execute the shell code directly, but to use the binary code to execute information. So we use the stack as a data for the code that you're reusing. We use the stack as a source of data with the instructions that are used. So we use gadgets that are connected to each other by using the jump call rate instructions. So there are two actions that need to execute the payload, and it also needs to transfer the instructions that contain the information to transfer the flow of execution to the next gadget. The problems, the limitations in Europe are that we don't have as many gadgets as available. We're talking about ROM-monitor, so not a lot of code available. The second way is from the gadgets because most of them are function epilogues. They modify the stack frame, delete the local variables, and then we have to count the functions associated. So it's important because it can easily crash the vulnerability that you're trying to exploit. Basically, for us to do anything, but mostly, most of the times, we are working on a lot of things, but most of the time, we use to do arbitrary writing in memory, which can lead to an execution of arbitrary code. So the idea is to find a gadget that sends values, which are the other values of the stack at the level of the registers. So for example, we have a V0 register that contains the values that we want to write, and another gadget called S0 that has the addresses that we want to write. So we actually want to find a gadget that also loads information from the stack to go to the next gadget. So we don't have to look for these gadgets manually in IE, we don't have to check these gadgets manually. There are a lot of tools like Roper, for example, that we find on GitHub, and with adequate instructions that will allow you to build your ROPChain, the ROPChain that is required with the gadgets. Now, the next step in terms of how ROPChain works in our vulnerability, and then we will move on to the demo. So this is a perfectly healthy stack, with a frame. So we have local variables at the stack, we have a return address, and we have a vulnerable function at the level of our local variable. So that's what happens once we apply our ROP. So we do an overflow at the local variables, and these variables are probably written in S0 and S6 in the general registers. But we also have the part that will go to the ROM monitor, we overflow the stack frame and then we also go to the ROPChain. What we do here is that we take the value of S0, we control the value of S0, and we move it in the V0 register. So it's only for that, because we don't have other gadgets that use the S0 value to write data. So we have to use the V0 register value. Here we see that we have the return address that we load at the S0 level. And we also have the address at the level of ROP data 2 that returns. Now we have S0 that points to the memory, it contains 4 bytes, just before the code section that interests us. The gadget that is performing the arbitrary write is the gadget that takes the value of register V0 and reference it to a pointer referenced in S0. The last thing it does, actually, it will be to show back to the gadget to recover the data for us. After the gadget execution, it allows us to run the exploit several times. And for that, you will have to launch the exploit several times. This actually means that the process that we will return to will crash if we don't point the stack pointer. So we are looking for values that will allow us to move the pointer to the bottom to have a perfectly safe stack. And we also have the return value, RA, which symbolizes our return address of the valid function. So in this way, we can create a 4-bit writing without any problem, and we can do it several times. And the last thing we do is that we do an overflow of the stack once again. And then we go to the shell code. So what makes us go to the shell code part, the code section is editable. So there is no reason why we could not send code to the shell code. So we see here that we have a kind of authentication that will check if the user is verified or not. So for example here, we can create a function that will accept certain credentials at the level of the app. So what the shell code does is inspect the return address in it, the stack and the return address, to calculate the ASLR address, the offset of the offset ASLR. So we want to patch something at the ASLR level. And then it will write a zero, which is a check for a telnet password, for example, or for an active password. And then we will go to the SNMP service level. So now we are going to do a demo. We will see if I can do a live demo. All right, let's go. So here we have the serial connection to the device. We have a shell. So what we do now, we inspect the password on the telnet service to make sure it's password. So we see that that password, we don't know the valid password of the device. What we do now is we launch the actual exploit. As parameters, it takes the host, community and shell code in hex. So this is the shell code I was talking about that patches the code. So it's right. So here you see that we initiate writing the four bytes. So basically this writes the shell code into the memory. So let's see. So let's see. So let's see. So let's see. Please do not crash. Yes. So back to the slides. And of course you can build a shell code that will unset this behavior and match the process back to enable the password. But what can you exploit this vulnerability? So of course this exploit will be a community or the version of the particular router. But it does not. And we're basically constructing route chains in the ROM monitor. So actually you have not that many versions of ROM monitors available. So the worst case scenario is just you crash it four times. And you have to crash it 4,000 times to beat the ASLR. But there's a package to be able to charge the code. Which is interesting because we have only five versions we can crash it four times before finding the right firmware. And download a new version. So we can upgrade the ROM monitor. We have a special region to upgrade. A special place. And the ROM monitor is always located with the same offset. So even if we update the ROM monitor, the read-only version will always be located in the same place. The assumption is that all the devices in the manufacturer have the same time and place. They will have the same read-only ROM monitor. All the routers that have been manufactured at the same time will have this ROM monitor in the same place. So for example, we can check it with the serial number. So for example, my router here has the firmware version compared to the place where it was manufactured last year. So to sum up all this, don't let the passwords pass by default. Don't use public communities on devices that are exposed to the outside. Pay attention to what you expose on external networks. And of course you have to patch the devices. And you have to pay attention to devices that are end of life. And that don't have any support. Alright guys, thank you so much for your attention. So it was your French translation. Made by Ironic and David. Thank you so much for listening to us. If you have the least feedback, Twitter, at C3Lingo, or the hashtag C3T on Twitter. And now we will move on to questions. Questions in the room? Hi, I'm an admin network random. And I know that a lot of people use the same SNMP community on a lot of their devices. And to my knowledge, if you can access the router in read only, you can use the same principle to hack on all devices. So don't use the same community on all devices, that would be an idea. It's a patch to vulnerability. A patch was released in September of this year. So what's important is to update the routers, because that's a vulnerability of patches. So it's a patch that has been exploited. And it's enough to update. So the problem of using the same community shouldn't exist. Thank you. Another question? A question from the internet? How long have you learned this project? So working on this exploit took me about four weeks, between the discovery of the device until the creation of the final exploit. Thank you. I have a question maybe for you as well. I have a question for you as well. You have lots of volunteers who are working with you as well in researching these exports. Volunteers? I don't think we don't have any volunteers. This is all part of my work. I don't have a lot of volunteers working with me. It's part of my personal research. Thank you very much for this revealing lecture. This presentation is really, really enlightening. Is my mic on? So the actual proof concept and the debugger will be released in a few days. The proof of concept and the publication of this vulnerability will all be published this week. Thank you.