1 00:00:00,000 --> 00:00:15,065 *34c3 intro* 2 00:00:15,065 --> 00:00:30,130 Herald: All right, next lecture here is from Artem. Next to the fact that these, 3 00:00:30,130 --> 00:00:38,819 how would I spell it, earning a nice amount of money probably at a lab that's 4 00:00:38,819 --> 00:00:46,589 quite renown in the world as Kaspersky and from that point on he's not just looking 5 00:00:46,589 --> 00:00:52,539 in this lecture to exploit a development for Cisco stuff we all suffered from this 6 00:00:52,539 --> 00:00:57,609 last year or we all heard about it and don't know the impact maybe, but he's 7 00:00:57,609 --> 00:01:05,019 going to explain us the work he did on that field so please can I ask your warm 8 00:01:05,019 --> 00:01:14,299 welcoming applause for Artem Kondratenko, do you, okay good, please give him a warm 9 00:01:14,299 --> 00:01:21,960 applause and start. *applause* 10 00:01:21,960 --> 00:01:26,149 Artem Kondratenko: Hello everyone, so excited to finally be able to attend Chaos 11 00:01:26,149 --> 00:01:31,880 Communication Congress. Very happy to see y'all. So without further ado let's jump 12 00:01:31,880 --> 00:01:38,229 into some practical IOS exploitation. So a few words about myself, my name is Artem, 13 00:01:38,229 --> 00:01:43,659 I do stuff, mostly security related stuff but mostly my areas of expertise are 14 00:01:43,659 --> 00:01:48,869 penetration tests, both internal external and also do research in my free time and 15 00:01:48,869 --> 00:01:54,289 get a bug bounty here and there and this talk is actually kind of a continuation of 16 00:01:54,289 --> 00:01:59,729 my talk this summer at Def Con about Cisco Catalyst exploitation. 17 00:01:59,729 --> 00:02:04,600 So for those of you who are out of context, let's recap what happened earlier 18 00:02:04,600 --> 00:02:14,450 this year. So year 2017 was reaching vulnerabilities for Cisco IOS devices. So 19 00:02:14,450 --> 00:02:20,140 we had at least three major advisories for Cisco IOS that represented three remote 20 00:02:20,140 --> 00:02:24,280 code execution vulnerabilities. So the first one is vulnerability in 21 00:02:24,280 --> 00:02:30,600 cluster management protocol which resulted in unauthenticated remote code 22 00:02:30,600 --> 00:02:36,560 execution via telnet, second one is SNMP overflow and the DHCP remote code 23 00:02:36,560 --> 00:02:40,310 execution. In this lecture I'm gonna be talking 24 00:02:40,310 --> 00:02:47,060 about two of those vulnerabilities because DHCP RCE is yet to be researched. So 25 00:02:47,060 --> 00:02:51,880 hopefully by the end of this talk I'm going to be able to show you a live demo 26 00:02:51,880 --> 00:02:56,810 of exploiting the SNMP service in Cisco IOS. 27 00:02:56,810 --> 00:03:05,870 So but first what happened earlier: So on March 26, 2017 we had a major advisory from 28 00:03:05,870 --> 00:03:10,790 Cisco that announcing that hundreds of models of different switches are 29 00:03:10,790 --> 00:03:15,230 vulnerable to remote code execution vulnerability. No public code, no public 30 00:03:15,230 --> 00:03:21,070 exploit was available and no exploitation in the wild. So it was critical and main 31 00:03:21,070 --> 00:03:24,380 points of the vulnerability were as follow: 32 00:03:24,380 --> 00:03:30,970 So Cisco switches can be clustered, and there's a cluster management protocol 33 00:03:30,970 --> 00:03:36,430 built on top of telnet, and this vulnerability is a result of actually two 34 00:03:36,430 --> 00:03:43,880 errors, a logic error and a binary error. So the telnet options get parsed 35 00:03:43,880 --> 00:03:49,940 regardless whether the switch is in cluster mode or not and the incorrect 36 00:03:49,940 --> 00:03:56,560 processing of this cluster management protocol options result in overflow. So 37 00:03:56,560 --> 00:04:00,980 what is interesting about this vulnerability that actually the source of 38 00:04:00,980 --> 00:04:06,010 research for Cisco guys was another internal research. But the "Vault 7" leak 39 00:04:06,010 --> 00:04:13,210 that happened in March this year so many hacking techniques and tools were released 40 00:04:13,210 --> 00:04:20,440 to public by WikiLeaks, and among many vendors that were affected was Cisco 41 00:04:20,440 --> 00:04:25,090 Systems. So basically except for the advisory you 42 00:04:25,090 --> 00:04:30,240 could go to WikiLeaks and read about this potential exploitation technique for Cisco 43 00:04:30,240 --> 00:04:35,490 Catalyst. So basically these were notes of an engineer who was testing the actual 44 00:04:35,490 --> 00:04:43,750 exploit, there were no actual exploit in the leak. So basically this worked as 45 00:04:43,750 --> 00:04:49,210 follows: there was two modes of interaction, so for example an attacker 46 00:04:49,210 --> 00:04:55,330 could connect to the telnet, overflow the service and be presented with a privileged 47 00:04:55,330 --> 00:05:02,860 15 shell. The other mode of operation was the … is to set for all the subsequent 48 00:05:02,860 --> 00:05:08,790 … connections to the telnet, there will be … without credentials so I 49 00:05:08,790 --> 00:05:14,620 did. We discover this exploit, full research was presented at DEFCON 25. I was 50 00:05:14,620 --> 00:05:20,620 targeting system catalyst 2960 as a target switch. I also described a PowerPC 51 00:05:20,620 --> 00:05:25,340 platform exploitation and the way you can debug it. 52 00:05:25,340 --> 00:05:31,430 You can look at my blog post about exploiting this service, and also the 53 00:05:31,430 --> 00:05:37,530 proof accounts of exploit on my github page. But today I want to talk about 54 00:05:37,530 --> 00:05:42,200 something else, about another vulnerability that was announced this year 55 00:05:42,200 --> 00:05:49,490 about SNMP remote code execution. So the actual motivation behind this 56 00:05:49,490 --> 00:05:55,840 research was that I was conducting an external pentest, and it was revealed an 57 00:05:55,840 --> 00:06:00,510 nmap scan revealed that a Cisco router where the default community string was 58 00:06:00,510 --> 00:06:07,090 available. So the goal was to get access to the internal network. 59 00:06:07,090 --> 00:06:13,450 So the actual advisory said that the attacker needs a read-only community 60 00:06:13,450 --> 00:06:19,700 string to gain remote code execution on the device. The target router was a 2800 61 00:06:19,700 --> 00:06:26,650 integrated services router, which is a very common device on the networks. 62 00:06:26,650 --> 00:06:34,389 So the technical specs for it is it's a it has a MIPS big endian architecture, you 63 00:06:34,389 --> 00:06:39,990 don't have any client debugging tools for it available, and it's interesting in that 64 00:06:39,990 --> 00:06:46,919 sense that the firmware is relatively new for this router, and it might be 65 00:06:46,919 --> 00:06:52,771 interesting to look at the defensive end exploit prevention mechanisms employed by 66 00:06:52,771 --> 00:06:59,370 Cisco IOS. When I say relatively new is the interesting thing is that this device 67 00:06:59,370 --> 00:07:04,040 is actually end of support, it's not supported. So the last patch for it was 68 00:07:04,040 --> 00:07:12,360 came out at 2016, and to remind you the advisory for SNMP overflow appeared in 69 00:07:12,360 --> 00:07:19,040 2017, in June 2017, but nonetheless this is still widely used device. 70 00:07:19,040 --> 00:07:27,760 If you search for SNMP banner on Shodan, you will find at least 3000 devices with 71 00:07:27,760 --> 00:07:37,550 SNMP service available with default public string. So this devices are all supposedly 72 00:07:37,550 --> 00:07:43,710 vulnerable to SNMP overflow. And the question is whether we can build a mount 73 00:07:43,710 --> 00:07:49,140 code execution exploit for it. So since we're going to be exploiting SME protocol, 74 00:07:49,140 --> 00:07:54,460 let's make a quick quick recap of how it works, just light touch. 75 00:07:54,460 --> 00:08:01,930 So SNMP comes with several abbreviations like MIB, which stands for management 76 00:08:01,930 --> 00:08:07,919 information base, and is kind of a collection of objects that can be 77 00:08:07,919 --> 00:08:12,860 monitored from the SNMP manager. And so a management information base actually 78 00:08:12,860 --> 00:08:21,370 consists of object identifiers. And as an example: you all know that printers 79 00:08:21,370 --> 00:08:25,550 usually use SNMP, For example if there is a certain level of ink in the cartridge, 80 00:08:25,550 --> 00:08:31,729 you can query the SNMP service on this device for the percentage of ink left. So 81 00:08:31,729 --> 00:08:39,179 that's a kind of example how it works. Management information base looks like a 82 00:08:39,179 --> 00:08:42,219 tree. So you have your base element at the top 83 00:08:42,219 --> 00:08:47,839 and your leaf elements, So all these elements represent an object that could be 84 00:08:47,839 --> 00:08:53,509 queried. We're going to be looking at get requests. And that is why the advisory 85 00:08:53,509 --> 00:08:57,790 states that for their vulnerability to be triggered you only have to know the read- 86 00:08:57,790 --> 00:09:03,110 only community string. So it's a relatively simple protocol, you just 87 00:09:03,110 --> 00:09:08,199 supply the object identifier you're querying and you'll get back the result. 88 00:09:08,199 --> 00:09:14,999 So here for example we get the router version, the description field. And you 89 00:09:14,999 --> 00:09:24,170 can also do this with a readily available Linux tools like snmpget. So before we 90 00:09:24,170 --> 00:09:28,629 will build an exploit, we have a starting point. So how do we look for for the 91 00:09:28,629 --> 00:09:35,110 crash? So the advisory actually states that there are nine different vulnerable 92 00:09:35,110 --> 00:09:41,399 management information bases and you only have to know the read-only community string. 93 00:09:41,399 --> 00:09:50,089 So for the fuzzing to be done I'll be using Scapy as a tool to as a toolkit to 94 00:09:50,089 --> 00:09:54,310 work with network protocols, and here you can see that I'm building an object 95 00:09:54,310 --> 00:09:59,160 identifier, a valid object identifier that references the description field, and then 96 00:09:59,160 --> 00:10:04,921 I'm appending some letters "a" which is 65 in ASCII table. Then I build an IP packet, 97 00:10:04,921 --> 00:10:12,149 I build a UDP packet and an SNMP packet inside of it with community string public 98 00:10:12,149 --> 00:10:17,320 and object identifier. So of course this will not trigger the 99 00:10:17,320 --> 00:10:23,589 overflow, because this object identifier is completely fine. How do we get all the 100 00:10:23,589 --> 00:10:28,670 object identifiers that our router will respond to? So basically there are two 101 00:10:28,670 --> 00:10:36,230 ways: you can take the firmware and just extract all the OIDs from it. It's easy to 102 00:10:36,230 --> 00:10:43,670 grab them, they're stored in plain text. Another way is to actually look at the 103 00:10:43,670 --> 00:10:52,399 vulnerable MIBs and visit the website OID views and get all object identifiers from 104 00:10:52,399 --> 00:10:59,399 this website. So as a matter of fact the first crash I had was in ciscoAlpsMIB, 105 00:10:59,399 --> 00:11:08,959 which is kind of related to airplane protocol, which does not concern us because it's not 106 00:11:08,959 --> 00:11:16,759 a focus of our exploitation. So the actual overflow was in one of its 107 00:11:16,759 --> 00:11:23,290 object identifiers. So this request this I actually crashed the router when you 108 00:11:23,290 --> 00:11:30,480 connect to the Cisco router of via a serial cable you will be and there's a 109 00:11:30,480 --> 00:11:36,480 crash you will be presented with a stack trace. So we see here that we got a 110 00:11:36,480 --> 00:11:45,890 corrupted program counter, and we also see the state of registers that we have at the 111 00:11:45,890 --> 00:11:55,270 moment of crash. So here you can see that we have control of a program counter, it's 112 00:11:55,270 --> 00:12:04,110 called EPC, and also we control the contents of registers s0, s1, s2, s3, s4, 113 00:12:04,110 --> 00:12:08,160 s5, s6. Further inspection also provided me with 114 00:12:08,160 --> 00:12:14,959 knowledge that we have 60 spare bytes on the stack to work with. But before we 115 00:12:14,959 --> 00:12:20,369 build we exploit we have some problems, issues to be solved. 116 00:12:20,369 --> 00:12:26,149 And that is: yes, we do control the program counter, but where do we jump to? 117 00:12:26,149 --> 00:12:34,880 Is ASLR on? Can we execute shellcode directly on the stack? Is stack 118 00:12:34,880 --> 00:12:42,660 executable? If we can place the shellcode on it, is data caching a problem for us? 119 00:12:42,660 --> 00:12:49,179 And if we launched our shellcode, can we just bash the code? Is the code section 120 00:12:49,179 --> 00:12:54,060 writable? Is the code integrity check on? But the most important question is: how 121 00:12:54,060 --> 00:12:59,119 can we return the code flow back to the SNMP service? 122 00:12:59,119 --> 00:13:07,930 Because IOS is a single binary running in the memory, and if you have an exception 123 00:13:07,930 --> 00:13:15,019 in any thread of this big binary, the Cisco device will crash. And if we look at the 124 00:13:15,019 --> 00:13:16,829 advisory, one of the indicators of 125 00:13:16,829 --> 00:13:23,129 compromised Cisco states is device reload, so exploitation of the vulnerabilities 126 00:13:23,129 --> 00:13:29,499 will cause an affected device to reload. We will build an exploit we'll try to 127 00:13:29,499 --> 00:13:36,110 build an exploit that will not crash the SNMP service on it. Before we dive deeper 128 00:13:36,110 --> 00:13:45,149 into the firmware I want to reference previous researches on this matter. This 129 00:13:45,149 --> 00:13:53,670 is by no means a complete list but these researchers actually helped me a lot and 130 00:13:53,670 --> 00:14:00,899 seemed interesting and very insightful to me. You should definitely check them out 131 00:14:00,899 --> 00:14:07,029 so for example "Router Exploitation" by Felix FX Lindener and "CISCO IOS 132 00:14:07,029 --> 00:14:12,079 SHELLCODE" by George Nosenko is a great resource for IOS internals and great 133 00:14:12,079 --> 00:14:16,699 reference to how IOS works in terms of exploitation 134 00:14:16,699 --> 00:14:22,499 and the third resource "How to cook Cisco" is a great info on exploiting 135 00:14:22,499 --> 00:14:29,189 PowerPC-based Cisco switches and also great info on bypassing common mechanisms 136 00:14:29,189 --> 00:14:38,129 and exploit prevention stuff in IOS. So basically if I were to tell you how IOS 137 00:14:38,129 --> 00:14:42,929 works in one slide it's basically a single binary running in memory. Everything is 138 00:14:42,929 --> 00:14:50,860 statically linked into a single ELF file which gets loaded on startup, of course 139 00:14:50,860 --> 00:14:57,720 you have no API whatsoever. Everything has no symbols whatsoever. Yes, there is a 140 00:14:57,720 --> 00:15:03,579 glibc library at the end of the firmware but it's also kind of hard to use it 141 00:15:03,579 --> 00:15:10,170 because you have so many different versions of firmware and the offsets jump 142 00:15:10,170 --> 00:15:14,310 and you don't know the exact location of those functions. So to start with static 143 00:15:14,310 --> 00:15:19,209 analysis you should probably copy the firmaware from the flash memory of the 144 00:15:19,209 --> 00:15:27,589 router. Use the copy command, it supports TFTP and FTP protocols so you download 145 00:15:27,589 --> 00:15:32,439 this firmware, the next thing you do is unpack the firmware. The firmware itself, 146 00:15:32,439 --> 00:15:38,949 when the router starts loading it, has an initial stop that does the unpacking but 147 00:15:38,949 --> 00:15:43,779 you don't have to reverse engineer that, you just use binwalk, that will do the 148 00:15:43,779 --> 00:15:53,259 unpacking for you. You load the result of unpacking with binwalk to IDA Pro, you 149 00:15:53,259 --> 00:15:58,420 have to change the processor type to MIPS 32 big-endian and we know that this is 150 00:15:58,420 --> 00:16:05,139 MIPS, because we saw the registers. These registers tell us that it was indeed MIPS 151 00:16:05,139 --> 00:16:13,040 architecture. So one thing I want to note, the actual firmware gets loaded into 152 00:16:13,040 --> 00:16:20,519 address 800F00 but the program counter is located at address 4 and this is because 153 00:16:20,519 --> 00:16:29,089 IOS when it loaded the firmaware transfers, I mean maps to memory 2400F00 154 00:16:29,089 --> 00:16:35,120 and this is important because to have correct cross references in IDA Pro you 155 00:16:35,120 --> 00:16:43,220 have to rebase your program to 4 and after that you will have all correct string 156 00:16:43,220 --> 00:16:48,929 cross-references. We will have all the necessary strings and your static analysis 157 00:16:48,929 --> 00:16:56,009 setup will be complete. But in order to build an exploit it will not suffice to 158 00:16:56,009 --> 00:17:00,740 only have the, you know, IDA Pro loaded with the firmware with all the cross 159 00:17:00,740 --> 00:17:07,140 references, you probably want to, you know, set up a debug environment. It is 160 00:17:07,140 --> 00:17:14,689 well known that IOS can be debugged via a serial port and actually there's a "gdb 161 00:17:14,689 --> 00:17:23,109 kernel" command that is used to start the internal gdb server, or it was because 162 00:17:23,109 --> 00:17:29,139 functionality was removed in the recent versions of IOS and you can't really run 163 00:17:29,139 --> 00:17:38,950 the gdb. But nonetheless there's a way to enable the gdb and this way is to reboot 164 00:17:38,950 --> 00:17:46,389 the device, send an escape sequence to the serial line, this will bring up the rom 165 00:17:46,389 --> 00:17:52,500 monitor shell so rom monitor is a simple piece of firmware that gets loaded and run 166 00:17:52,500 --> 00:17:59,720 just before your firmware starts running and in this ROMMON you can manually boot 167 00:17:59,720 --> 00:18:08,950 your firmware with a flag and which will launch the whole firmware under gdb. And 168 00:18:08,950 --> 00:18:17,980 after your firmware is loaded, the gdb will kick in. Now you can't just use your 169 00:18:17,980 --> 00:18:25,919 favorite gdb debugger and Linux and connect it to IOS via a serial port 170 00:18:25,919 --> 00:18:35,000 because IOS uses a slightly different subset of commands of gdb protocol. It has 171 00:18:35,000 --> 00:18:43,679 a server-side gdb but the client side should be accustomed to this gdb server. 172 00:18:43,679 --> 00:18:48,630 Basically there is no publicly and officially available client-side debugging 173 00:18:48,630 --> 00:18:56,300 tools for IOS and that is because this is intended for Cisco engineers for to be 174 00:18:56,300 --> 00:19:02,240 done. Although there have been some efforts from the community to build tools 175 00:19:02,240 --> 00:19:08,750 to debug several versions of routers and switches with IOS and if you look for ways 176 00:19:08,750 --> 00:19:15,929 to debug Cisco IOS you will find, you most definitely will find a tutorial that says 177 00:19:15,929 --> 00:19:21,610 that you can actually patch an old version of gdb that still supports IOS, but it 178 00:19:21,610 --> 00:19:26,120 actually never works because I tried it and all I could do is read memory, the 179 00:19:26,120 --> 00:19:34,950 stepping, the tracing, it just doesn't work. So another way is to use a cool tool 180 00:19:34,950 --> 00:19:42,389 by NCC group, it's called IODIDE, it's a graphical debugger for IOS, it really 181 00:19:42,389 --> 00:19:48,769 works, it's a great tool, but the thing is it is only, it targets PowerPC 182 00:19:48,769 --> 00:19:54,830 architecture and it has some some problems you probably have to patch the debugger to 183 00:19:54,830 --> 00:19:58,639 be able to work with it and the third option, the last resort 184 00:19:58,639 --> 00:20:05,380 is to implement your own debugger for the router. And to do that you have to know 185 00:20:05,380 --> 00:20:12,370 which commands actually Cisco supports, and not a lot, so you can basically read 186 00:20:12,370 --> 00:20:18,520 memory and write memory and set and write registers and the only program counter 187 00:20:18,520 --> 00:20:25,230 control command is a step instruction. So basically it's kind of easy to implement 188 00:20:25,230 --> 00:20:31,870 such a debugger because all the information is just sent as a plain text 189 00:20:31,870 --> 00:20:40,820 over a serial cable and appended with a checksum which is just a CRC. So this way 190 00:20:40,820 --> 00:20:48,179 I was able to, you know, make a quick Python script using Capstone to be able to 191 00:20:48,179 --> 00:20:55,450 debug IOS, you can inspect registers, there's a basic breakpoint management, you 192 00:20:55,450 --> 00:21:02,169 just write a special control double word to be able to break. You can step over a 193 00:21:02,169 --> 00:21:06,789 step over step into and also a good feature is to be able to dump memory, which we will 194 00:21:06,789 --> 00:21:15,170 use later. So to find the overflow, the SNMP overflowing the code, how do you do 195 00:21:15,170 --> 00:21:20,840 it? Basically you can follow, since we have all the string cross-references, you 196 00:21:20,840 --> 00:21:28,960 can follow the strings, that reference SNMP get requests and just step until the 197 00:21:28,960 --> 00:21:35,139 crash, but a more efficient method is just to crash the device and start inspecting 198 00:21:35,139 --> 00:21:41,570 the stack after the device is already crashed. You just have to dump some memory 199 00:21:41,570 --> 00:21:47,180 on the stack and look into the values that reference the code, some of them will be 200 00:21:47,180 --> 00:21:58,809 return addresses and this will give you a hint where the crash actually is. So the 201 00:21:58,809 --> 00:22:03,500 actual program counter corruption happens in the function epilog, I call this 202 00:22:03,500 --> 00:22:12,549 function snmp_stack_overflow, so you can see here that at the end of a function we 203 00:22:12,549 --> 00:22:18,720 load the values from the stack to registers $s0 to $s6 and also we load 204 00:22:18,720 --> 00:22:24,610 value into register $ra and this is an important register, it's called a return 205 00:22:24,610 --> 00:22:31,049 address register and almost every function in MIPS uses this register to jump back to 206 00:22:31,049 --> 00:22:39,779 its parent function. So basically we have some space on the stack, but the question 207 00:22:39,779 --> 00:22:47,789 is can we place our shellcode on this on the stack? And can we execute it? Because, 208 00:22:47,789 --> 00:22:51,789 you know, stack location is unpredictable, every time you trigger this 209 00:22:51,789 --> 00:22:57,370 vulnerability a separate space on the stack is allocated and you cannot really 210 00:22:57,370 --> 00:23:04,679 predict it. So, no valid jump to stack instructions in the firmware like we did 211 00:23:04,679 --> 00:23:11,980 on Intel x86 like jump ESP. No such instructions in the firmware, but even if 212 00:23:11,980 --> 00:23:19,131 we could find such an instruction, the address space layout randomization (ALSR) 213 00:23:19,131 --> 00:23:26,070 is on, which means the code section and data section is based on different offsets 214 00:23:26,070 --> 00:23:31,789 each time we reboot the device, which means that we can't reliably jump to the 215 00:23:31,789 --> 00:23:39,950 instruction. And also an unfortunate thing is that data caching is also in place. So, 216 00:23:39,950 --> 00:23:49,309 about ASLR, this is the first first time I encountered the randomization in IOS. 217 00:23:49,309 --> 00:23:56,120 Previous researchers, that I've been doing with, they said a lot about diversity of 218 00:23:56,120 --> 00:24:01,919 the firmware. So, basically you had so many different versions of firmware when 219 00:24:01,919 --> 00:24:07,139 you exploited the Cisco device it couldn't really reliably jump to any code because 220 00:24:07,139 --> 00:24:11,940 there's so a vast diversity of different firmware that was built by different 221 00:24:11,940 --> 00:24:17,990 people but here we actually have the stack address based randomization and the text 222 00:24:17,990 --> 00:24:26,110 section and data section is loaded on different offsets after each reboot. So, 223 00:24:26,110 --> 00:24:32,929 another thing that really upsets us is data caching, so when we write our shell 224 00:24:32,929 --> 00:24:38,580 code to stack, we think that it will be on the stack but what actually happens, 225 00:24:38,580 --> 00:24:43,070 everything gets written into data cache and when we place our program counter to 226 00:24:43,070 --> 00:24:51,140 the stack we get executing garbage instructions which results in a crash once 227 00:24:51,140 --> 00:24:58,539 again. So this problem this is basically a data execution prevention, well it's not 228 00:24:58,539 --> 00:25:06,150 it's a it's a cache but the solution to this problem is the same as for data 229 00:25:06,150 --> 00:25:12,419 execution prevention and it is return oriented programming, so but unfortunately 230 00:25:12,419 --> 00:25:21,139 we still have ASLR so we can't really jump to anything because it's on a random 231 00:25:21,139 --> 00:25:28,580 offset but here the rom monitor, that I was talking about comes to our rescue. So 232 00:25:28,580 --> 00:25:34,620 this little piece of software that gets loaded before the actual firmware might 233 00:25:34,620 --> 00:25:40,149 actually help us. So the first thing we want to find where 234 00:25:40,149 --> 00:25:45,549 this bare-bones firmware is located and the interesting feature of 235 00:25:45,549 --> 00:25:52,740 this ROMMON shell, it's actually allowing you to disassemble arbitrary memory parts 236 00:25:52,740 --> 00:25:59,179 and if you target the disassembler at an invalid address you will get a stack trace 237 00:25:59,179 --> 00:26:06,039 revealing the actual address of the rom monitor. And what's the most interesting 238 00:26:06,039 --> 00:26:13,070 thing as the rom monitor is located at bfc0000 and you can dump it using the 239 00:26:13,070 --> 00:26:19,070 debugger or you can just search the internet for the version and download it. 240 00:26:19,070 --> 00:26:28,620 The most interesting part about this piece of firmware, is that rom monitor is 241 00:26:28,620 --> 00:26:34,470 located at the same address and it's persistent across reboots and it's really 242 00:26:34,470 --> 00:26:41,610 great because we can use it for building ROP chains inside of it. So now we have a 243 00:26:41,610 --> 00:26:49,610 theoretical possibility of circumventing ASLR, defeating the cache problem. So how 244 00:26:49,610 --> 00:26:56,190 do we build an exploit, so the overview is as follows: we jump to ROMMON, we initiate 245 00:26:56,190 --> 00:27:02,929 a ROP chain, which makes an arbitrary write using the code reuse technique and 246 00:27:02,929 --> 00:27:10,669 after that we have to recover the stack frame to allow the SNMP service to restore 247 00:27:10,669 --> 00:27:16,049 the legitimate code flow. This is really important because we will be writing only 248 00:27:16,049 --> 00:27:22,470 four bytes and that is not enough for a full fledged shellcode and if we don't 249 00:27:22,470 --> 00:27:28,529 crash SNMP we can exploit this vulnerability over and over again, thus 250 00:27:28,529 --> 00:27:33,090 building a shellcode in the memory. So after we build the shellcode we make a 251 00:27:33,090 --> 00:27:44,289 jump to it. So, here's how it works: we overflow the stack, we overflow the return 252 00:27:44,289 --> 00:27:51,779 address so it points to rom monitor, we jump to the rom monitor, then what we do 253 00:27:51,779 --> 00:27:57,680 we actually find a gadget that reuses the data on our stack to make an arbitrary 254 00:27:57,680 --> 00:28:04,499 four byte write just before the text section. Then we have to find a gadget 255 00:28:04,499 --> 00:28:11,529 that will recover stack for us so we can restore the legitimate SNMP execution call 256 00:28:11,529 --> 00:28:19,730 flow. So this is basically an overview of one cycle of how we write a four byte 257 00:28:19,730 --> 00:28:27,970 double word. Now, a little bit on building ROP chains, so what is it? what is return 258 00:28:27,970 --> 00:28:38,179 oriented programming? So basically the idea is to not execute the shellcode 259 00:28:38,179 --> 00:28:45,389 directly but is to use existing code in the binary to execute your 260 00:28:45,389 --> 00:28:52,200 payload. So you use stack not as a source of instructions but you use stack as data 261 00:28:52,200 --> 00:28:59,720 for the code that you're reusing. So basically you change the snippets of code 262 00:28:59,720 --> 00:29:07,720 we call them gadgets and you chain them together with jump or call instructions 263 00:29:07,720 --> 00:29:17,159 and candidate gadgets has to meet two requirements: It has to actually execute 264 00:29:17,159 --> 00:29:22,820 our payload and also it also has to contain instructions that will transfer 265 00:29:22,820 --> 00:29:28,340 execution flow to the next gadget or, if it's the last gadget it should transfer 266 00:29:28,340 --> 00:29:37,780 execution back to the SNMP service. The problems with the return oriented approach 267 00:29:37,780 --> 00:29:42,419 is that there is a limited set of gadgets available, so if you're talking about the 268 00:29:42,419 --> 00:29:46,980 firmware it's around 200 megabytes of code so there are plenty of different gadgets 269 00:29:46,980 --> 00:29:51,330 there, if we're talking about a rom monitor it's only 500 kilobytes of code, 270 00:29:51,330 --> 00:29:58,669 so not a lot of code available and the second major problem is that gadgets, 271 00:29:58,669 --> 00:30:04,549 because most of them are function epilogues, they modify the stack frame 272 00:30:04,549 --> 00:30:09,409 because they delete the local variables after they jump back to the parent 273 00:30:09,409 --> 00:30:15,790 function and you have to account for that because this, my crash, the process you 274 00:30:15,790 --> 00:30:23,720 are exploiting. ROP chains can be basically forced to do anything but 275 00:30:23,720 --> 00:30:31,419 mostly, most of the times we do arbitrary memory writes and this actually might lead 276 00:30:31,419 --> 00:30:39,600 to arbitrary code execution. So the idea for for looking for gadgets is that you 277 00:30:39,600 --> 00:30:46,200 find a gadget that loads data from the stack into the registers and then you find 278 00:30:46,200 --> 00:30:50,580 a second gadget that works with the data in the, in those pages for example you 279 00:30:50,580 --> 00:30:58,399 have one register $v0 which contains the value you want to write and the other 280 00:30:58,399 --> 00:31:09,929 gadget $s0 which has the address you want to write to. So we actually want to find 281 00:31:09,929 --> 00:31:15,659 gadgets that also load data from stack to return registers so we can jump to the 282 00:31:15,659 --> 00:31:24,159 next gadget. I don't have to look for these gadgets manually in IODIDE, in there 283 00:31:24,159 --> 00:31:29,860 are a lot of different tools for building ROP chains, one of those tools is Ropper 284 00:31:29,860 --> 00:31:32,480 you can find it on GitHub it's a really handy tool. 285 00:31:32,480 --> 00:31:36,379 You just search for necessary instructions to build 286 00:31:36,379 --> 00:31:48,669 the necessary ROP chain. So now the last technical part of how the ROP chains in 287 00:31:48,669 --> 00:31:54,940 this particular exploit work and then we'll get to the demo. So this is how a 288 00:31:54,940 --> 00:32:02,830 perfectly, you know, healthy stack frame looks like. So you basically have local 289 00:32:02,830 --> 00:32:07,499 variables on the stack, you have return adress, you also have a stack frame of 290 00:32:07,499 --> 00:32:13,389 parent functions underneath the stack frame of our vulnerable function. So when 291 00:32:13,389 --> 00:32:19,679 we overflow the local variables with our long object identifier here's what 292 00:32:19,679 --> 00:32:27,769 happens: We overflow the local variables and these variables actually partly get 293 00:32:27,769 --> 00:32:34,210 written to $s0 and $s6 general purpose registers we also, of course overflow the 294 00:32:34,210 --> 00:32:41,299 return address, which will jump for us to rom monitor and we also have some 60 295 00:32:41,299 --> 00:32:46,590 bytes, after that we overflow the stack frame of the next function and we use that 296 00:32:46,590 --> 00:32:54,970 data also for our ROP chain. What we do here, we take the value of $a0, we control 297 00:32:54,970 --> 00:33:01,919 the value of $a0 as you remember and we move it to register $v0 and that's for 298 00:33:01,919 --> 00:33:10,039 only solely purpose because there are no other gadgets in rom monitor that use $s0 299 00:33:10,039 --> 00:33:16,510 as a target register to write data so we have to use register $v0. After that the 300 00:33:16,510 --> 00:33:22,279 most important part is that we load the return address from the ROP data too and 301 00:33:22,279 --> 00:33:31,289 also we load the address we will write to from the ROP data too. So basically right 302 00:33:31,289 --> 00:33:40,539 now after this gadget stops executing we have $s0 points to a memory we want to 303 00:33:40,539 --> 00:33:49,700 write to and $v0 contains 4 bytes we will be writing just before the code section. 304 00:33:49,700 --> 00:33:57,649 So the final gadget that is performing the arbitrary write is the gadget that takes 305 00:33:57,649 --> 00:34:08,190 the value of register $v0 and writes it to a pointer reference that referenced by 306 00:34:08,190 --> 00:34:15,040 register $s0 and the last thing it does actually transfers the control back to the 307 00:34:15,040 --> 00:34:22,150 gadget, which will recover the stack for us. Most important gadgets it allows us to 308 00:34:22,150 --> 00:34:28,139 run the exploit several times, you might have noticed that the previous gadgets 309 00:34:28,139 --> 00:34:36,460 actually moved the stack pointer 30 bytes and hacks down them down the 310 00:34:36,460 --> 00:34:38,360 stack and this actually means 311 00:34:38,360 --> 00:34:44,510 that the process that we will return to will crash if we don't point the stack 312 00:34:44,510 --> 00:34:50,770 pointer just between two stack frames. We find a gadget that will move the stack 313 00:34:50,770 --> 00:35:00,340 pointer down to 228 bytes in hex, which will result in a perfectly healthy stack. 314 00:35:00,340 --> 00:35:08,690 Also we load the return address to register $ra and it points to the parent 315 00:35:08,690 --> 00:35:16,660 function that called our own vulnerable function so this way we perform an 316 00:35:16,660 --> 00:35:22,850 arbitrary four byte write. We can do this several times until our shellcode is 317 00:35:22,850 --> 00:35:28,350 actually built, just before the text section and the final thing we do, we 318 00:35:28,350 --> 00:35:34,850 overflow the stack again and jump to the shellcode. A few words about the 319 00:35:34,850 --> 00:35:45,910 shellcode: The device I was working with had a telnet service and it had a password, so I 320 00:35:45,910 --> 00:35:52,150 designed a simple shell code that will just patch the authentication call flow. 321 00:35:52,150 --> 00:35:58,610 So as you can see here we have a function "login password check" and a result which 322 00:35:58,610 --> 00:36:09,170 is in $v0 register is checked whether the authentication was successful or not. We 323 00:36:09,170 --> 00:36:13,700 can build a shell code which which will just patch this instruction which checks 324 00:36:13,700 --> 00:36:19,900 "login password check" and it will allow us to make a credential list 325 00:36:19,900 --> 00:36:29,780 authentication against telnet service. So what it does: basically the shell code 326 00:36:29,780 --> 00:36:35,780 inspects the stack and the return address in it to calculate the ASLR offset 327 00:36:35,780 --> 00:36:43,170 because, of course the ASLR is on for the code section and we want to patch 328 00:36:43,170 --> 00:36:52,470 something in it and after that it writes a 0, which is a nop instruction in MIPS, to 329 00:36:52,470 --> 00:37:00,770 a call that checks for password for telnet and also for enable password and then it 330 00:37:00,770 --> 00:37:10,610 just jumps back to SNMP service. So now the long-awaited demo. Let's see if I can 331 00:37:10,610 --> 00:37:42,480 make it a live demo. All righty, so here we have the serial connection to the 332 00:37:42,480 --> 00:37:52,820 device, you can see we have a shell. So what we do now, we inspect the password on 333 00:37:52,820 --> 00:37:56,460 the telnet service to make sure it's working as intended. So we see that bad 334 00:37:56,460 --> 00:38:03,700 passwords. We don't know the valid password for the device, what we do now is 335 00:38:03,700 --> 00:38:16,050 we launch the actual exploit, as parameters it takes the host, community 336 00:38:16,050 --> 00:38:26,200 and shell code in hex. So this is the shell 337 00:38:26,200 --> 00:38:41,300 code I was talking about that patches the code flow in authentication. So let's 338 00:38:41,300 --> 00:38:53,580 write sudo. So here you see that we initiate writing the four byte sequences 339 00:38:53,580 --> 00:39:02,490 into the text section. Basically this writes the shell code into the memory. So 340 00:39:02,490 --> 00:39:17,180 after the exploit finishes this, we just have to jump to the shell code. So let's 341 00:39:17,180 --> 00:39:57,530 see. Please do not crash. So, yes. So back to the slides. And of course you can build 342 00:39:57,530 --> 00:40:02,500 a shell code that will unset this behavior and patch the process back to enable the 343 00:40:02,500 --> 00:40:07,940 password and on the side notes how reliably can you exploit this 344 00:40:07,940 --> 00:40:15,220 vulnerability? So, of course the SNMP public community will leak you the version 345 00:40:15,220 --> 00:40:20,560 of the particular router but it does not leak you the version of ROMMON and we're 346 00:40:20,560 --> 00:40:29,380 basically constructing ROP chains in the rom monitor. So actually you have not that 347 00:40:29,380 --> 00:40:34,080 many versions of rom monitor available. You have only five if we're talking about 348 00:40:34,080 --> 00:40:41,500 2800 router. So the worst-case scenario is just you crash it four times. It's not 349 00:40:41,500 --> 00:40:46,410 like you have to crash it four thousand times to you know beat the ASLR but 350 00:40:46,410 --> 00:40:52,340 there's a second option which is interesting. ROMMON is designed to be 351 00:40:52,340 --> 00:40:57,590 upgraded, so basically a system administrator can download a new version 352 00:40:57,590 --> 00:41:02,800 and update it but the thing is that read- only region that contains the stock ROMMON 353 00:41:02,800 --> 00:41:10,300 is always in place and it is always at the same offset, so even if you updated the 354 00:41:10,300 --> 00:41:15,760 rom monitor, the read-only version of it, the old version that always been there, 355 00:41:15,760 --> 00:41:24,650 will always be at bfc00000. So basically the assumption is that all the devices 356 00:41:24,650 --> 00:41:29,031 manufactured at the same time and place, they will have the same read-only rom 357 00:41:29,031 --> 00:41:38,030 monitor, you can query your serial number of your router using snmpget. So for 358 00:41:38,030 --> 00:41:44,760 example my lab router is manufactured in the year of 2008 and Czech Republic. So 359 00:41:44,760 --> 00:41:51,720 and it has the following version of rom monitor. So guys to, you know, to 360 00:41:51,720 --> 00:41:57,210 summarise about all this, do not leave default credentials on external networks. 361 00:41:57,210 --> 00:42:02,730 So public communities are not designed to be placed on external networks 362 00:42:02,730 --> 00:42:09,990 for the Shodan to find it. Take care of what you expose on the external networks. 363 00:42:09,990 --> 00:42:17,270 Of course patch your devices and watch for the end-of-life announcement by 364 00:42:17,270 --> 00:42:28,200 Cisco. Sorry? Sure why not? Alright guys thank you so much for your attention 365 00:42:28,200 --> 00:42:40,510 *applause* thanks for having me. 366 00:42:40,510 --> 00:42:42,600 Herald: I suppose there are some questions 367 00:42:42,600 --> 00:42:50,250 in this audience, please take a microphone if you can. no one on the internet? They 368 00:42:50,250 --> 00:43:00,590 are flabbergasted there it seems. Microphone number one. 369 00:43:00,590 --> 00:43:07,110 Mic 1: Yeah, I'm a random network admin and I know that people tend to use the 370 00:43:07,110 --> 00:43:13,320 same SNMP community on many of their routers. My view is that basically if you 371 00:43:13,320 --> 00:43:19,171 can get access to read only on those routers you will be able to hijack that or 372 00:43:19,171 --> 00:43:25,140 like use the same principle. So basically don't use the same SNMP community on all 373 00:43:25,140 --> 00:43:29,910 your devices that would be also something. Artem Kondratenko: the main thing is to 374 00:43:29,910 --> 00:43:34,800 update your routers because it's a patched vulnerability, the patch was released in 375 00:43:34,800 --> 00:43:42,860 September of 2017 but if you tend to use the end-of-life products like router 2800 376 00:43:42,860 --> 00:43:48,940 you probably should use a strong community strength for it. 377 00:43:48,940 --> 00:43:55,040 Herald: Thank you. Someone else having a question there? Yes someone on the 378 00:43:55,040 --> 00:44:00,390 internet is alive. It's alive. Signal Angel: Let's try it. Yeah now I've 379 00:44:00,390 --> 00:44:05,050 actually got a microphone. The Internet is asking how much time did you put into this 380 00:44:05,050 --> 00:44:08,830 whole project? Artem Kondratenko: While working on this 381 00:44:08,830 --> 00:44:19,070 exploit consumed around I'd say four weeks. Four weeks from the discovering the 382 00:44:19,070 --> 00:44:26,320 device on the external network to the final exploit. Yes. Thank you. 383 00:44:26,320 --> 00:44:31,460 Herald: I have a question maybe for you as well. Is that you you're as well a lot of 384 00:44:31,460 --> 00:44:36,070 you have lots of volunteers who are working with you as well in researching 385 00:44:36,070 --> 00:44:38,440 these exploits or? Artem Kondratenko: Volunteers? 386 00:44:38,440 --> 00:44:41,730 Herald: Yeah I don't know. Artem Kondratenko: No, actually we don't 387 00:44:41,730 --> 00:44:44,260 have any volunteers, this is all part of my work. 388 00:44:44,260 --> 00:44:52,300 Herald: Okay. Thank you very much for thank you very much for this in its really 389 00:44:52,300 --> 00:44:56,420 revealing lecture, if someone wants to... Artem Kondratenko: Oh I just forgot to 390 00:44:56,420 --> 00:45:02,460 say, is my mic on? okay so the actual proof of concept and the debugger will be 391 00:45:02,460 --> 00:45:07,570 released in a few days, so the Python script with the capstone and the actual 392 00:45:07,570 --> 00:45:12,070 proof of concept I'll publish it and in a week or so. 393 00:45:12,070 --> 00:45:16,039 Herald: okay thank you. 394 00:45:16,039 --> 00:45:20,550 *34c3 outro* 395 00:45:20,550 --> 00:45:36,741 subtitles created by c3subtitles.de in the year 2018. Join, and help us!