← All talks

Return-Oriented Exploitation on ARM

BSides Budabest · 201923:03958 viewsPublished 2019-06Watch on YouTube ↗
Speakers
Tags
About this talk
An introduction to return-oriented programming (ROP) exploit techniques targeting ARM architectures. The talk covers ARMv7 and ARMv8 register fundamentals, differences between the two architectures, stack-based attacks including buffer overflows, heap-based techniques such as heap feng shui and heap spray, and demonstrates these concepts with a vulnerable application.
Show original YouTube description
The focus of my talk is to introduce Return-Oriented-Programming (ROP) exploit techniques. The talk will also cover the basics of ARM exploit development for those who are unfamiliar with it. The presentation will cover the fundamentals of ARMv7 and ARMv8 registers and also some differences between the two architectures. I will talk about stack based attacks and Heap based techniques such as Heap Feng Shui and Heap Spary. In the end I will show a demo with a pre-made vulnerable app. The presentation was held at #BSidesBUD2019 IT Security Conference. All rights reserved. http://bsidesbud.com
Show transcript [en]

all right so um today i'm going to talk about return or into the exploitation on arm so first of all um who am i so my name is tomintogish i'm a 15 year old ios flashmakers developer and i'm interested in arm mobile security and software exploitation for about two to half years now i'm also continuously working some private older jailbreaks because my focus on kind of on ios and the jailbreaking process but the main focus of this talk is to cover the basics of army 7 and army 8 registers and also i'll show you a couple of differences between rb7 and r8 then cover the fundamentals of rope exploit techniques and in the end i'll

show a demo exploit let's start with army seven so army seven aka ar 32 uh army seven has a fixed size of 32 bits and there is a 16 bit mode available known as thumb mode and on number seven we have 15 general purpose registers and these are labeled from r0 to r15 and from r0 to r12 okay from r0 to r12 these are the general ones and from r13 to r15 those are the special types of registers so r13 is a stack pointer which is always points to the top of stack r14 is the link register which is always holds everything uh address from for example when a function call is made and r r15 is the perfect camera which is

always holds the next instruction to be executed now m8 on the other hand is arm 64 or arc 64. we have a lot more registers so like 30 general registers and these are labeled from x0 to x19 and army 8 supports uh army 7 for backwards compatibility but when this mode is enabled the upper 30 bits are ignored and the register names are actually changes uh slide a bit so it's changes from x to w's and so yeah we have from x0 to x29 the general ones and we have the same special registers like in rmd7 so x30 is a link register the stack pointer is its own register so i also refer to this uh

actually one and the programming camera here is not directly modifiable means for example if you're writing in our in arm assembly on army seven you can just use r15 uh just kind of as a programming camera but not an rm8 so armory 8 supports expression levels as well uh so from lo to r3 and this is kind of our physical separation of levels so even the kind of like rings but that's actually bmi talk now so there is a couple of differences so you can see first of all uh the register name so like r0 and x0 then instruction analytics so like uh move the w and army seven uh and uh the retail instructions so

like on army seven we branch to link register and on arm v8 we just write which is uh basically the same thing just with a different name so yeah here's a differences when adding items to the stack so on army seven we have a punch instruction which adds many special specified registers to the top of the stack and on arm eight uh it's actually um subtract from the stack marker so it actually manually grows the stack because uh in here it's actually the stack is gross the exact opposite way which hitting so it's actually grows downwards and then we have another instruction so it actually stores a pair of register at a specified location now rob stands for

so rough stands for return oriented programming and uh this is a morning and exploit technique and the old fashioned way was to actually use a shell code to execute your malicious code but nowadays actually you would change gadgets do you actually execute your malicious code so here's what we're upgrades are so all rubber gadgets are found within the text segment so the code segment uh and this shortcut just has students with uh written instructions so write the instruction because obviously that's how you can change them together and even hundreds of gadgets could change gary if the program allows you so there's a quick diagram of how uh gauges work so you can see where we have the save

return address that's where we override uh the program carrier so and we put our first gated address there which obviously it prints first gadget then uh once it's executed it's gonna jump back to or return back to the stack and it's uh going on like uh with the gadget to address and so on but as well now the all box slash vulnerabilities are different and sometimes you only have one gadget worth of execution uh for example when you uh dealing with a non-stock based function player overflow and there's a solution for that and it's called stack pivoting and basically stack people think you create a fake stack and to be able to do that you need to control the stack

pointer and to be able to control the secondary you need a special type of gadget called uh pivot edit series is a an example of people get this so it's very simple it just actually actually moves the value of x uh one to the segment so it's just basically override it and the last instruction just load x30 and return [Music] so here's how kind of um stack pivoting stack pointer works so we have the memory and uh we can see that stackman now points to zero see it means it's going to execute from there so like 0x41 if we get an instruction to move down then or pop we can see is now the second we're going

to print points to 10 and 0x41 does not doesn't need to be cleared because it just doesn't count as a stack anymore now if you actually can control uh this uh segment here by our paper gadget you can actually move there and we can control the whole stack so we can just basically execute our blockchain so here's a stack-based attack side the very basics one are stack buffer overflows and these types overlays targets the sac and the main goal is to override the function pointer with ethical control data all right so this accuracy man program is run out of space and you essentially start writing the function bars and the aim is to control the program camera

so here's a actually a diagram of how flow works so you can see that the first uh picture is nothing located in the stack the second when you can see a few is located and the third picture you can see an overflow and we can control this because uh we actually overvote uh the program camera with ace [Music] now i don't think this will work in modern sums because most monitoring some have uh protection against these overplays and emergencies have asl and definitely world as well so yeah um what is asl so well a self stands for address space layer channelization and it's basically rendering design or addressing runtime so if you can see the first one it was a

nine 0x16fd0f790 and the second one was uh 16 f d e seven seven uh nine zero so the two addresses are kind of different so um what's asr for so slr for making the program camera control useless because even if you can control the program camera you just can't jump to anywhere because um you just don't know where anything is so it's also for preventing charcoal from being successful because it's just you don't know where anything is because there are a few ways to defeat aslr so i wrote down two so the first one is a brute forcing which is not very practical because it could take a lot of time and the second one is an info leak which

i'll talk about a little bit so the very basic uh info link one is a format string vulnerability and uh this is due to using printf in a wrong way so we can see the attack can enter basically anything even percentage ps uh to leak the data from the stack so if you actually try to compile that program uh the compiler uh will show us some warnings so uh without the form of string is not a string literally potentially insecure and underlines the format string which is uh in the wrong way so you should actually use uh message performance inspire and then put the deformation so now testing this app is our binary let me see what we enter so

we entered high and here's what the program printed out for us so it's basically simply hi now um all foreign performance specifiers start with a percentage so what happens if you actually enter a percentage high so here's what we entered and here's what the program printed out for us some read output because it's uh treated the percentage h as a form of specifier so a percentage p purpose to print upon your value and if you actually enter a lot of percentage fees you can see uh that program printing out uh uh for us some stick burners so yeah and uh usually 1.0 from the stack is enough to defeat the whole aslr uh by finding the

function in this is this slumber and uh compared the leaked address will be actually just and then compare uh to the static address in the distance number and the difference will be the aslr side and now anytime you want to jump to an address from now what you want to do is uh obviously get the address where you want to jump to and add the asl slide to it so yeah um here's some heat-based techniques so on the heap you have basically dynamic location and you can allocate by molecule and specify the size and you can delocate by uh three and specify the pointer so the first technique is actually heaps way and history does not actually

exploit any security issues so it's like can't really be fixed by an updater for program and his training attempts to put a certain sequence of bite is at a pretty terminated location by allocating a large membrane blocks on the heap and you want to kind of think of a heap straight as you would spray uh what we paint so here's our diagram how it works so we can see before the spray basically nothing located on the heap and after the spray we can see a lot of knobs are located and then our shell code so when we went to put consecutive knobs uh or no operations plus our track code using not as the program to move into

the next instruction and this will happen until we actually reach our chat code and it will essentially execute it we'll execute it there's um some heathen shoe so here thank you you actually carefully place objects in the memory and the repeating allocations and we will have um consecutive memory blocks and after that i do like the allocation uh chemical cause so here's our generic heap overview so you can see the orange is in use and the gray is is a whole so you can see uh we actually don't know how the heap looks like so it's just like some of them are in use and some of them are actually our holes and now let's do the first episode

allocation is repeating often enough so all fours will be closed so let's just do that and allocating a bit more and we will have consecutive remember blocks so now we actually kind of put our data to it so we kind of know how the hip looks like now and now the locating uh can poke holes so like we poke through holes and essentially next location will be into our hole and so by this a buffer overflow can be controlled because if we actually control the data or we can rewrite after this the data before the new allocation uh we can essentially control this buffer overload so user-free um user free occurs uh when a program can need to use a pointer

after it has been freed and we often call this uh dangling pointers and this could lead to a virtual code execution now i took the source code from ios 9.0 is a kernel current extension and what you want to carry by is the if the device is not null then what it will does is cause device terminate and this calls oscillates function and plus an argument as a device uh yeah so the oc release is the untip function because if you actually check out how apple actually defined it we can see they actually didn't set an install so apple should use other surface node they actually quickly patched this uh by setting the device and all so

it was a bit of shame so yeah now here's uh the demo so the target name is b side subway and the vulnerability is uh user free and the architecture which available on his army is having the army eight so every time we went to exploit any uh binary application we kind of always have a checklist so first we want to find the real very uh the vulnerability good or her and then find the addresses for our rope chain and in the end we're going to carve the exploit and test it so here's the first stage um by running the program you can see we have actually six options uh we're interested in five because the

six is just basically exit the program so well option number one we can basically allocate so we can see uh the program uh tells us to enter some data to arcade so maybe we want to actually check this function because um a buffer before make it occur now i have access to the source code because i've read this program but you could get this by decoding from ida or hopper so we can see we have by option number one we actually have a function called allocate object by user and it was an argument as input for outlook so let's check this function um we can see at the scan app it's actually kind of safe because i put like a

percentage 31s which means this will only scan up to 31 bytes and we need plus one for the new termination and the buffer is 32 bytes so it's perfectly now again use the safer function the story and copy not the store copy but we actually have a object stacked here so we actually want to check out that so we can see it's actually defined by struct object and let's go object and here's the struck how it looks like so this is basically a struct and what you want to note down is that we have two function pointers sitting there all right so now choosing option number two you can see it actually opens a file

so entering option number two we can see that the program is actually waiting for an input from the user now let's actually enter a part for a file to basically test this function and we can see that it prints out the data was created uh with hello besides but this is a test and if you actually check what the file contains it basically contains the same thing but the program printed out for us so let's check um option number two so we can see it's actually calls a great data object so let's check this function so first of all we can see that it's basically allocate 200 bytes in the heap now this part is just for uh scanning

part from the user and opening the file and we have the f read now if you don't have a ball i've read syntax it says positive programming arguments and kind of be interested in and now the in the first one and the first one is a pointer and it says uh when there is a reference of an array or a structure where the data will be stored off the um grading that means it will store it to object data which is on the heap so let's continue our journey so you can see um by option number three you can see that it actually allocates device um yeah and we get a message that device was located so but you can uh this

function again which is basically what it does this allocates our two function pointers on the heap there so yes again it's uh it's an instruct so now to actually free the data we actually need to allocate first um if we don't do this uh bill might end up in a double free so yeah and in theory this option number four is only free the data will be entered by option number one but in reality uh this basically what we can see here there is a check so if the object is not oh then it scores a function called terminate object and it passes argument as object and the determinant object just simply free a struct so now we actually know

where the vulnerability is because um it just i use it for free because the terminator object frees the object but it doesn't set the null so checking the heap player before executing option number three you can see the there is nothing on the heap and uh continuing uh if we get the message that device is allocated and we can see that uh our two function pointers are there so just basically allocated our uh two function partners now if you actually um uh call number four or determinate uh we can see that our few addresses are messed so like uh three ones and three tens uh but most importantly our two function pointers are there so it means uh we can

still uh somehow reference to these addresses and kind of overflow with opening a big file bigger than 32 bits right so yeah we actually have this first part because we know where the vulnerability could occur now we want to find addresses so this is the aim of the um uh binary so this is the secret code now okay okay uh yeah so the secret starts at zero x zero zero zero zero v nine fifty so yeah we can just jump there and be done but we can see if we actually jump to secret we have a check here uh which a check variable is if a check variable is equal to zero then it's going to print out for us that

we are inside secret and terminating and basically terminates so checking out we can see we have the check variable and it's set to zero so yeah now checking this uh variable um in this number we can see it's in the data section which is good for us because uh it means we can actually write it because if this would be in the text segment we just couldn't write it because the text segment is uh accessible but not writable but this data segment segment is not um executable but writable not actually placed directly to be in the data section anyways so this means that we actually have to write a rock chain to modify the check

value and then jump to secret uh with holding check the correct value and you once again noted that it also means that we actually have to execute more than one engagement so here's what we know so far so first we need to find the setup credit um to set up our registers then we need to find a correct bracket to write the correct values to the correct address then we want to trigger the uaf block and then execute our webchain here's the first part so we want to find the setup and the right edges so i actually placed these gadgets into the banner because just to be easier um to find it and yeah so we can see uh it's actually pops

r zero and r one r two and program here but this means that we can control r0 and r1 so we basically have uh the setup created now here's the bright edges so what we can see here is it stores a value found inside r0 to a memory location uh pointed by run now this is perfect for us because as i said earlier we actually can control r0 and our bomb values so we have both of them are set up with so now remember we are actually working on the heave and we have one gauge vertebra execution so we need a solution and that is stack pivoting so now we need to find a pivot so um i

actually placed this website in inside my binary so you can see it just basically moves the value inside uh found inside r2 the uh the stack manager so just basically overwrite the value so now we have all the gadgets set up so we can see but we can see that this is the secret code again this is the code when if the check uh uh equals zero it's gonna jump here and it will exit now you're probably one wondering why not jump jump just here and uh skip the check well uh that would be too easy and i wanted to demo how full rock chain works [Music] so um yeah now we have uh the gestures

now we need to corrupt the exploit so here's the how the exploit looks like so we have basically um the search device which will essentially fill up the heap and this will overwrite our first function pointer and yeah so here we go again with the phillip field up here and this is where we override the first function planner and this is actually points to our paper gadget so um after executing the pivot gadget it will actually jump here and uh [Music] uh this will the this will the setup get it so this is the setup gadget address and now we will load 111 uh into r0 and we will load the address of check into

our one so now here's some junk characters um and here's the address of the bracket you can hear some junk characters and here's the address of the secret so after executing this exploit we can basically have full control over the program so now all the checks are done and here's the test yeah so i'm just running the binary which doesn't really matter what we enter there

we allocate the device and uh i just called option number five to just show you guys just basically prints out that first trick was done in second quest and yeah so this is the correct order uh and yeah i specified the path for exploit file now calling option number five you can see that pawn then here's the child and just execute the u name a command so yeah the exploit is complete and here's some useful links so if you want to learn more about arm exploitation so the top one is especially a good one and the last one is my github repair where you can download this challenge from and you can try out yourself

so yeah um this is my twitter handle if you want to follow any of my work or if you have any questions later you can dm me but if you guys have any questions now um feel free to ask and i will try to answer as best i could thanks [Applause]