 Alright, next speaker is Zuck, he's going to be talking. So let's please give him a big DevCon welcome. Come on. Thank you. Hello and welcome to my talk on arm exploitation techniques. Thank you, crowd. I love you. Hello and welcome to my talk on arm exploitation technique. Thank you again. Can you hear me? You're in the back. Alright, we got it. Hello and welcome to my talk on arm exploitation technique. I actually said it three times now. In this talk I'll cover exploitation technique on both arm and x86 architecture from scratch actually. So if you've never done it before, it's the time to start actually. This is my first DevCon ever. So I'm really excited to be here with you. I'm really happy to attend this great conversation, this great event. Well, I had a buddy who had to go yesterday. He couldn't stay today. So I promised him I'll take a photo of you while you scream DevCon. So if you can do that for me, that would be awesome. Like five, four, three, two, one. Yeah. I'm going to pass it on that blog right there. So you can see yourself. I'm Isaac Avram. My nickname is Zook. You can call me Zook if you love me. I work for Samsung. I'm a researcher there. I do some neat research for them. I really like it. I'm also a partner at PIA. PIA is a pre-incident assessment. Just penetration testing, reverse engineering, custom stuff like that. You can follow me on Twitter under that account. It's actually a sticker name I borrowed the name from. That's the blog. The full presentation and the paper which will have like more technical details will be there. The updated one, not the one in the city. It's quite not updated. It doesn't got any Android info. So the updated one is going to be there in a few hours. For any request, talks, whatever Dirty offers, that's my email. Feel free. Well, like I said, the presentation is not enough. You need, if you really want, like, it's nice to know exploitation techniques and stuff. If you want like real more technical details, you can see the paper. It's on the city, but it's also will be in the website, the updated one. It'll be there in that website. All right. So that's what's going to be actually in this stock. We're going to start from the very beginning. And someone just told me to speak louder so everybody can hear me right there. All right, cool. Like, what's the calling convention? Why ARM exploitation is different from x86? What we need to adjust in order to make our exploit work from x86 on ARM? Some logic is different. Some logic is different. Some local attacks, remote attacks, and finally a demo on this Android phone. All right, let's do it. So that's the best skills I can get in PowerPoint because, all right, if you don't like it, just leave it because I can get any better in PowerPoint. Anyway, why would someone want to hack a mobile phone or a ARM device or whatever? Let's stay on mobile phones. There's various reasons you want to do that. One of them is just, it's just like a regular computer these days. You can use it for botnets. You can make calls, send SMSes. That's someone who wants to attack from remote. You can just charge them. You can do whatever you want. It's a computer that can make calls. So that's it. Also, applications are very common these days. So if you download a malicious application for, let's say, a weather, some checks weather, and it actually wants to use your Bluetooth or send emails from you and stuff like that. And also, it only requests, in the manifest, just permissions for the, I don't know, nothing. And then he exploits some system APIs to privilege escalation and just use the Bluetooth model or your internet or your calls. Someone can steal your calls. And there's also the user itself that would want to hack a mobile phone. You would want to do that to reveal some stuff that the mobile operator didn't allow him to do. You can see that in iPhones. A lot of people do that. All right. So after the very beginning, we'll cover the status of Buffalo Flows on x86. These days, you can see on x86 many defenses from Buffalo Flows. It's really hard actually to exploit these days on x86 architecture. The stack and heap is not executable. You got stack cookies. ASLR is very, very, most of the places are randomized very good. It's really hard to bypass, especially if you've got all of the vectors. On ARM, it's quite different. The architecture is different. So you have to adjust stuff. It's not fully working. Also, the stack and heap, they're not executable on most devices these days. But you can see ASLR. Most of the time, there is a PAX patch for a Linux platform a few months ago. So now you can see ASLR being implemented, but it's not mainline yet. So let's cover x86 or Tulip C attack. I'm just beginning from scratch. If you want to exploit stack overflow on ARM architecture, on x86 architecture, it will be something like that. It's very easy to... Can you see my mouse monitor? All right. It's very easy to exploit. You just put the buffer here. Let's say you want to slash pin slash SH to execute. It's just very easy. You put the buffer here. You override the EBP. It doesn't really matter, actually, because it's good for framefaking and more advanced attacks. But in this case, it's not. You just override the EAP with the system function address. You can also put return address and just push parameter on the stack. So you put your parameter in the payload like that. It's very easy. I think x86 was meant to be hacked. I mean, look at that. You can push parameters through the stack in the same payload. I think someone up there wanted us to hack the x86 to make it easier somehow. All right. So for the demo, like I said, we would want to use the system functions. Just execute our command and we want to execute slash pin slash SH. All right. It will not work on ARM like that. It wasn't meant to be hacker-friendly like x86. I think that's my opinion. So, yeah, you know, just don't. Also, why wouldn't it work on ARM? Because if it worked, we wouldn't have this presentation right here. And it has different calling conventions. And it works differently because ARM assembly works differently. And we just want to cover that. So we're going to the technical part. Actually, when I edited this presentation yesterday, I wanted to add this girl. I wanted to do a break before the technical details. Just put girls with tits or something. So you can have a break before I'm going to technical details. But I decided to remove it because there are some girls in the crowd. So that's, I'll get killed or something. All right. So this is the basics of ARM assembly. That's what actually you need to know for this presentation. You can also always become better, that one. The ARM assembly is unlike x86 assembly. In x86, if you want to push parameter, you can do it through the stack. In ARM, you just need to put it through the registers. So let's say if I wanted to put slash b in s h to push it somehow, I would need to put it on r zero. And I can do it through the payload like that. So that's less sucker friendly. Also, the registers can be edited. Like PC is similar to EIP. It's the instruction pointer. And you can actually move address to PC and will be the next instruction. What you also need to know is, well, r zero to r three are the most important registers. The rest, r 13 is the stack pointer and l r link register is r 14. r 15 is like I said, the EIP of ARM, it's PC. So let's start it exploiting. All right. So the libc overrides the return address and pass parameters to a vulnerable function. But we can't pass parameters on the vulnerable function because we need to store it on the r zero register, for instance, in this one. So we're quite screwed. And we can only override existing variables from local function. So it usually depends on which function you're as the vulnerability in it. All right. And we can also override the PC, the program counter. So that's what we'll use in order to get full control of the application. So there's no really ready to libc attack on ARM. We'll have to make some adjustments. So, all right. Why is it actually passable? So when entering a vulnerable function, the pushed parameter, it's usually it's not all cases, but it's most of them. The r 14 is being popped into the PC at the end of the function. So if you can override the r 14 at the end of the function, it will be being popped to the PC, the r 15. So you get control of the code. If you can control it, we can own it, actually. So let's do it like a POC in a program that is very hacker friendly. All right. It gets the PC. Right. It gets the buffer here. And the stack pointer is pointing to the beginning of our buffer. It's very convenient. Our zero is pointing to the beginning of the buffer. Also very convenient. So let's just put a command here. And after we override the PC, just we'll put there the system address of the function. So we'll see PS is being... I'm actually on my screen. All right. It's mirrored. You can see PS function is being executed. But that's a lie because that's very convenient hacking friendly program that I made especially for that. So that's not a real life scenario. Anyway, that's the POC that it can work. Okay. Let's face it. It's not real life scenario. In order to have that scenario, we need a function that returns void that after the overflow nothing happens. So our zero will not be deleted. And it should be small. There's another problem with that. The buffer should be small. Like 16 bytes in order to have a free space of the system function not using the same stack pointer space. So it will not override each other. So there is actually almost no chance in the world for that to happen. And if it happened to you, you're very lucky. It's like ringing the jackpot in Wheel of Fortune outside. So, yeah, you don't want that scenario. All right. So what do we need actually for successful exploitation? We need several stuff. So let's do it. We need parameter adjustments and variable adjustments. Parameter adjustments will be just register adjustments. R0 to R3. We must modify that in order to continue exploiting and do whatever we want. We also would like to get back the control to PC. So after we execute some command, we won't still control the flow of the buffer. And we also might want to do a stack lifting because, like I said, you don't have to count on that the buffer to be 16 bytes or if it's a longer buffer you're screwed. You don't want to do that. In the 16 bytes you just get four bytes of buffer that you can execute. And that's not enough unless it's a local attack. So like everybody is just making attacking names. So we just made a new one. Because it's, I don't know, I don't really put a lot of thought of that. But it just makes a lot of stuff. We're trying to program it. We're trying to stack lifting parameter adjustments. And that's it. I mean, it's not really a name, just like a joke. Like everybody in the security community just make up names. So this is for Zook, but don't tell anyone, right? So I won't put my name outside. So how can we control the R0, R1? You're probably fascinated about that. So like amazingly fascinating. R0, yeah. All right. So we need to actually jump into a pop instruction. We'll do return oriented programming. There have been several return oriented programming in Black Hat this year. And I think in DEF CON also. Very interesting. You can put that with this attack and do some more complex attacks. You can do actually whatever you want with that. So we'll need to jump into a pop instruction. Which also pops the PC. Or we can control it later. And we can control the R0 or maybe more, right? So I just looked like a quick regular expression on libc. And you can see like LDM is like pop in Intel. It's similar. I don't want to get into details what's different. But you can see it's popping R0 and R1. So if we jump right here, this address will be able to pop R0 and R1. We'll put any values that we want in there. Also you can see the stack pointer is lifting itself by 12 bytes. So there will be actually R0, R1 and extra 4 bytes. And then you can see pop PC. So we got 4 bytes of junk. So what we want to do after the buffer, we got AAAs. R4, R11, it all depends how it's compiled. And then we'll be jumping, actually it's a mistake here. It's not 4, it's 48. So we'll be jumping here to the LDM instruction. And then we'll pop R0. We'll put it inside the slash bin slash SH address. R1 is not really matter for that one, but it's just 4 bytes. And then we got 4 bytes of junk. It doesn't really matter what you put there. And then we'll call system. So that's the original idea of how you can control the R0 and R1 instructions. But that's only good for local attackers. So let's we can do some more complex return-oriented programming payloads, but let's just keep it that way in the system function. It's very easy. So if we can control R0 to point to a relative path to be in the beginning of our buffer, we can actually put any command. Let's say we want to put like netcat with reverse shell. We can do that if R0 is pointing to the beginning of our buffer. So what we need in this one is actually to have like R0 to point to the relative color to the beginning of the path and then we'll call system. But like I said before, we need the size of the buffer to be a certain type. So it will not work because it's for short buffer, we only get the words of unwritten commands. For long buffer, we get none. So that's not enough. We have to stack life. So that's another thing in our attack we need to remember. Sometimes we just got a stack lift ourselves in order to execute the full payload without being controlled by the lack of the creators of libc and the one who compiled it. So our commands are actually very easy, very nice for exploitation. There are several variations of the same stuff. You can do many instructions. It's much more better than x86 in my opinion. So let's see what we can do in that one. We can abuse the current stack pointer. We can just lift ourselves and then just go back. So let's just a quick look. WPrintf function, epilogue. You can see that you can pop LR. If we jump right here, we will jump right here. And then the SP adds to itself 16 bytes. And then the next instruction will be BXLR. BX means branch. It checks the first bit. But in this case, just say it's like a call. Advanced call. So like x86 advanced call. So we'll get our stack lifted by 16 bytes just by coming to that one. And then we'll put a new instruction right here where we want to jump next time. So we can jump again and again and again and lift our stack. We only need to lift our stack 384 bytes so the system will not override ourselves and we can execute whatever payload we want. So if we do that, our payload will look like something like that. Like net cut, reverse shell. And that one is actually very important because it ignores the rest of the command until a null byte. And then we'll override the function and just go back and forth, back and forth until we lift it enough of the stack and execute. And then when we finish, we'll just go to our zero adjustment. Maybe that was a better idea to just put it right here. But anyway, we'll go to our zero adjustment. Again, our one adjustment, four bytes of junk and then we'll call system. And we can execute whatever we want, whatever size we want of the buffer. So another interesting parts to adjust parameters will be, I just seen it on M count epilogue. You can see you can pop any, all zero to all three, whatever you want. And R11, LR. And then you branch to LR. So you can pop and adjust multiple parameters in the same jump, in the same return oriented, in the same widget of this one. What we want to do next would be, as a remote attackers, would be actually to enable the stack and execute whatever we want. That can be easily done by calling and protect and changing our place in the memory to be executable. And then we'll have to jump on it. There is a good section of that on Perk magazine, the Alphanumeric armshell codes. So yeah. All right. So yesterday I was very bored. It was like 3 a.m. And well, that's the Android device. I'm going to demo on that one. Actually, we went pretty fast. It's cool. So let's see if we can get a shell out of Android application. There are several limitations on Android devices. First of all, you don't want it to be like a Dalvik application. You want it to be a native Android application, for instance, something that had been compiled with NDK. NDK is the native development kit for Android. And well, it's actually pretty hard to compile dynamically. There's lots of tutorials in the Internet, but it took some time. It's not user-friendly. And also Android Lipsy had been compiled differently. The BNSH is actually nothing in Android. There is slash system, slash BNSH. They recompiled their Lipsy. And they did, I don't know if they did it by mistake or by luck, but like by mistake or they're really meant to do it. But Lipsy of Android is much more harder to exploit because it has no pop R0 instructions and stuff like that. So you have to be a little bit more complicated to do that. But it's the same technique. So it works on every ARM architecture. So we don't get things on R0 immediately. But we can do that. And the slash BNSH is actually on a different path. But for instance, the system function is being implemented that it executes execve function with the full path of the BNSH in regular Lipsy. So it has to do that. You're also, so they just modify the variable and they just put system slash BNSH. So that string should also be in the same library. So we're cool with that. All right. So don't worry. It's all the same. Also here in Android. We'll get the slash system BNSH to R0. And we'll not pop R0, but we'll do a trick to do that. As you can see that, I hope that some people can see the trick here. I'll give you like 10 seconds to think about it before I say what it is. It's the mal info function, just a function in Android Lipsy that I took from that one. And you can see that you can pop to, that's a pop instruction if you're not familiar with ARM architecture. So you can actually pop to R4 and get the PC back. So let's do that. We'll pop to R4 instruction so we can control the R4 register. That's the first step we want to do. So after we control the R4 register and we control the PC, which means the next instruction, we might want to go here. So we just control the R4 instruction and then we move the R4 to R0. And then we can put some more four bytes of junk on R4 and we can go to system. So our payload will look like that. If that thing is the LDMD R4, we'll just put this, slash system, slash BNSH address in R4 and then we'll jump, like you can see, it's four bytes offset between that one. So we'll just jump to the first instruction and that will move the R4 to R0 and then we can put some more four bytes of junk that will be on the next R4, the second phase of this attack and then we'll go to system. So, well, I'm quite, I did it too hairy. I was too hairy to do the conversation. So let's show the demo then. So what I did here was actually compiling, yeah, I can read it. A native application for Android, just to run C application on Android, what it do is just calling a vulnerable function. That's after the function. So you're not supposed to see that if the payload that succeeded or the program had crashed, because after the function we would get a segmentation fault. So we go to the STACO, which means stack overflow, and we got two buffers, a small buffer and a big buffer. What we do is actually read from that place, slash SD card, slash buffer, and we'll just put the stuff in it on the small buffer via memcpy. I use memcpy because there's actually, I think there was a null in one of the parameters. So they were lucky on this version but it was an honest mistake by them, I think. So I used memcpy to copy the buffer to the small buffer. Small buffer is 16 bytes and the big buffer is, I don't know, 256. So what should happen if we succeed in this one is actually getting a shell. I put my shell code is on that place and it has the same technique I described here. So what we're going to do is put AAAs and then we're going to adjust the R4. We're going to jump again. We're going to adjust the R4 to slash system slash bin SH. We're going to jump again to the move instruction. So the R0 will contain our parameter and then we'll jump back and do the system. All right, so let's do it. That's this device right here. It's the G1, I think. The only Android device I had on my desk. Let me find it. I was a bit drunk yesterday. No, not really. So that's our function. That's our binary. It has the same technique. It's just the C code that you just saw earlier. It was an item to compile it on Android. But here we go. I'm going to execute it and we're going to get a shell. So we got our shell, like you can see. And if you can see what executed is the buff one executed a shell that executed a shell. So we made it. We won. Victory. All right. I feel like dumb. All right, thank you. And so we actually made it and when we're going to exit the binary, we're supposed to see a segmentation fault. And it's not going to get into the printf that after the function. Because the path has been, the path of the execution has been altered. So we're going to exit out of the shell. If I'm not joking with you, it's supposed to see a segmentation fault. So we just stop it and now... All right. So we did it. We got a shell. That was the least complex one, but this stuff works. So that's the whole point of the talk, right? So you can do whatever you want actually on Android. So I'm about to finish right now. I did it a bit earlier. You might want to catch some other talk anyway. The buffer holes on ARM are actually a real threat. We need some more security mechanism set up on that one. And like fully ASL ARM mainline, we want to do that. And if you're writing an application for ARM, don't count on it being unexploitable, because it can be exploitable like you can see. Sometimes it can be even easier. Sometimes it's harder. It's not a hacker's heaven like this, but it can be done. If you want to prevent it, we want not a single unrandomized static code and stack cookies, and like the most vectors we can to prevent buffer holes, the better. If anyone got questions, I'll be at Q&A 114. You can download the full talk and the paper, like I said. And if anyone wants a business card or something, I got like a full pack here. Anyway, special thanks to some guys, Ilan from Samsung Israel and Moshe Verde and Matthew from InGuardians. Help me a lot. Some references, and that's it. Thank you.