Skip to main content

Azeria Labs ARM challenge ROP Exploitation (day 90) ಠ_ಠ



When I was scrolling through my twitter feed 2 weeks ago I noticed that azeria just release new material on her website and it's about ROP in ARM. As you know we talk a lot about ROP in several posts on ARM buffer overflow thus I think this could be a good opportunity for me to learn the basic again about ROP again and without a second thought, I took my favorite notebook, click the link and start learning(check it out in link).

The author also put some challenges about how to construct ROP exploitation in an ARM architecture to test our skills and in this post, I will show you how I approach these challenges.

When you boot up the qemu emulator you can find the two binary in the challenges directory




Note: Before you continue this post make sure you turn off ASLR mode in the QEMU emulator

Challenge1: 1st approach(Without ROP)  




At the first challenge, we got 32 bit ARM binary, not stripped and the PIE protection is on. Basically, PIE enables the program to randomly load its source code in different places. Try to run the program several times so we get the general idea of the workflow.





From the looks of it, the program will take the first argument as the input and if we try to load the program in GDB and provided really long character as its input, it will crash. Typical buffer overflow vulnerability

if we try to see the code in the program the culprit is in the func1 function since it's using strcpy() which consider as an unsafe function.



Let's try to find how many bytes we need to overwrite the PC register, to do this I'm using exploit-pattern tools. Next, all you have to do is put the pattern into the program and as you can see from the figure above the string "e4A" is overwrite the register. Put this result in the tool and we found that the offset is 133 bytes but notice something strange?

every time we crash the program the last character of the PC always ends up in "@" to get the actual offset you need to subtract it by one => 132







Let's try to test it again by crafting a simple python script and run it again in the program.




this time as you can see we accurately overwrite the PC register. Next, we need to find where we want to put our shellcode in the SP so we can jump to this location and take control of the program, we get the information inside the GDB like the below figure.



cool! we have a pretty roomful of space to put our shellcode, I will use 0xbefffab8 to place our shellcode. From this information, we can create our exploit like this:



This script will generate a payload that will redirect the instruction pointer to the desired location which is 0xbefffab8(where our shellcode is waiting to be executed). Run it in GDB and we can see that we got a shell



But unfortunately, when we run it outside the GDB this will eventually crash because of the different environment.



to get the actual location where we can put our shellcode outside the GDB environment we can utilize the core dump file. You can enable this feature by putting this command:



run the program one more time and it will create a core file, this file contains the last state of our program at the time of crash including information of register and stack content

load the core file by using this command:

~# gdb -c core ./challenge1

then dump the SP register and try to find where is your input, you can do this by adjusting the location by this command:

(gef)  x/100wx $sp-100



from this result above we can see that our shellcode it actually located in 0xbec8baf8

update the script once again with this new location

................
shell_address = struct.pack("<I",0xbec8baf8)
................

Run it again and we can see from the below figure we got a shell :) cool!



Challenge1: 2nd approach(with ROP)

The advantage of using this approach is we don't have to worry about the location where we want to put our shellcode and all we need to do is to find a gadget that simply jumps to the top of the stack where our shellcode will be located.

We can search for the gadget inside the libc.so.6 library by using "ropper" tools



from the above result, there are two gadgets: blx and bx it's up to you which one that you choose basically this two gadget will eventually jump into the stack pointer

next is to find the base address of the libc of the program. The address that we have just found in ropper is just a relative address and you need to add it with the base address of the libc when it's loaded in the program to get the actual location of the gadget. You can find this information in the following way:



get the first row of the start address and update our previous python script into this:



now all you have to do is run this script along with the program and we got a shell again :)



Finish Challenge2 with ROP

the second challenge is the same as the first one but the only difference its that the program is equipped with NX and PIE protection.





Certainly, we cannot use the last two approaches because we cannot execute a shellcode inside the stack. So we need to find a proper that let us to execute Ret2libc attack

In the fundamental level ARM use R0-R3 as its 1st-4th argument when calling a function so we need to a find a proper gadget that let us load "/bin/sh" string to R0 as the first argument and jump to the system() function to execute shell

we can find the right gadget by using Ropper again just like the below figure:



we can use the pop{r0,pc} gadget and we need to find where is the location system() function in library, you can get this information in the following way:



remember! this location is a relative address we need to add with the base address of libc library. Fortunately, the location will be the same as the previous challenge because we turn off the ASLR.

The last thing we need to found is the location of the "/bin/sh" string, we can find the location by typing this command, in GDB:

(gef) find &system,+999999,"/bin/sh" (sorry i forgot to screenshot the result)

from all of the information we have gathered it's time to construct an exploit script:





run the script with the program and we got a shell :) cool!

Conclusion:

From this challenge, we got a chance to see several cases that show ROP help us to bypass the protection of NX and make our life easier.

It is important to always find and solve this particular type of challenge to strengthen the basic over and over again 

Lastly, I think from this exercise I could tell that ROP is one of the essential technique for all of the security enthusiast who wants to develop exploit in ARM environment and the author did a great job creating this exercise(*Two thumbs up).

So that's all for today post I hope to see you again in ARM exploitation challenge



Comments

Popular posts from this blog

Having fun analyzing nginx log to find malicious attacker in the net (ง'̀-'́)ง (day 37)

  What makes you sleepless at night? is it because of a ghost or scary stories? is it because you have an important meeting tomorrow? or is it because you have an exam? For me, what keeps me up all night is that I keep thinking about what happens to a website that I just created, is it safe from an attacker (certainly not) or did I missing some security adjustments that lead to vulnerability? well I'm not the best secure programmer in the world, I'm still learning and there is a big possibility that I can make a mistake but for me, a mistake can be a valuable investment to myself or yourself to be better so from this idea, I want to know more about what attackers casually do when attacking a website. Here in this post, I'm going to show you how I analyzed attack to the website that I have permission to design and also some interesting findings that I could get from the analysis Background: All of this analysis comes from the traffic that is targeted to th

Utilize Pwntools for crafting ROP chain :') (day 69)

who doesn't like pwntools? it is a very versatile tool and can be customized according to our need using the python script but did you need to know that pwntools itself can help us to automatically craft a rop chain for us? so in this post, I will show you how to make rop chain less painful and make pwntools do all the heavy lifting. To demonstrate this I will use the binary challenge callme 64 bit from ropemporium link: https://ropemporium.com/challenge/callme.html Crashing the app: Like any other exploitation process, we need to crash the program by generating a long string pattern to determine the offset. based on the information from the above figure we can see that we required to provide 40 bytes of offset Fun stuff: now this where the fun stuff began write the following python script: as in the guideline of the challenged said we need to chain the function call by first to call the callme_one function, callme_two function and then callme_three funct

WriteUp PWN tarzan ROP UNICTF ಠ_ಠ (day 61)

So in this post, I'm going to talk about how to solve the Tarzan pwn challenge from UNICTF 2019. Back in the day when the competition is still going I couldn't finish it and don't have any clue to solve this but this time I was able to finish it :) Also in this post, we will be going to be heavily focused on how to utilize pwntools to construct a ROP chain. If you kinda confused about my explanation in this post you can refer to this following youtube video, link: https://www.youtube.com/watch?v=gWU2yOu0COk I build the python script based on this video Ok, let's get started! In this challenge, you will get two binary first go with tarzan and libc-2.29.so by providing .so file it tell us what version library that the target machine is using this could help us to do ROP chain. first, we run the Tarzan binary to get the basic idea of the program work and as you can see it just show you some text, newline and when you try to input something it doesn't gi