1 00:00:05,350 --> 00:00:09,510 Okay, don't ruckus again, take one million. 2 00:00:11,210 --> 00:00:20,290 Hi everyone, and thank you for watching my talk and thanks DEF CON for inviting me and not giving up on this year con. 3 00:00:20,510 --> 00:00:31,550 This is the first time I speak on DEF CON and I could really use a welcome round shot, but since I'm not in Vegas, well, I think I'm gonna save it for another time. 4 00:00:33,670 --> 00:00:39,510 This talk will present my recent research on Ruckus Wireless. 5 00:00:39,510 --> 00:00:44,610 Ruckus is a wireless solution company owned by Comscope. 6 00:00:44,610 --> 00:00:49,230 I've come to realize that Ruckus is pretty popular in the States. 7 00:00:49,230 --> 00:00:54,210 They even partnered with Black Hat for conference Wi-Fi solution. 8 00:00:54,410 --> 00:00:58,330 Actually, this is how I first noticed them. 9 00:00:58,330 --> 00:01:09,990 In the last year, I've been doing vulnerability research on Ruckus access points, and so far I managed to find several critical vulnerabilities in many of these devices. 10 00:01:11,070 --> 00:01:19,850 My previous research was introduced in the recent CCC convention, back when traveling places was a real thing. 11 00:01:21,130 --> 00:01:25,970 But before I begin, I would like to go over the obligatory who am I part. 12 00:01:25,970 --> 00:01:27,670 So my name is Galt Swar. 13 00:01:28,010 --> 00:01:33,770 I'm a research team leader at Aleph Research by HCL AppScan. 14 00:01:34,130 --> 00:01:39,410 I'm recording this talk from our lovely office in Herzliya, Israel. 15 00:01:39,510 --> 00:01:43,750 And I've been doing reversing for more than a decade. 16 00:01:43,750 --> 00:01:48,030 I try to focus on offensive embedded devices research. 17 00:01:49,250 --> 00:01:53,350 All right, I would like to begin with a quick recap. 18 00:01:53,350 --> 00:02:02,090 In my previous research, I demonstrated three ways to run code on Ruckus unleashed and zone director devices. 19 00:02:02,090 --> 00:02:05,920 All vulnerability were found on the device web interface. 20 00:02:07,010 --> 00:02:14,270 My first RCE was credential leakage with SSH jailbreak. 21 00:02:14,390 --> 00:02:19,750 My second RCE was unauthenticated stack buffer overflow. 22 00:02:20,710 --> 00:02:29,590 And the last RCE was command injection vulnerability, which was reachable without authentication by writing a new page. 23 00:02:33,230 --> 00:02:42,090 In this talk, same as in my previous one, I will be using Ruckus R510 unleashed. 24 00:02:42,110 --> 00:02:47,190 Ruckus has an unleashed version for every access point they provide. 25 00:02:47,190 --> 00:02:52,450 Unleashed access points don't rely on Wi-Fi controllers. 26 00:02:53,030 --> 00:03:00,030 Well, all access point in the list you can see here share the same vulnerable code base. 27 00:03:00,230 --> 00:03:08,530 And I also noticed that some vulnerabilities works on zone director product line, which is the Wi-Fi controllers. 28 00:03:10,550 --> 00:03:12,310 Okay, so what's new? 29 00:03:12,310 --> 00:03:18,930 Well, this research began right after I got Ruckus patch for my first research. 30 00:03:19,230 --> 00:03:24,230 I noticed that they did not fix my vulnerability correctly. 31 00:03:24,230 --> 00:03:27,270 So I decided to try and re-enable it. 32 00:03:27,930 --> 00:03:34,530 Besides that, my first research was 100% based on device emulation. 33 00:03:34,670 --> 00:03:42,090 Now that I bought an actual device, I can try to see if I missed something that I couldn't emulate. 34 00:03:43,250 --> 00:03:51,910 Well, but before I begin with the new vulnerabilities, I would like to talk about a new Jidra script that I used for this research. 35 00:03:54,630 --> 00:03:59,130 My previous research and this one was done relatively fast. 36 00:03:59,130 --> 00:04:08,430 Thanks to a Jidra script, I wrote that fetches function name from log strings Ruckus has left in their binaries. 37 00:04:08,430 --> 00:04:13,010 Here you can see some of them from one of the binaries. 38 00:04:14,990 --> 00:04:22,830 This script helped me rename function by parsing these log lines that contained the function name. 39 00:04:22,830 --> 00:04:31,950 For more information about the script and its generic version, please check my previous talk or our GitHub. 40 00:04:32,390 --> 00:04:43,520 All in all, this script was super useful for binary compiled with Ruckus code, but not all binaries were like that. 41 00:04:46,160 --> 00:04:53,170 It's a common thing for embedded devices vendor to use open source project in their devices. 42 00:04:53,350 --> 00:04:56,000 Ruckus web server is a good example for that. 43 00:04:57,610 --> 00:05:05,150 Ruckus added new functionality by adding code to a popular web server called Embed This. 44 00:05:06,250 --> 00:05:13,930 Since Embed This sources are public, I didn't really need to reverse the entire web server binary. 45 00:05:13,930 --> 00:05:17,570 It was easier for me just to review the source code. 46 00:05:18,750 --> 00:05:21,850 But what about the parts that Ruckus added? 47 00:05:21,850 --> 00:05:27,970 I would like to be able to mark these parts in JITRA, so I'll know I'll have to reverse them. 48 00:05:28,530 --> 00:05:31,830 So for this, I wrote an additional JITRA script. 49 00:05:34,090 --> 00:05:41,170 My new script tries to extract as many function names as it can from the Embed This sources. 50 00:05:41,600 --> 00:05:50,030 I use different methods to extract this information, things like string matching and function call trace. 51 00:05:50,510 --> 00:06:02,150 But the thing that helped me the most were debugging functions that contain the exact C filename and line number in the Embed This sources. 52 00:06:03,080 --> 00:06:18,830 Here we can see that for this unnamed function from the web server binary, we get that this function appears in server.c file around the line number 138. 53 00:06:20,770 --> 00:06:29,150 So if we go to this line in the Embed This sources, we'll be able to extract many function names from the sources. 54 00:06:29,990 --> 00:06:34,470 This is the function in JITRA after conversion. 55 00:06:37,540 --> 00:06:44,040 These are all function name that I was able to extract from the source code to JITRA. 56 00:06:46,380 --> 00:06:51,240 Okay, so let's take this function coin graph, for example. 57 00:06:51,360 --> 00:07:00,140 This function is called macreateWebServer, and it's being called from the main. 58 00:07:00,300 --> 00:07:03,180 And it also calls other functions. 59 00:07:04,100 --> 00:07:15,440 Well, on the right-hand side, we can see that all of the function names I was able to fetch from the sources by using the script I just introduced. 60 00:07:17,320 --> 00:07:30,080 On the bottom left-hand side, we can see the function names I was able to fetch by using the script from my previous research, the one that uses the log strings. 61 00:07:30,980 --> 00:07:38,240 And as you can see, there are still unnamed function left, but still the majority of functions are now named. 62 00:07:38,580 --> 00:07:50,040 So this is an excellent example of how these two scripts help me retrieve plenty of information and save me so much time and effort on reversing. 63 00:07:53,670 --> 00:08:03,150 I'm also in the progress of writing a generic version for this script that won't rely on specific debug information. 64 00:08:03,390 --> 00:08:11,450 I will share all of my script in our Aleph Research GitHub account, so feel free to check it out. 65 00:08:11,450 --> 00:08:17,050 And while you're there, you can also check other tools that we got there. 66 00:08:18,690 --> 00:08:20,270 All right, cool. 67 00:08:20,270 --> 00:08:22,630 So now we're ready for some exploits. 68 00:08:22,630 --> 00:08:24,670 This is my first RCE. 69 00:08:24,670 --> 00:08:35,150 In this attack, I found another stack overflow that was reachable with unauthenticated web request. 70 00:08:37,730 --> 00:08:40,470 And I would like to start with a demo. 71 00:08:40,470 --> 00:08:48,990 Well, this is clearly not a live demo, but I will still try to do it in a live demo style. 72 00:08:49,190 --> 00:08:54,410 So yeah, let's see how it goes. 73 00:08:55,490 --> 00:09:07,150 Okay, so for that, I need my demo screen and my listener screen. 74 00:09:09,070 --> 00:09:19,090 Okay, so this is the terminal that I'm gonna listen to port 1337. 75 00:09:19,190 --> 00:09:24,090 And my exploit will create reverse shell to this port. 76 00:09:25,090 --> 00:09:29,010 Let's just start listening. 77 00:09:29,870 --> 00:09:35,050 And now, okay. 78 00:09:35,870 --> 00:09:44,290 And now let's have a look on my stack overflow. 79 00:09:44,450 --> 00:09:46,810 So this is my overflow. 80 00:09:46,810 --> 00:09:50,850 Wait, let me open it in a different way. 81 00:09:50,850 --> 00:09:54,070 Okay, so this is my overflow, as you can see here. 82 00:09:54,770 --> 00:10:03,210 And I am creating this reverse shell by using Netcat. 83 00:10:03,530 --> 00:10:08,050 And let's just go ahead and send this. 84 00:10:08,050 --> 00:10:15,070 So I will be posting this file to this address. 85 00:10:17,410 --> 00:10:22,170 And okay, hopefully everything will work. 86 00:10:22,170 --> 00:10:26,570 Connection refused, it's a good indication. 87 00:10:26,570 --> 00:10:29,320 Let's see what's going on with my listener. 88 00:10:30,190 --> 00:10:33,840 Okay, so connection received, looking good. 89 00:10:34,700 --> 00:10:45,460 As you can see, I managed to run ls and my user is admin. 90 00:10:45,830 --> 00:10:52,150 And this user is part of the root group. 91 00:10:52,850 --> 00:10:54,670 Yeah, so this is it. 92 00:10:54,670 --> 00:10:58,890 This is my demo. 93 00:11:06,200 --> 00:11:13,560 Okay, before I get into the vulnerability, I would like to do a quick recap on my previous talk. 94 00:11:13,760 --> 00:11:22,660 This slide and the next one were actually taken from my previous talk, but I'll go over them just to create the right context. 95 00:11:23,290 --> 00:11:28,440 There are three important binaries in the web interface. 96 00:11:28,440 --> 00:11:32,200 The first one is slash bin slash webs. 97 00:11:32,200 --> 00:11:35,860 This is the actual embeddice web server. 98 00:11:35,860 --> 00:11:42,090 It handles HTTP requests and executes handlers according to its configuration. 99 00:11:42,680 --> 00:11:48,150 It then sends commands through a Unix domain socket to emfd. 100 00:11:48,740 --> 00:11:55,060 Slash bin slash emfd is an executable that contains the web interface logic. 101 00:11:55,060 --> 00:12:01,940 It maps function from web pages to their own function, to its own function. 102 00:12:02,150 --> 00:12:13,180 It then implements web interface commands such as backup, network configuration, retrieve system information and much more. 103 00:12:13,180 --> 00:12:15,980 And the last one is libemf. 104 00:12:15,980 --> 00:12:25,520 This library is used by emfd for web authentication, input validation and some code execution. 105 00:12:26,940 --> 00:12:30,780 And now let's look at this in a diagram. 106 00:12:31,060 --> 00:12:35,300 So webs listen to HTTP slash HTTPS. 107 00:12:35,300 --> 00:12:46,020 If it receives a JSA page request, it uses EGS handler to pass a function name to emfd. 108 00:12:46,360 --> 00:12:50,700 Emfd then checks if the function name is mapped. 109 00:12:50,700 --> 00:12:53,200 So it calls the right function pointer. 110 00:12:56,100 --> 00:13:05,500 Eventually emfd runs some kind of shell commands, for example, ifconfig, IP tables, routes, et cetera. 111 00:13:08,820 --> 00:13:22,080 Since the web server contains both Embedish code and Ruckus code, I decided to mark Ruckus function with an RKS prefix. 112 00:13:22,160 --> 00:13:30,300 Ruckus has added a new function that registers new ESP functions. 113 00:13:30,320 --> 00:13:37,420 ESP again is the handler that runs if the web server receive a JSP request. 114 00:13:38,780 --> 00:13:43,020 So here we can see that 12 functions are being registered. 115 00:13:43,340 --> 00:13:48,900 Each function registration needs a function name string and a function pointer. 116 00:13:48,900 --> 00:13:54,440 Now let's understand how we can reach this function with an HTTP request. 117 00:13:57,020 --> 00:14:10,860 Okay, so for example, when sending an HTTP request to slash admin slash webpage slash Wi-Fi network slash wlan sysconfirm.jsp. 118 00:14:10,860 --> 00:14:14,260 Please remember this page because it's a very long one. 119 00:14:15,680 --> 00:14:19,740 The web server invokes an EGS handler. 120 00:14:20,140 --> 00:14:27,940 On this page, we can see that EGS script has a special tag right at the beginning, right? 121 00:14:27,940 --> 00:14:31,840 And EGS function are being called from it. 122 00:14:33,920 --> 00:14:39,180 Webs maps every string it received to a function pointer and then runs it. 123 00:14:39,880 --> 00:14:47,040 So here we can see that a function called escape JSTR is being called. 124 00:14:48,500 --> 00:14:54,700 And another wonderful function named S is also being called. 125 00:14:54,780 --> 00:14:56,280 Yeah, S, yeah. 126 00:14:56,440 --> 00:15:01,000 A great, a really great example of a shitty naming convention. 127 00:15:01,940 --> 00:15:06,420 But the naming convention is not the only lousy thing about this function. 128 00:15:06,780 --> 00:15:20,100 When I reviewed this edit functions, I noticed that S, STR, escape JS and get cookie value are all using unsafe string copy. 129 00:15:21,300 --> 00:15:32,080 That means if I can find a webpage that passes user inputs to one of these function, I will be able to smash the web server stuck. 130 00:15:34,820 --> 00:15:45,160 All right, so to search for an input that leads to one of these functions, I decided to use the good old grab command. 131 00:15:45,160 --> 00:15:53,100 So I would like to search if there are any calls to one of these function with a non-static value. 132 00:15:53,460 --> 00:16:00,820 It also should not be a session related values because I might not be able to manipulate them. 133 00:16:00,820 --> 00:16:07,040 Let's say session cookie or something like that that is being generated behind the scene. 134 00:16:08,740 --> 00:16:18,160 So here I used a regex that made sure S don't get any value inside a double or single quote. 135 00:16:18,480 --> 00:16:22,020 I managed to find two JSP pages. 136 00:16:22,020 --> 00:16:28,540 One was an error page, which did not receive any user inputs, the second one. 137 00:16:28,540 --> 00:16:36,300 And the first one was that page with a very long name that I don't really want to say it again. 138 00:16:36,300 --> 00:16:39,780 So I just have a look on that page. 139 00:16:41,100 --> 00:16:51,140 Okay, so we saw that S function receive a non-static value called content. 140 00:16:52,020 --> 00:16:59,960 And luckily the content variable is set directly by a user parameter called content key. 141 00:17:02,400 --> 00:17:11,840 So I just needed to send the right request to wlan sysconfirm.jsp and that's it, I smashed the stack. 142 00:17:13,260 --> 00:17:20,260 As for exploitation, R510 uses both NX and ASLR. 143 00:17:21,180 --> 00:17:25,280 To overcome NX, I decided to use rope gadget. 144 00:17:25,280 --> 00:17:32,240 Actually, I use the same gadgets as for my previous stack overflow. 145 00:17:33,300 --> 00:17:40,560 So these are two gadgets that run system with a pointer to my payload. 146 00:17:40,620 --> 00:17:46,800 And in this case, I'm using NC to create a reverse shell to my machine. 147 00:17:47,060 --> 00:17:58,180 As for ASLR, same thing as my previous stack overflow, I can just brute force my way and overcome its nine bit of randomness. 148 00:17:59,260 --> 00:18:00,460 All right. 149 00:18:03,780 --> 00:18:15,920 So before I continue with my second attack, I would like to share other vulnerabilities I found in this research that I think worth mentioning. 150 00:18:16,960 --> 00:18:28,060 So I also found a cross-site scripting, a denial of service and information leakage that may lead to another jailbreak. 151 00:18:28,200 --> 00:18:34,300 All of them were found in either the web server or EMFD. 152 00:18:35,840 --> 00:18:39,000 So let's talk about the XSS. 153 00:18:39,060 --> 00:18:47,780 I discovered that, I discovered this cross-site scripting on my first research and actually it was pretty straightforward. 154 00:18:48,560 --> 00:19:04,240 So every Ajax request to slash admin slash underscore WLA underscore CMD stats dot JSP has to contain an updater attribute. 155 00:19:05,060 --> 00:19:12,660 This attribute is simply reflected without any sanitation, as any validation, sorry. 156 00:19:13,240 --> 00:19:21,720 So all I had to do is to send this payload and it just runs the, you know, the alert message. 157 00:19:24,280 --> 00:19:30,380 XSS in embedded devices is not that big of a deal, but I decided to report it anyway. 158 00:19:31,500 --> 00:19:35,880 All right, so let's go over the denial of service. 159 00:19:36,240 --> 00:19:43,400 So while I was researching, I came across this request that simply crashed the server. 160 00:19:43,540 --> 00:19:48,480 I must say I did not invest too much time understanding this bug. 161 00:19:48,900 --> 00:20:00,740 This is a web server related bug, of course, that caused either by an old version of embeddice or in the code Ruckus has added. 162 00:20:04,260 --> 00:20:07,440 All right, and now for the information leakage. 163 00:20:07,440 --> 00:20:14,140 So Ruckus are considering the device serial number as sensitive information. 164 00:20:14,140 --> 00:20:26,760 In my previous research, I came across functions in Ruckus CLI that rely on the device serial number to get to a busy box shell, to jailbreak. 165 00:20:26,760 --> 00:20:34,660 In this research, I noticed that upnp.jsp page is reachable without any authentication. 166 00:20:35,820 --> 00:20:43,180 And this page gives away many useful information on the device that can be used for fingerprinting, let's say. 167 00:20:43,740 --> 00:20:50,660 But the best part is that I can get the device serial number and probably jailbreak. 168 00:20:52,580 --> 00:20:58,280 Okay, so now is the time for my second RCE. 169 00:20:58,340 --> 00:21:05,860 In this attack, I found a way to reuse the command injection vulnerability from my previous research. 170 00:21:05,860 --> 00:21:12,820 I then had to find a new way to bypass authentication by overriding admin credentials. 171 00:21:15,860 --> 00:21:22,140 So let's first understand how the command injection used to work in my previous research. 172 00:21:22,420 --> 00:21:28,700 So embed this, I'm sorry, EMFD execute code in a really messy way. 173 00:21:28,700 --> 00:21:42,680 EMFD sometimes uses libemf, other time calls the shell script sys underscore wrapper.sh and sometimes just run the command itself using libc. 174 00:21:43,640 --> 00:21:49,660 These are all the different function that EMFD uses to execute shell commands. 175 00:21:51,340 --> 00:21:56,220 As you can see, there are many libc system function code. 176 00:21:56,220 --> 00:22:02,440 So I had to find a page that uses this system function without validation. 177 00:22:04,580 --> 00:22:11,780 And I found four functions that call system and were vulnerable to command injection. 178 00:22:12,060 --> 00:22:19,160 And I will be showing the injection on the last one, which is CMD import AVP port. 179 00:22:20,920 --> 00:22:31,680 To reach the vulnerable function, I had to send an Ajax request to slash admin slash cmdstat.jsp. 180 00:22:33,700 --> 00:22:42,060 This request use an EMFD command called import AVP port. 181 00:22:42,900 --> 00:22:51,420 And when EMFD received this request, it uses a function called CMD import AVP port. 182 00:22:51,420 --> 00:22:57,240 And this function just uses libc system function just like that, unsafely. 183 00:22:58,620 --> 00:23:05,000 Here you can see the function decompiled code as it used to be in my previous research. 184 00:23:05,360 --> 00:23:14,380 So for my previous research, all I had to do is to pass a command injection in the upload file attribute. 185 00:23:14,380 --> 00:23:18,600 As you can see, it just executed without any validation. 186 00:23:20,560 --> 00:23:25,820 But the problem was that I had to be authenticated to reach this function. 187 00:23:25,820 --> 00:23:28,100 I had to use a valid cookie. 188 00:23:32,290 --> 00:23:40,990 Okay, so to fix this, Ruckus decided to use a function called is validate input string. 189 00:23:41,190 --> 00:23:47,860 That's supposed to validate there are no injection characters in the upload file attributes. 190 00:23:49,370 --> 00:23:55,030 This is an external util function found in lib EMF. 191 00:23:55,030 --> 00:23:58,840 And it's being used widely for input validation. 192 00:24:04,060 --> 00:24:07,890 So let's have a look at this validation function. 193 00:24:10,010 --> 00:24:14,840 Here are all the forbidden characters for a given input. 194 00:24:14,840 --> 00:24:18,780 Well, at first, this validation seems pretty solid. 195 00:24:18,800 --> 00:24:23,520 However, some very important characters are missing from that list. 196 00:24:25,280 --> 00:24:36,800 So something I like to do when reviewing a validator is to create a set of all the printable non-alphanumeric characters that can pass this validator. 197 00:24:37,400 --> 00:24:47,300 And well, this is the moment I would ask you guys if you think of a payload using this set of characters. 198 00:24:47,300 --> 00:24:50,620 But thanks to coronavirus, I can't really do this shtick. 199 00:24:50,620 --> 00:24:52,240 So nevermind. 200 00:24:52,400 --> 00:25:04,120 And anyway, after some trial and error, I realize a shebang sign, which is pound followed by exclamation mark is a valid input. 201 00:25:04,120 --> 00:25:09,900 So I can also use slash and I can also use slash. 202 00:25:11,020 --> 00:25:15,980 So I can use shebang slash bin slash sh. 203 00:25:16,720 --> 00:25:19,720 So this is good, but not good enough. 204 00:25:19,720 --> 00:25:24,580 I can't just append this payload to a command run by system. 205 00:25:25,040 --> 00:25:30,120 And well, this is because shebang should be in a line of its own, right? 206 00:25:30,120 --> 00:25:32,040 It's usually the header. 207 00:25:33,260 --> 00:25:37,020 Luckily, I could also use a newline character. 208 00:25:37,020 --> 00:25:39,580 Yeah, that is correct. 209 00:25:39,580 --> 00:25:47,160 A newline character as a parameter input is not being sanitized, not in the web server, nor EMF. 210 00:25:47,160 --> 00:25:48,820 Amazing, right? 211 00:25:49,060 --> 00:25:57,280 Well, shebang plus a newline, it equals sweet, sweet exploit love. 212 00:25:58,380 --> 00:25:59,300 Yeah. 213 00:25:59,300 --> 00:26:03,180 Okay, so that was good news. 214 00:26:03,780 --> 00:26:12,740 I can now replace my injection with shebang, but there was one thing left to solve. 215 00:26:13,800 --> 00:26:17,880 Space characters is also not a valid input. 216 00:26:17,880 --> 00:26:22,860 So I simply replaced them with tab characters. 217 00:26:23,860 --> 00:26:27,000 Let's have a look on my new payload. 218 00:26:29,120 --> 00:26:43,700 You can see that for semicolon, so I replaced semicolon with shebang plus a newline and spaces were replaced by tab. 219 00:26:45,020 --> 00:26:46,260 And that's it. 220 00:26:46,260 --> 00:26:52,500 This is how I was able to reuse my command injection vulnerability. 221 00:26:52,500 --> 00:26:58,880 The last thing I had to do to complete this exploit is bypass authentication again. 222 00:27:01,320 --> 00:27:08,980 Okay, so now I would like to explain how the admin credentials are stored in the device. 223 00:27:10,420 --> 00:27:16,260 So system.xml is the device general configuration file. 224 00:27:16,260 --> 00:27:21,400 It contains the admin credential as well as other important configuration. 225 00:27:22,500 --> 00:27:31,740 Here you can see that the admin element and its password is stored in the x-password attribute. 226 00:27:32,340 --> 00:27:43,560 While working on this exploit, I noticed that Ruckus has decided to use the most secure mechanism for storing sensitive passwords, as you can see here. 227 00:27:43,560 --> 00:27:54,400 So you might look at this x-password attribute and think that my password is 12345BCB, but that's not the case. 228 00:27:54,400 --> 00:28:00,200 My actual password is 12345ABCD. 229 00:28:00,200 --> 00:28:02,600 Yes, yes, yes. 230 00:28:02,600 --> 00:28:08,210 Ruckus are obfuscating the password by adding one to each character. 231 00:28:08,980 --> 00:28:16,080 Gosh, gosh, I just don't understand why won't they use a simple hash function. 232 00:28:16,080 --> 00:28:17,280 Don't get it. 233 00:28:17,280 --> 00:28:20,100 But nevermind about that. 234 00:28:20,980 --> 00:28:30,880 Let's have a look at slash admin, slash underscore WLA underscore conf dot JSP page. 235 00:28:31,080 --> 00:28:42,040 We can see that this page calls for two functions in EMFD, login without access check and AJAX conf. 236 00:28:42,520 --> 00:28:50,080 Please keep in mind that we must pass the first function to get to AJAX conf, which is the vulnerable function. 237 00:28:51,960 --> 00:29:06,560 So without login access check, expects an AJAX request XML that contains either set conf action or do conf action. 238 00:29:06,780 --> 00:29:12,620 The do, sorry, either set conf or do CMD action. 239 00:29:12,620 --> 00:29:21,440 The do CMD action in this case was very limited and I decided to focus only on set conf. 240 00:29:23,620 --> 00:29:33,100 So set conf action calls an EMFD function called check research credentials configuration parameter. 241 00:29:34,660 --> 00:29:41,640 This function expects an admin XML element with the following attributes. 242 00:29:43,560 --> 00:29:59,520 And please note that this function only validate the number of elements, eight in this case, and it only validate that the attributes names matches the one we see here. 243 00:29:59,520 --> 00:30:08,460 That means it won't check the value only that a certain request contains eight elements that matches with this name. 244 00:30:08,840 --> 00:30:15,480 And it doesn't check for any permissions whatsoever. 245 00:30:16,720 --> 00:30:22,820 Okay, so here we can see a valid AJAX request with an admin element. 246 00:30:24,200 --> 00:30:34,240 So this request has all the right attributes as you can see eight and then the right, and it can reach the vulnerable AJAX conf function. 247 00:30:35,240 --> 00:30:39,320 Okay, so let's move to AJAX conf. 248 00:30:39,790 --> 00:30:44,120 This is a very big function that does all sorts of things. 249 00:30:44,120 --> 00:30:52,050 One of them is to use adapter set conf to update different configuration file. 250 00:30:53,410 --> 00:30:59,780 In particular, it can update the main system dot XML configuration. 251 00:30:59,780 --> 00:31:09,440 Okay , as we saw, without login access, forces me to use a specific XML element. 252 00:31:10,020 --> 00:31:15,440 But thankfully, this is the admin credentials XML element. 253 00:31:15,440 --> 00:31:24,360 So now let's understand how adapter set conf works and may be manipulated to write these credentials. 254 00:31:25,360 --> 00:31:32,080 So this is how adapter set conf function looks like. 255 00:31:32,680 --> 00:31:42,060 It receives the request component attributes and the AJAX request itself. 256 00:31:43,100 --> 00:31:55,860 I realized that if the component equals to system, then it can only update a specific XML element, which is not the admin element. 257 00:31:55,860 --> 00:32:00,980 So I can just override the admin credentials with this request. 258 00:32:03,920 --> 00:32:13,360 However, if the component attribute is not equal to system, it uses a function called repo get curr child. 259 00:32:14,340 --> 00:32:23,120 And this function gets a component name and looks for an XML configuration file with that name. 260 00:32:24,140 --> 00:32:30,540 So that means I can access any XML file in the air spider directory. 261 00:32:30,540 --> 00:32:39,960 Well, all of them except for the system XML because adapter set conf make sure it's excluded. 262 00:32:40,260 --> 00:32:47,460 But the credentials I want to override are in the system dot XML, which sucks, right? 263 00:32:48,520 --> 00:32:52,840 So this is where slash come to our rescue. 264 00:32:53,300 --> 00:33:02,900 I noticed that if I add a slash at the beginning of the component attributes, it's no longer a system component. 265 00:33:02,900 --> 00:33:07,120 It's now a slash system component. 266 00:33:07,780 --> 00:33:29,780 So now I can pass this system attribute check and now get a repo get curr child function will look for the file slash system dot XML, not system dot XML, which is perfectly fine in POSIX since we can add as many slashes as we want. 267 00:33:33,390 --> 00:33:36,330 Okay, and that's about it. 268 00:33:36,330 --> 00:33:46,790 Adapter set conf has replaced the admin element in system dot XML, which means I was able to override the admin credentials. 269 00:33:46,790 --> 00:33:53,810 Okay , now I just need to chain these two vulnerabilities together. 270 00:33:54,890 --> 00:34:02,330 So first the override, here I'm overriding the admin credentials with password 1234. 271 00:34:05,450 --> 00:34:10,810 Then run the command injection to pop a shell on the device. 272 00:34:12,150 --> 00:34:25,910 Well, since I consider myself a polite person, after getting a shell, I can obtain the original credentials by grepping slash var slash run slash RPM key asterisks. 273 00:34:26,750 --> 00:34:33,250 This was the file that I was able to leak in the first research. 274 00:34:33,250 --> 00:34:38,230 Fortunately, Ruckus insist on saving passwords as plain text. 275 00:34:38,230 --> 00:34:47,010 So all is left to do is to repeat the attack with the original credentials and avoid leaving any footprint on the device. 276 00:34:47,010 --> 00:34:49,730 Cause we're not that rude, right? 277 00:34:50,930 --> 00:34:51,990 Okay. 278 00:34:58,030 --> 00:35:02,030 So this is the time for my final demo. 279 00:35:02,030 --> 00:35:05,130 Again, I'll try to do it live-ish. 280 00:35:06,650 --> 00:35:10,910 Okay, so for that I need my terminal again. 281 00:35:11,850 --> 00:35:16,690 Okay, so first I would like to override the credentials. 282 00:35:16,690 --> 00:35:22,090 So let me just show you the payload. 283 00:35:22,090 --> 00:35:25,610 So this is the request. 284 00:35:25,750 --> 00:35:32,210 And let's just, you know, change the passwords to DEF CON. 285 00:35:32,210 --> 00:35:33,170 Why not? 286 00:35:33,170 --> 00:35:36,050 And 28 safe mode. 287 00:35:36,710 --> 00:35:37,810 Awesome. 288 00:35:39,770 --> 00:35:40,810 Okay. 289 00:35:40,810 --> 00:35:42,090 Yes. 290 00:35:42,090 --> 00:35:46,810 And now I would like to post this XML. 291 00:35:46,810 --> 00:35:55,070 So I'm just posting it to this admin wla-conf-jsp. 292 00:35:56,650 --> 00:35:57,650 And this is it. 293 00:35:57,650 --> 00:36:00,350 I overrode the credentials. 294 00:36:00,350 --> 00:36:03,930 Now I'll have to authenticate again to log in. 295 00:36:07,250 --> 00:36:12,070 So let's go with, what was it? 296 00:36:12,090 --> 00:36:16,110 DEF CON 28 safe mode. 297 00:36:16,110 --> 00:36:20,090 So this is just a standard login request. 298 00:36:20,410 --> 00:36:24,350 And I get the CSRF token and a set cookie. 299 00:36:25,010 --> 00:36:33,070 And now for my new, oh wait, I just want to show you guys my injection. 300 00:36:33,070 --> 00:36:47,450 So this is my new command injection where I use shebang and then new line, telnet top tab, and I'm going to open a port in 7331 on the device. 301 00:36:48,030 --> 00:36:49,630 Yes. 302 00:36:50,250 --> 00:36:51,210 Okay. 303 00:36:51,390 --> 00:36:52,590 So this is it. 304 00:36:52,590 --> 00:36:57,350 Let me just update the credentials real quick. 305 00:36:59,650 --> 00:37:05,190 This is the first one and that's the cookie. 306 00:37:05,870 --> 00:37:07,470 Okay. 307 00:37:09,650 --> 00:37:10,290 Okay. 308 00:37:10,290 --> 00:37:10,930 Great . 309 00:37:11,190 --> 00:37:15,610 So let's just run it. 310 00:37:17,230 --> 00:37:19,070 Okay, that's it. 311 00:37:19,070 --> 00:37:27,050 And now for the moment of truth, I'll log in, I'll tell it to 7331. 312 00:37:27,230 --> 00:37:33,950 And as you can see here, I'm the root and this is it. 313 00:37:34,910 --> 00:37:36,170 Okay. 314 00:37:43,540 --> 00:37:50,780 So in conclusion, today I demonstrated two pre-auth RCEs. 315 00:37:50,780 --> 00:37:55,220 The first one was pre-auth stack buffer overflow. 316 00:37:55,220 --> 00:37:59,700 And the second was command injection with credentials overwrite. 317 00:38:01,380 --> 00:38:08,920 I will also share my new and improved Jidra script that really helped me with this research. 318 00:38:09,760 --> 00:38:14,500 Ruckus Networks was informed about these vulnerabilities. 319 00:38:14,500 --> 00:38:18,000 I requested six CVEs and they confirmed them. 320 00:38:19,320 --> 00:38:30,240 So in total, these two research concluded in 17 CVEs that resulted in five different RCEs. 321 00:38:32,600 --> 00:38:44,320 And as I said in my previous talk, if there are any Ruckus users who are watching this, you should stop what you're doing and check that you're running the latest firmware update. 322 00:38:44,320 --> 00:38:50,260 If not, you may be a victim to some very serious stuff. 323 00:38:51,520 --> 00:38:54,480 Okay, so that's it. 324 00:38:54,480 --> 00:38:58,020 These two research were tons of fun. 325 00:38:58,160 --> 00:39:02,940 I'm really glad that I helped Ruckus making their equipment more secure. 326 00:39:02,940 --> 00:39:09,940 I will post a second blog post with all the specific at alephsecurity.com. 327 00:39:09,940 --> 00:39:18,200 Feel free to check our blog for my previous research and other amazing research done by our group. 328 00:39:19,960 --> 00:39:20,720 That's it. 329 00:39:20,720 --> 00:39:22,920 Thank you very much for your attention. 330 00:39:22,920 --> 00:39:24,760 Stay safe and healthy. 331 00:39:27,080 --> 00:39:28,260 Woohoo!