
uh so yeah just a bit of an outline as to what I'm going to be doing who am I and why am I doing this um and we I'm gonna go over a bit of x86 exploitation just to get you in the mindset of what it is like to actually do exploit development um then going to go over uh Android and it's actual internals and take a look at the actual application binary interface of the assembly the registers whatnot um and then I'm gonna actually take a look at exploiting uh unfortunately my work um uh yeah unfortunately my demo died on me uh so I typed it out instead um and then yeah gonna talk about some mitigations that Arnold implemented um so firstly an introduction uh I am John D John Doe or some may call me um I work at ba assistance as a security researcher um been up there for the past two three months I'm also a university student studying part-time uh and yeah started my second year currently studying cyber security and then I also play ctfs in my spare time and have been doing that for the past three to four years started out with x86 reversing um moved on to expert development a year after that in the x86 looking at stack Heap and then a bit of Linux sorry the kernel exploitation and then I moved on to Android versing and Android exploitation in the last one or two years so why am I actually doing this um I in my research there is only one talk conference talk that I've found which is exploited memory Corruptions in an Android context um yeah you've got the links there and you've got a couple of more talks uh exploiting arm binaries um yeah so there's just not enough awareness of this that is out on the public internet um and I recommend like yeah a lot of people check that out there is the link there that's the 2013 so that's a 32-bit um context a 32-bit arm and we're now running yeah armed 64 was introduced in 2014. uh so there's just yeah there's just not any research done um so yeah let's take a bit of a look at exploitation just giving us a bit of a background um so normal x86 64 exploitation normally starts out with a buffer overflow or a format string or some way where you get an out of bounds read or write one of the ways which once you've found that vulnerability when you start to exploit it how would you actually like get code execution that's what we're here for um the main used to be main way was Shell Code um executing or compiling assembly into machine code in which you could then Chuck that into the binary um and yeah just run Shell Code it will get you out of reverse shell get you out open files whatever um that was prevented with non-executable which is a page table uh mitigation which essentially says all your pages so Pages you stack you'll have c um regions in the binary um that basically says this page can either be read and writeable or read and executable so this means that you're not able to write showcode onto the stack and then execute it just because that will break the NX uh so how do we get around that we went to Rob uh return orientated programming uh that's now turned into or sorry some extra ones are drop and cop jump and call orientated programming um and that is chaining together assembly instructions um with a return or jump to essentially get code execution and these Rock gadgets are used in any rect 2x your rep to live C so that's jumping or pushing a bin sh onto the stack and then jumping to the system cool um you've got ret2 CSU which is using the Thunder lip CSU in it which is defined at the start of every C binary um and yeah there's a bunch of sick rocks and everything else um so how was that mitigated not quite mitigated but how was it made harder we or introduced uh Pi position independent executable or pick position independent code which essentially defines a page as a base and then every um every function in a binary is an offset to that base um and so that's effectively how Pi Works um how do we defeat Pi an aslr aslr does the same thing um Pi is just for the binary aslrs for all the other Pages snack Heap Lipsy LD and Linux um so yeah how do we defeat those it's a bit of a camera Mouse game as you guys see but how do you defeat those it's leaking leaking um leaking addresses which we can then calculate offsets to the base of the page and then we can find any other offset we want um so yeah let's take a look at Android so what actually is an APK uh an APK is essentially a zip file um there's a bit of a bash script up there um but that essentially uh tells you how many of each file descript how many each file extension there are so you have an Android resource file which contains the identification or IDs of every single function in an app um as well as any anything in an app uh you then get your Dex files which are your byte code um so I forgot to mention uh Java is written in apks Android um applications are written in Java and or kotlin um and they are then compiled down down to yeah your bytecode um so the decks is your bytecoded version of that your MF file uh your manifest file when publishing an APK you have to sign it signed with the RSA key down there the extension uh and that manifest file contains a hash of every single uh every single file in the APK and it's hash so when people want to recreate or add extensions to your APK they have to sign it but those hashes won't align effectively um and then yeah we get a couple of others the big ones are pngs and XML files uh every file in your Android phone is an XML file every yeah view rather is an XML file um so yeah so that's effectively what we're working with um and when reversing an Android app application you want to look for the Android manifest XML file this contains the entry point for when an Android app starts uh uh yeah as you see there it's commonly your com company name slash appname dot or slash mainactivity um and that will show you any broadcast activities any intents that an Android has ways to interact with that Android app not from the user there's also the strings uh so yeah you get the two paths there um the top path is from Android version I think SDK up to SDK 24 which is Android five six I believe um and then the bottom location um in your resources to our AR a resource um is yeah where strings are now located um and then there's also this folder in slash res slash lib slash star lib stands for Library and oh that picture didn't come out well um and yeah reslib contains um shared object files uh again something I forgot to mention uh Android apps whilst using javo kotlin you can also interface with them through C and C plus plus an assembly through the jni the Java native interface and that allows you yeah to do anything low level that you want uh threading opening files whatever uh and so yeah so these have to be compiled and then brought in with the app so these are stored in your res slash lib slash star.so files so that's a bit of brief about that uh so let's actually Dive In to what an so file contains uh this is the bit which people don't like this is the bit which people are scared to get into reverse engineering because we take a look at assembly we take a look at registers um it's the bit that scares people um um have done a very very good thing of having an actual web page for their documentation uh you take a look at Intel's documentation and that is just a 5 000 page PDF um which you do not want to read through uh AMD has something similar I think theirs as a web page but it's not the most accessible no hate to Intel and AMD by the way but uh yeah arm just have this absolute lovely uh way of searching through through this website um so let's actually get a look at the registers involved um so as you can see there I've put the x8664 if you know that um those registers there uh so yeah you get your x0 to x30 registers those are your generous general purpose registers and those correlate to your Rex to RDX R8 to R15 registers in the 64-bit context um so the first eight registers X naught to X7 are your are the registers that hold arguments to functions um if you have more than eight arguments you put them on the stack um and yeah as you can see that correlates to those registers up in there I can never remember them which order they go in let's see I put them up on there x29 is your frame pointer so in x86 yeah so an x8684 um you've got your stack frames for divining functions so this is essentially what the x29 register holds um so yeah as you can see it's the RBP register you get your x30 uh register which isn't really known in the x8664 world um and that is what's known as the link register and the link register holds when you want to jump to a function um essentially this x30 register will be pop uh yeah it will be populated with the address of where you're you're saved RBP in x86 World effectively um so when you want to jump to functions that is where you want to be looking for that is where program is going to be redirected to the in the x30 register you then get your stack pointer um also when used in assembly code known as the xero register um and yeah that again correlates same similar to the stack frame with your RPP and that's used there uh finally you get your program counter same as x86 um and then your current program status register or application program status register and again x86 just holds the flags something interesting in um specifically 64-bit is that the arm registers can only access or sorry yeah the arm assembly can only access 64-bit and 32-bit um parts of registers it cannot access 16 or 8 Bits as you see in the x86 World um if you do want to do that you can't uh that's in yeah the 32-bit version of arm uh so you're only able to access 64 and 32 um denoted by X for your 64-bit and W for your 32-bit uh yay assembly um so yeah as you can see we have a bit of a different uh relation or a bit of a different layout to x86 um with arm um usually takes three registers or three operands for an OP code in the instruction um the move and compare saying that I've just put a couple of two um but yeah there there's two or three uh registers involved um the normal way of thinking is the first operand holds the result of the instruction occurred on the second and third register so as you can see you get move uh compare ldr load register um and then it's got a couple of arguments as you see with the over top you get the immune mnonics and then the S uh that stands for sign um oh yeah and then the conditions um so down in the that LS uh ldr bit sorry uh those are your conditions you can have a signed byte you can have a signed half word um or two bytes or you can have a signed word which is four bytes and of course you can remove those s's for unsigned um there is also this um concept of indexing uh taking a look at the next two load register assembly codes um so yeah it pretty much tells you they're in the purpose what they are doing but essentially you have post indexing which is that top on there which is saying add 8 to the X1 register and then perform some functionality load it into X zero um you can have normal intermediate indexing which is your standard um kind of yeah um load x0 and X1 into x0 and then add eight to X1 the store assembly code um it performs the load but in the opposite direction of which way around the registers are um and you can also store a pair of registers so you commonly see this function down there um at the beginning of functions you're going to store the pair of x29 into the stack pointer and then x30 into stack pointer plus eight you can also add a comma and then a constant after the stack pointer say that you can Define where that second register is going to be [Music] pointed to all stored um and then yeah as with x86 you get your jumps in arm we have branches um Branch to x0 BL Branch to a label BL Prince f for example um and there's a couple of others uh take a look at the documentation on documentation for more uh and then there's also the ret instruction um which yeah as I was talking about the link register it's going to jump to the X where what the x30 register holds um yeah uh a couple of more um these are more your addition subtraction your logical mathematical instructions um the LSL means left shift or sorry logical shift left and logical shift right um and yeah as you can kind of see those are just the instructions uh ad sub and or or negative X or not reverse which quite literally takes the bytes on the right of a register punks them to the left and then yeah you can also rotate right for some odd reason um the yeah however much you want of a register uh so when actually reversing I talked about the functions and the um sub so what do we actually see uh so there is this we want to First allocate some space for our function as we see in the intel only add decrement the stack pointer by a constant how many registers you want to store on there we're then going to store these x29 and x30 registers the link register and frame register onto the stack pointer just to save them and then yeah we're just going to perform all our other functions um and yeah on the right hand side is just a bit more where you've got a couple more variables used um and then in your epilogue when you want to exit the function uh you can load a pair of registers x29 x30 or sorry load the stack pointer into x29 and the stack pointer Plus 8 into x30 uh and then yeah essentially close the stack frame adding 10 or sorry 16 to your stack pointer and then returning um as you can see on the right you've got a similar thing um this time there's just a check with sack pointers which I didn't mention at the start but yeah you get your stacking Aries um essentially checking if there is a buffer overflow uh yeah um just jumping a bit abroad from an application Level um in Android sorry in x86 uh we have the ring model of ring zero being the user space the space where applications can run and then we got ring one and two which is where device drivers are able to run their code um and then we have ring three which is for kernel operations so and that's just yeah Degrees of Separation um just separating out your memory so we have a similar thing and in arm context uh we have the exception level zero uh so any time that an exception is raised whether that be anything that goes wrong um there's been a buffer overflow some address has gone wrong um it goes into one of these exceptions and so yeah so you get your exception level zero is your ring zero where user space applications happen um you get your exception level one which is where the kernel will operate um then you get your exception level two the hypervisor um and then you also get exception level three which is your firmware and again just Degrees of Separation most people know that in Android um the Android is built off the Linux kernel a bit more hardened with a bit more SC Linux and it separates its applications out into its own user um so it's called its own user ID group ID um but yeah this is just saying that it actually goes a bit more further when you dive deep down into the actual levels of privileges so yeah let's go a bit more back on track back to exploitation um so when you want to reverse an Android app you want to get it from the target device that you're running it on it might you might get it from the Google Play Store uh you might get it from it might be provided to you from you it might be from a shady link from the internet uh looking at you APK tool um APK Droid um or you can yeah when downloaded on a Target device on your phone on the iot uh you can pull it with ADB Android debug Bridge uh and yeah that's just the commands up there that you can use to pull an APK once you've actually got it um if it's an APK we can then extract it um we can either either through unzip or we can use APK tool which does a bit more than unzip it unzips and converts the decks bytecode into actual Java code so it's nice and easy for us to read and then once we've actually got the contents we can then start reversing uh we can Smiley is well yeah Smiley is assembly in x86 ways um and yeah we can start decompiling using jadex or any other decompiler and we can also use decompile Elf or shared object files and through ghidra Ida Pro x-rays or whatever uh so this was the bit where my demo wasn't working I was going to show you how to perform a rock chain um on an actual Target device although I for some reason it wasn't working some stack registers um so this is the essence of what an actual attack would look like let's say that you had a c binary that I don't know uses the get function because that's insecure it's not size checked we can perform some buffer overflow um so yeah we can essentially provide our padding up to where we want to overflow the buffer um we then want to load into x0 our first argument to a function the bin sh pointer if you want to execute system bin sh for example um and then yeah we're going to do that's a very similar thing we're going to load uh the assistant the point to system into the x30 register uh and then just watch our show code run and hopefully get a show uh although it's never as easy as that and you don't just get gadgets handed to you like that like your ldrx0 to the stack pointer um as with yeah sigrop and uh normal Rock on oh yeah rep CSU for example uh in your actual binary um there are very limited registers so sometimes you have to be creative in your op chains um and yeah so that was that I was going to show yeah actually reversing but yeah it's just a bit of a pain um so yeah let's talk now that we've actually exploited um what is arm actually doing to prevent these um exploits vulnerabilities from happening so first off as with x86 we get xn your non-x sorry wrong way around and X which is your non-executable pages in arm we get x n uh execute never and that can be broken down into uxn your user privilege execute never which happens in the E exception level zero your user space applications and then it can be also broken down into kind of your kernel area of pxn uh privileged exec execute never uh and yeah this is just a bit more from how that actually works from the actual arm documentation they've actually documented how they are preventing which is actually really cool um you don't see that in Intel um and yeah so yeah you can read that uh I think the main point was location writable in exception level zero in your user space is never executable at the kernel level um regardless of how what the control bits are set to in configured so we then get our Rob uh how do we how is our mitigating against Rock chains um they're introducing something called pack or pointer authentication code um some of you keeping up with security might have heard about the most recent Pac-Man attack um where some researchers from an institution in America uh essentially defeated um this pointer authentication code on the Apple M1 chips which is really interesting really good read would recommend it um so what how does pointer authentication code work registers I should say registers uh actually use so yeah you've got 64 bits to work with registers only use 52 bits of that sick divorce space um and so what arm have done is they have essentially realized this and said okay can we store a signature defined by this pointer authentication code defined by a couple of keys and how we do stuff um we're going to store those in the 52 to 64 bits of a register um and yeah as you get that big wall of text there um essentially what that's doing is that means that for when you leak addresses in the pie oh yeah in the binary you get your gadgets but then you also need to try and find where your Gadget is for this signature how how this function is actually being signed um so something that we haven't quite seen on Intel um would be quite cool to see it uh but yeah so that is how rock is being mitigated uh and I mentioned job uh jump orientated programming um how is R mitigating against that it uses Branch Ta