Skip to main content

ARM buffer overflow: chapter 6 ಠ-ಠ (day 76) (bypassing stack canaries by utlizing format string exploit)


Last time in arm buffer overflow chapter we look at how an attacker can bypass NX and ASLR protection by simply brute force the location of the stack memory because of the low entropy of address randomization.

Although brute-forcing the address is easy but is not an elegant way to defeat further protection such as canary. Actually, there is a second way to defeat not just NX and ASLR but also canary protection by utilizing a technique called "information leaking" using the format string attack

For the sake of POC, we will be using source code from billy ellis exploit challenge (link: https://github.com/Billy-Ellis/Exploit-Challenges/blob/master/ROPLevel5.zip)

//
//  roplevel5.c
// 
//
//  Created by Billy Ellis on 09/08/2017.
//
//

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

char feedbackString[32];
char feedbackString2[32];

void give_feedback(){

        printf("\033[1mLeave some feedback:\n");
        char string[16];
        scanf("%s",string);

    if (strcmp(string,"q") == 0){
        exit(0);   
    }

    char leakme[] = "AAAA";
   
        printf(string);
        printf("\n");

        sprintf(feedbackString,string,string);
    char leakme2[] = "BBBB";
        sprintf(feedbackString2,feedbackString,feedbackString);
   
        FILE *f = fopen("./feedback.txt","w");
        fprintf(f,"%s",feedbackString2);
    fclose(f);

   
}

void secret(){

    printf("\n\x1b[32myou win ;)\n");
    system("ls -sail");

}

int main(){
   
    printf("\033[1m\x1B[34m================================================\x1B[0m\n");
    printf("\033[1mWelcome to ROPLevel5 by Billy Ellis (@bellis1000)\n");
    printf("\x1B[34m================================================\x1B[0m\n\n");
   
    int a = 1;

    while (a){
   
    give_feedback();

    sleep(1);

    }
   
    return 0;
 
  



once you create a file with this source code try to compile the file using above command by using the following parameter we enable stack canary in the binary and don't forget to turn on your ASLR in full mode



once it's done try to load it into your favorite gdb tool



you can test the binary by just providing a long string of input



if it says stack smashing detected then you set to go. Next, is to find out where is the location of the canary value stored in the stack. After a couple of trial and error by decrementing the length of the value it stops showing error when I supply 16 bytes

the input was : "BBBBCCCCDDDDEEEE"



if you put a breakpoint after the scanf() function call and look at the stack we can see that after the character "EEEE" the next byte will contain the canary, the canary value always end with "\x00"

so we know where is the location of the canary but how do we predict this value when we to launch our exploit then?

simple!

take a look at the "give_feedback" function



after comparing our input with "q" string it will print the value using printf luckily the value was passed directly allowed us to control the output of the program this is what is called "format string attack"

We also notice that the function using unsafe scanf() function to process our input this is the function that causes a buffer overflow earlier

you can test this vulnerability by supplying this type of input to the program



cool so by using format string attack we can use this to leak the memory in the stack and we can retrieve the value of canary at runtime. But we need to determine at where is the canary can be accessed via format string, we can utilize direct access parameter



I use python to generate the list of direct parameter access, save it to the file and then pass it to the program



after taking a quick view of the result the canary can be directly accessed at the 13th parameter. We can test this by supplying "BBBB|%13$x" to the program inside GDB





from the above figure, we can see that we got the canary value at runtime. You can test it outside the GDB of course. Remember the canary value only change every time the program is started



so we know how to predict the canary value but how can we automate this task to employ it in our exploit. Well, we can use pwntools to make it easy but unfortunately when I try to install pwntools at the raspberry pi it didn't work and I have to reserve into a more traditional approach using pexpect.

note: before you can use pexpect you have to install via pip( sudo pip install pexpect)

so my python script will be like this



the first function called "sending_payload" will be handling the program when it startup, we can see at the beginning of the function there are a bunch of readline() function this responsible to handle the banner of the program when it first runs and receives "Leave some feedback:" then we supply an input "BBBB|%13$x" to leak the canary value

then we readline() again to get the return value, as you expected the result will be in this format "BBBB|<canary value>" so we need to split into two part using .split() function and then get the second part which is the canary value. Don't forget to strip the trailing "\r\n" from the result

At the end of the function, we will convert the canary value into little-endian. This is one of the neat tricks that you can use if you don't have pwntools p32(), we can create our own p32() function by utilizing lambda and struct together



the second function which is "post_payload" will be handling the rest of the interaction of the program and in this function, we will be sending the actual payload that contains canary that will overflow the stack and take over the program flow. The rest of the function code will be just used to print any response we get when we execute the secret function

notice at the main function, below the function post_payload we craft payload by filling the first 16th bytes of "A", follow with canary that we got from the function sending_payload(), append it with another 4 bytes of "A" so we can overwrite the return address and finally supply the new value which is the secret function location



run it and we are able to take control of the code execution and then circumvent the canary protection. Cool! so we can see here that by using format string attack it provide us with a very powerful capability to bypass not just ASLR and NX protection but also Canary

That's all folks :)

Hope you like this post and see you at the next post of ARM buffer overflow



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...

Bypassing stack canaries protection :') (day 51)

In my previous blogs, I show you guys how to bypass some common protection usually used in Linux binary such as NX and ASLR but this time we are going to take it to the next level we are going to talk about protection employ in the modern Linux OS which is "The Canaries" and how to bypass it. note: this post was not originally mined it was inspired by the following resources https://ctf-wiki.github.io/ctf-wiki/pwn/linux/mitigation/canary/ (Credit goes to the author) we are going to start this post about what is stack canaries and types of different implementation of it then move to the implementation about how to bypass this protection. We are going to focus on "leak canaries" technique What is stack canary: In layman terms, canaries are just another protection mechanism to prevent stack overflow implemented by appending 4/8 bytes value (depend on the architecture) into the stack when a function is entered. When the function is at the end of its exec...