 And now for my favorite DEF CON speaker, FX! Thank you guys. And with me here is Greg, one of my colleagues. And yeah, welcome to the annual RavdaFucking event. So I learned today from much that in marriages in the United States there's traditional gifts for every year. And for the 20th anniversary, the gift is China. So I didn't know that before. So let's get started. Oh yeah. So you will occasionally see fortune cookies. The strings on the paper slips are actually from the binaries. So let's talk about who are we, routers and stuff. Who is who are we? Most people don't know them or think they're only present in China. It's a 21 billion dollar company. They essentially make telecom networks, equipment, global services, which means they get to operate the stuff that they sold. And they make white label products. They do a lot of shit. Here's just different business units. So everything that goes into communication networks more or less can be purchased by who are we. What we're interested in here is the routing equipment. So the routing equipment is separated into like two series, the NE and the AR. Of the AR series, we actually have two types of devices to play with because they're not really easy to get. The routers are commonly also referred to as Quidway. There is another company, Huawei 3.com, or heck as we call them, who essentially make the same product and run the same software, but it is a different company. So if your vulnerability is getting or something, then make sure that you're taking this in. They also do security devices. And well, then there's interesting joint ventures. And you know that saying that A-class people hire A-class people. And B-class people, well, who are we cementing? When we look at product security, there is directly accessible from the main web page on Huawei.com. They're talking about open transparency and attitude, blah, blah, blah, work with all the governments. There is CEO recently called for a global cooperation for data protection. Yes. The reality is this. There is no externally visible product security group. So neither security focus nor Osvdb lists a vendor contact. The website of Huawei doesn't either. They've never released a single product security advisory. So nobody knows anything. The product security related patches are not visible as such. They just increment the release number. So apparently it's really someone hacks into the fix and then recompiles the code and this is your new image. That's it. So responsible disclosure, if I can't reach you, I can't tell you about your box. This is what happens. So let's talk about VRP. So the versatile routing platform is Huawei software, a general myth in the United States that they stole Cisco IOS. Nobody ports that shit. I mean seriously, that's just not efficient. So what actually happened was they, according to Cisco's legal documents, they actually copied the enhanced IGRP stuff and made the CLI look like a Cisco CLI. So people didn't have to learn new shit. And since they made the CLI look like the Cisco CLI, they copy and pasted it widely from the Cisco documentation into their own. But in reality, the VRP platform is actually VxWorks, version 3 or version 5. Last year there was VRP8 coming out, but we haven't seen it yet. So the versioning, as you see, is not very clear. I really haven't figured out what the release numbers actually mean. You will also see different names for the software. So sometimes it's called VxLS or Comware. And what's really interesting, so in the UK, Huawei has a Huawei cybersecurity center, but they don't have a security contact group, right? But they have a cybersecurity center in which they build a special certified version of the software for the UK. Commonly referred to as the GCHQ VRP. So how do you talk with VRP? Pretty much like every other router, you have default CLI interfaces, web configuration, NetConf, SNMP, and then some more obscure things like the branch intelligent management system. What's interesting here is you can configure those things between Chinese and English. So by default they run on Chinese, you can configure them to be in English. However, the debug commands, and that took me actually several days to figure out, the debug commands actually only output in Chinese. So if you're a terminal, now this is actually really clever if you have a professional services group that usually operates your equipment, because now it means if you have Huawei equipment, you actually need Huawei people or speak Chinese. So yeah, business-wise that is actually really clever. The CLI comes with several levels of hidden commands. So when you log into a router, you can enter the command underscore and go into hidden command mode. And then depending on the device that you have, there's additional hidden command codes that you will find. So on the hack machine, it asks for the secret password, which turns out to be a string compare and looking for Huawei 3.0. What is it? You're interrupting my talk. I just want to make sure if you're here for the tenacious D thing, that's tenacious. The rooms switched. That's it, last announcement. And I wanted to give you an opportunity to get some beer. Thank you. Well, if you haven't figured out that this is the other talk by now, then I really suck. I want to repeat myself. This is verbatim copies from the binary. So the VRP images. Image availability is a bitch. So if you're Chinese and you want to give me VRP images, that would be highly appreciated. We couldn't find a legal way to get them off the website. So we solved it the American way. Like, can we throw enough money at it? So the problem goes away and simply barred routers because they come with software. And they come with a default FTP service and you just FTP in and there's a file called system and that's the image. There's also an HTTP.zip, which contains the web content and stuff. So when you look at the images, they're very similar. You know, the headers are between 30 bytes and six kilobytes. But what you find after that is ARG. Anyone from the 90s remember ARG, the packer? So this is actually, they actually use ARG. We've also seen a 7-zip file. So essentially what's in there is one binary that they unpack. The default services are pretty plenty on those platforms. So we're looking at SSH by default open, HTTP, web management, FTP. You also often see Telnet open, X25 over TCP and H323. What can possibly go wrong? And apparently it is a very recent concept at Huawei that a configuration allows you to turn off a default service. So from what we hear, this was introduced last year. So if you have a default service, you have have it. Code quality. We were considering to leave this slide empty. So the smallest box that they make, the AR18, has on the image 10,730 calls to sprint F. The next bigger box has 16,420. So the number of calls to sprint F seems to be a linear function over the box price. You find lots of re-implementation of string copy and similar. They've wrote their own SSH server. Brave. Especially if you actually have to blackmail open SSH client to talk to this thing, because it uses two small RSA modellers. And for exploitability, the Nile page is not just mapped. It's read, write, execute mapped. So let's look at some of the internals. So this is the web UI. Everyone who speaks Chinese has a good time. Everyone else not. So they use session IDs. The session IDs are 32-bit, which is 4-byte. One of the 4-bytes is static. One of the 4-bytes is ignored. One of the 4-bytes is the concurrency session. And the rest is counting up. So if someone is already logged into the router, a very short code script gives you full administrative access to the machine. That's how it looks like. So you're getting the config, and you can change it and upload it again. So since they have web management, I'm glad you like that. So since they have web management, they actually also need a web server, right? So the web server tries to figure out whether a piece of content that is requested actually requires one of those complicated session IDs. So instead of looking into the HTTP.zip, which would actually tell them where that is, they actually have hard-coded substring comparisons. And if anything matches, they copy it into a buffer. That buffer is too small, and that buffer is on the stack. So any of those will work. And you essentially directly overwrite pre-authentication the instruction pointer. So this is essentially how much you control. You not only have instruction pointer control, but also a bunch of registers, and of course the stack. So what do we do? We look for a jump target. This being a string overflow, zero bytes are off. Image Bay is head zero bytes, ROM is mapped. For now, we just stay image dependent, and we simply use a move to counter register and then branch to counter register sequence from existing code. So we pivot back to the stack. And then, of course, we need code to execute. And I need the beer. So instead of having a complicated shell code, we actually use features. So VRP comes with a pair of functions that you can call and you can pass string to it, which will then put onto the CLI fully authenticated as administrator. So there's absolutely no privilege separation whatsoever. The address is, in this example, image dependent, but a short fat German hacker presented an alternative method a couple of years back here at DevCon for Cisco. So we actually took one of our existing Cisco shell codes and copied it pretty much verbatim over, and it actually works. So the strategy for the exploit here is to get around the HTTP limitations with spaces and stuff, we encode the commands and decode them in place and then run a command sequence like you see here, and we end it with a ping to ourself, so we know that everything worked fine. And this is all shell code you need for that. So the left side is the decoder. The right side is the execution. Pretty similar to OSX PowerPC shell code. Very basic. And this is the result you essentially get, you know, remote management power scripts that allow you to log into routers and configure them. Now it's Greg and the heap. All right. Hi, everyone. So after all this like sprint of stack overflows that we identified, we wanted to show you some heap stuff and I had a pretty hard time finding a heap overflow between all this like static sprint of stack overflow. We actually managed to find one inside the BIMS client which is like a default service on the device. BIMS is some proprietary protocol based on HTTP. The real use case is probably not so important because the bug is like just right in the beginning. So when they connect to an HTTP server and parse the response, then they look for the content length. So they call some sub-function to find the content length, store the content length and then go ahead and malloc so many bytes plus one. And then they go like, well, we already received some stuff. Let's copy it there. So they just mem copy all the stuff they already received into this buffer that like you can specify basically the size of. So this is like a pretty basic heap overflow. Of course unauthenticated and all that. So the way to trigger it is pretty easy. You just specify some small content length, send way more data than you specified in the content length field and then it crashes somewhere like in some weird location telling you, I don't know, the router just starts malfunctioning. So in order to really exploit that we need to have a look at the memory allocator of the system and this is what we're going to cover right now. Due to time constraints we're just going to cover the basics here and this is why we will only look at malloc. We'll not show that this assembly are free and all that kind of stuff. So at some point in time you'll probably have to trust my hand waving there. If you need to know any details then please feel free to catch us later on and we can chat about that stuff. So here we go. This is the relevant parts of malloc. What they do there is they have to request a block size in R31 and compare it with some values and depending on the block size they store some small integer constants in R5 and then later on if R5 is different from zero they will call some helper function which I called malloc worker and this helper function will actually use R5 as an index into some table. We're going to see that on the next slide. So malloc worker will first try to determine the free list that is actually to be used to give back chunks of the requested size. So this is a binning memory allocator which is pretty common. So they use this small value in R5 to find the right free list. They take the free list and then we'll try to put off the first chunk from the free list and to return it. However, there are some sanity checks which they probably introduced because it was crashing anyway all the time and they wanted to debug it or so. So they have some sanity checks there and those sanity checks are basically each heapplunk has to start with a hard-coded value of OX, EF, EF, EF, EF. Then at offset four each chunk has to contain a pointer to some memory allocator structure and this structure is going to be important later on and at offset 14 hex this structure contains some string or integer constant which reads exclamation mark PGH. This is why we're going to call this the PGH structure but it's just basically some heap management infrastructure that is placed inside each chunk. And when all this is done like when all the sanity checks are passed and then it just takes the first block, puts it off the free list and returns it. And in order to take it off the free list it will do like the classical pointer exchange that many of you might know from old school DL malloc or whatever. So what we learn so far about the heap is the following. Like in the setup that most of you probably know a heap chunk like has a header part that is not visible to the user actually and like the real user data. And inside the header we have the fixed value that we have seen already. We have the pointer to the management structure and then some other stuff that is not so important here. And then it continues with the user data part which is actually like the pointer that malloc returns you and like if the chunk is in use then obviously the user data contains the user data. If the chunk is free the allocator will place some meter data inside the user part of the chunk which is also pretty common. So it will start with a value of 0x bet 0, bet 0 just like as a marker and then it will place two pointers. One pointer to the next free chunk in the list and one pointer to the previous free chunk in the list. So it's a doubly linked list and this list is stored inside the user data portion of free chunks. Okay, so as we mentioned the allocator uses different bins for chunks of different sizes and so each like bin has its own free list. And this PGA structure that we have seen before actually contains a pointer to the respective free list. So this is what the structure is used for. So when like we call free, free will go ahead look at the block, look at the pointer to the PGA structure find the free list and then insert the chunk into that free list. And malloc basically does a similar thing. So malloc will take the first element of the free list and use this classical pointer exchange that we have also on the slides here. So it will go like pref next is this next and next pref is this pref. So that like the this chunk basically falls out of the list. And as we see those both operations enable us to do some arbitrary memory override if we control the values there. Like if we control the pref next and this next pointer then we have an arbitrary memory right here. So this is like the most old school malloc attack that you can probably imagine. We use the pointer exchange to write like arbitrary data to arbitrary memory. However to do that we need to override the meter data of a free chunk. So that's the difference to like DL malloc. And this is why we have like a couple of pre-conditions here that we need to fulfill in order to like reliably exploit heap corruptions. So let's look at those pre-conditions. Let's first assume that we have a very basic setup. For instance let's assume the device just freshly booted and the memory is all clean. And then let's just assume we have the following sequence of allocations. First we allocate some 512 bytes buffer. We do that again. Free the second one, free the first one. So the free list is going to look like this on the slides. The first element in the free list is A followed by B and the pointers are all intact like A points to B and B points back to A. And yeah that's like the regular way the free list would look like after that. Let's further on assume that the chunks A and B like directly follow each other in memory. Like there is no third chunk between them. Always keep that in mind because that's like an important thing if you overwrite those chunks. If there was some chunk in between and we would like write more bytes in order to reach the chunk that we actually want to overflow. Okay but like to make it simple let's just stick with this setup here. Okay so this is what the attack is going to look like. We have our free list that we already detailed on in the last slide. And up to now it's like perfectly in order and it's all fine. So the first thing we're going to do is we are allocating 512 bytes again and then the free list is going to look like this like the second part of the list. And keep in mind like in memory B directly comes after A. So now we overflow the A buffer that means we write data into the meter data part of the B buffer. So now we have a modified free list that contains B as the first element still but B has corrupted next and pref pointers. So instead of the next pointer we now provide some value that we want to write into memory. And instead of the pref pointer we provide a pointer to a memory location that we want to override. Okay so this is pretty much the basic heap overflow stuff. Okay in order to do all that we need to take care that the memory layout is alright in that. So we need to have two consecutive chunks and we need also to have a pointer that is like heap management structure and we of course need to know like what value do we want to write where. Okay so we're going to cover each of these items. Fortunately influencing like the heap layout is pretty easy because in like this very bug we can specify the size of the buffer that the system is going to allocate. So we pick 512 bytes that's not used so frequently in the rest of the system and fortunately we can control even more of the heap by opening TCP connections to the device because for each TCP connection the device will like malloc a 512 byte buffer. So yeah this is a useful primitive to make the free list look like we want to make it look like right. And let's then cover like the addresses that we need to know. We need to know the address of one of these PPH structures or at least we need to know the address of something that looks like a PPH structure. We need to know the address of this important piece of memory that we want to override and we need to know where in memory our shellcode is placed. We can basically solve the first and the last problem by just using heap spraying and thereby making it even more unreliable and it probably already is. So we will just go on and heap spray the system and then we know that at some like high memory address we'll have our stuff ready like the fake PPH structure and of course the buffer that holds the shellcode. Heap spraying here is pretty easy because we control the size of the buffer it allocates so we just go ahead and tell it you know what please allocate like, I don't know, 10 max of memory and then we send exactly that amount of data like not overflowing anything. We wait for a second connection and then we trigger the bug. So all wallets are still in memory. For other services you will probably need to come with another approach but then again it's pretty service dependent and yeah. Next question is what do we actually want to overwrite? And this is like a pretty interesting question because of course we could now go ahead and like pick some function pointer in the image but that again like would be image dependent and there is some pretty interesting thing we can do. The interrupt handlers of the system reside at low memory addresses like starting at 100 hex and as I've already mentioned this page is mapped read write executable. So we can just overwrite the exception handlers in order to gain control of the program flow later on. Pretty much like back in the days the exception handlers reside at fixed addresses and here they start at 100 hex. However here we don't have this like vector table thingy that you might remember from Intel. Instead each exception handler like is basically a blob of code that the CPU is going to execute as soon as like the interrupt arrives. Are we going to overwrite the exception handler at 300 hex because this is the handler for invalid memory access. And this is quite some fortunate thing because let me put it this way at least my exploits will most likely bring the system to an inconsistent state at some point in time and this is most likely going to end up in an invalid memory access. And this is great because then we just control like the control flow of the program like we hydrate the exception handler. So as soon as the system access invalid memory we gain control and we can fix it up and like clean all the stuff hopefully like keep the router running. So this is like we could say this is the SEH exploitation of Huawei devices. Yeah kind of. So what you need to do you overwrite the exception handler and inside your shell code you will like first need to clean the heap structures like you can basically nuke off elements from the free list and that stuff to like repair what you did wrong. Then do whatever you want to do like basically use the shell code that FX already provided to execute shell commands and finally you properly exit from the interrupt handler read the CPU documentation for that. That's pretty straightforward actually. And I guess there is not much more to say except for like showing the exploit running so SFX exploits this one also will notify us with a ping when it's done so what we see here we like start TCP dump start the exploit and we actually see making device two connections the first connection we use for heap spraying like we send our data wait for it to be placed in memory and when the device makes the second connection then we actually trigger the vulnerability and the last two lines we actually see that the device pings us which indicates our shell code like actually worked. That's pretty much it from my side so I will hand over to FX again now. So first of all many thanks to Nick Pharr for this tremendously large and great giga-meister that he got me. So what about the larger machines right we talked about AR machines if you've seen the movie Ice Age they had like three melons we have three routers we're working on getting the bigger ones but we have no idea how they look like so far right so just if anyone else now we're actually almost at the end so wanted to give you like something to bring home to your managers what we're looking at here is 90 style box and 90 style exploitation zero operating system hardening at all and a zero page that is map read write and execute no security advisories and no security releases so that's our verdict you essentially get what you pay for sorry and before anyone asks the same question did we find any backdoors if you provide the people that operate the devices and you have buffer overflows and every single service on the device nobody needs a backdoor this is plausible deniability and with that I would like to conclude and thank you for coming