01 - Can We Extract The Password?

Here we will be attempting to extract the password and get the correct one, the program is a simple one which simply asks for a password and we have to supply the correct one! Can we do it? Lets see!

Purpose & Outcome

This is a simple yet effective challenge for us to try and take on. Many developers once again will try and hardcode sensitive information within the client side of a program and to test and see if we can take advantages of these mistakes we need to put out reverse engineering skills to the test.

Source Code

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

void main() 
{
    init_wargame();

    char buffer[64] = {};

    printf("------------------------------------------------------------\n");
    printf("--[ Reverse Engineering Level #2 - Secret Password          \n");
    printf("------------------------------------------------------------\n");

    // prompt the user for the 'admin' password
    printf("Enter password: ");
    fgets(buffer, sizeof(buffer), stdin);

    //strip newline
    buffer[strcspn(buffer, "\n")] = 0;

    printf("------------------------------------------------------------\n");

    // check the password for correctness
    if(!valid_password(buffer))
    {
        printf("Incorrect password...\n");
        exit(1);
    } 
        
    printf("Authenticated!\n");
    system("cat flag");
    
}

Program Execution

Here below we will take a look at the flow of the program and how we will begin our process:

So as we can see the program is fairly simple and it requires a password to be entered and if it is incorrect then guess what, the program spits out "incorrect password" and closes the program. Okay so now that we know the way the program works where do we begin? If we look above at the source code we can see a function called valid_password but we do not have the source code for this function so we are forced to read the assembly and figure out what is truly going on, lets go!

Programs Assembly

Great so we broke down the assembly and I encourage you to read it above. This function seems like it is moving the value (which is the password we entered) into the function. After that it jumps to the address of 0x4008c8 which does a comparison to check if the value at RBP-0x4 is below or equal to 0x14 which is 20. So from what I can see and tell the program seems to be looping about 21 times due to the check being jump if below or equal to 20. Also the comparison check is being done on the dl and al register which each of those registers holds 1 byte each respectively. So let us go ahead and set a breakpoint on the address where the check is being compared which is 0x4008b9. Good we set the breakpoint and we entered a random password to see what goes on below, but 1 thing to note which is very important is that if you check the assembly above there is a simple encryption routine and for each of the 21 characters we enter for the password it runs a XOR algorithm and it essentially and checks each character against another respectively at the al and dl registers. This essentially is a loop and does it character by character, but to get this right we want to see below at the bottom what is stored at RAX+0x601080 first and here it is below:

Hmmmm, so maybe this is the password but it is encrypted form?? I think we can now test our theory of setting the al value equal to the dl registers value because from the assembly we know the code is looping through the character and byte by byte is running a XOR and eventually we then must check if the value equals the same for each character in the al and dl register which both hold characters. So what we will do is setup a command for a breakpoint which will do the following at the following address where our breakpoint will be which is 0x4008b9. We will then input the encrypted password we dumped but when this breakpoint is hit we will do the following:

The following command runs every time the breakpoint is hit, it sets al equal to dl and then prints!

set $al = $dl
print $dl
continue
end

Great so now lets check what happens below after we do what we spoke about above!

So we got the flag but we did not get the password....! However because we printed the value each time it looped which was the one byte character each time stored in the dl register we get the value in hex as you can see above! Lets go ahead and assemble all that got printed out!:

{0x75, 0x6e, 0x68, 0x34, 0x63, 0x6b, 0x34, 0x62, 0x6c, 0x33, 0x5f, 0x70, 0x40, 0x73, 0x73, 0x77, 0x30, 0x72, 0x64, 0x5f, 0x37}

Transferring the hex into a string or char for each one leaves us with the password which is the following: unh4ck4bl3_p@ssw0rd_7 let us now go ahead and enter this password in to win!

Conclusion

To wrap this up and conclude it all, this was a simple but yet effective way of retrieving a password and retrieving it against a small encryption scheme using XOR to go ahead and pull it out. Was this the hardest? Definitely not it was rather simple but is another great practice to show how badly things can go when hardcoding information in software. A little reversing gets the job done always!

Last updated