Easy Crackme.exe

2 views
Skip to first unread message

Louella Kammann

unread,
Aug 5, 2024, 4:26:57 AM8/5/24
to cantlacanta
juansaccoon 11:34 AM 07/15/2019: nice one! I enjoyed it thanks for sharingPlease, login with your credentials.Username:iwonderhowitfeelstobeatimetravelerNow, please insert the password.Password:heyamyspaceboardisbrokencanyouhelpmefindit?You have successfully logged into the system.

Parad0x13 on 1:47 AM 09/05/2019: U: iwonderhowitfeelstobeatimetravelerP: heyamyspaceboardisbrokencanyouhelpmefinditsize() compare of username input at 0x46EEFA requires a 0x22 (34) byte stringShortly after successful 0x22 byte username input we find a string compare located at 0x1C1908This string happens to be "iwonderhowitfeelstobeatimetraveler", this must be the usernameWe then find a password input compare of "heyamyspaceboardisbrokencanyouhelpmefindit?"We can verify that this is the correct username and passwordAdditionally we could have just checked strings to find them in plaintext and fuzzed the binary for a solution


0x4186 on 9:56 PM 09/21/2019: Please, login with your credentials.Username:iwonderhowitfeelstobeatimetravelerNow, please insert the password.Password:heyamyspaceboardisbrokencanyouhelpmefindit?You have successfully logged into the system.


Btoni on 7:24 PM 12/16/2019: Microsoft Windows [verziszm: 6.1.7601]Copyright (c) 2009 Microsoft Corporation. Minden jog fenntartva.c:\3EasyPeasy.exePlease, login with your credentials.Username:iwonderhowitfeelstobeatimetravelerNow, please insert the password.Password:heyamyspaceboardisbrokencanyouhelpmefindit?You have successfully logged into the system.


loyd93 on 5:12 PM 02/09/2020: Please, login with your credentials.U:iwonderhowitfeelstobeatimetravelerNow, please insert the password.P:heyamyspaceboardisbrokencanyouhelpmefindit?You have successfully logged into the system.it was really easy


rowdyninja on 3:42 PM 06/05/2020: Even for a beginner like me, the strings gave away the answer, so I tried to something different and patched the file such that no matter what user name or password we type, we'll be logged in.(Does doing it count?)


CouLi0 on 2:28 PM 06/14/2020: Please, login with your credentials.Username:iwonderhowitfeelstobeatimetravelerNow, please insert the password.Password:heyamyspaceboardisbrokencanyouhelpmefindit?You have successfully logged into the system.


Aligoliam on 8:10 AM 06/06/2022: que es el cialis - Cialis levitra professional Cialis Weakly acidic antibiotics dissociate to a greater degree in the alkaline environment of the chronically infected prostatic fluid pH Porgnr - 36 hour cialis online Ikxhxo


suicidenahimtrollincap on 10:05 AM 06/08/2023: Please, login with your credentials.Username:iwonderhowitfeelstobeatimetravelerNow, please insert the password.Password:heyamyspaceboardisbrokencanyouhelpmefindit?You have successfully logged into the system.


goddid on 9:30 PM 02/04/2024: Please, login with your credentials.Username:iwonderhowitfeelstobeatimetravelerNow, please insert the password.Password:heyamyspaceboardisbrokencanyouhelpmefinGTFO you lame ass hacker.


Welcome back! Today we are tackling another Windows binary from crackmes.one. Unlike the previous binaries, this was compiled with C/C++ so we will not be able to use dnSpy or a similar tool to reverse this binary. There aren't any surprises in this binary just some tricky disassembly that I'll do my best to walk you through! If you want you can feel free to watch the YouTube video below or continue reading!


I normally use my Windows VM to analyze Windows binaries but my Windows VM was acting a little funky so I used my Kali VM. Luckily we did not need to do any debugging to solve this challenge. If you're using a Kali VM you'll need to install wine to run the binary on Kali. If you're using my VM, you'll find this binary in the /home/kali/reverse_engineering/crackmes/find_the_pass directory. If not you can download the binary here. It comes in a password protected zip file. The password is "crackmes.one" without the quotes. With all of that out of the way let's get reversing!


Just like in the previous challenges we start by running file. However, you'll notice that on a Windows binary file doesn't provide much information. Also we can't look at the symbols either with the nm command. Again fortunately, this is a simple challenge so we do not need to worry too much about.


We see what looks like a possible password (highlighted in red). There's no way it's this easy right? Well you know me, I am a try everything kind of guy so let's try to supply this password to the binary! We also see, we are to supply the password as an argument to the binary.


And just as we expected. Well this string could have some significance later (spoiler it does), so let's just jot this down in our notes for now. Now, before we move on, not that this binary has reference to mingw32. If you didn't know, mingw is a cross compiler. This little detail will be important later on.


We see something that's a little strange at address 0x401556. We see a call to ____main. We don't have to worry about this. From what I can tell this is a mingw artifact that does some extra setup. After that we see it compares the argument count with two, ensuring we passed in a parameter. Assuming we pass in a parameter we can move to address 0x401565. We see the code grabs argv[1] which would be the password. Since this is a 32-bit binary, arguments are passed on the stack. At address 0x40156d, we see our user input being placed at the top of the stack followed by a call to strlen. The result of this is stored in a variable local_14. Recall that return values are placed in the EAX register. So, we can rename local_14 to password_len. We then see the password_len is placed at the top of the stack which sets up the malloc function call. The return is then placed in a variable local_10. Let's rename this to buffer. Ghidra is doing something that makes it a little difficult to figure out what's going on. You see at address 0x401591 that EAX gets stored to ESP+local_2c. This is a little bit misleading. What's actually happening is the value stored in the EAX register which happens to be argv[1] is being placed on the stack, specifically, ESP+4. We can tell prevent Ghidra from doing this by making the following changes: Edit -> Tool options -> Listing Fields -> Operands Fields and then uncheck the box Markup Stack Variable References.


With this notation we can see clearly that our user supplied password and the newly created buffer are placed on the stack ESP+4 and ESP respectively. This makes it easier to determine that the arguments for the strcpy function. So far, our decompiled output will look something like this:


Similar to the previous function, we see the arguments to _hash are buffer and 0x1c. The first argument is buffer and the second is 0x1c. This will be important in just a moment! Let's take a deeper dive into the hash function.


Right off the bat we see param_2 which is 0x1c gets passed to the srand function. This means the author is using a static seed (giggity). This is good for us because it means every time rand() is called, the same number will be generated every time we run the program. Next we see param_1 which holds our user_input is passed to the strlen function. Let's go ahead and rename these variables so it's a little easier to follow.


We see that we are grabbing the creating another buffer with the malloc function. Notice the len_user_input goes through an SHL instruction before being passed to the malloc function. This will multiply len_user_input by 2 raised to the 2 power or simply 4. Finally, we see a variable being set to 0 followed by an unconditional jump which we know by experience is normally how a loop begins so I renamed this variable to i. Let's go ahead and take a look at what's going on in this loop.


We see the loop continues as long as i is less than len_user_input. The first few instructions in LAB_0040149A look a little confusing but let's go through it step by step. First, i is placed in the EAX register. The next instruction, we see EAX*4 get stored in the EDX register. We can ignore the + 0x0 since that does not affect anything. So EDX holds EAX*4 or we can i*4. Next, buffer gets placed in the EAX register. Lastly, before the rand() function call, we see EDX+EAX*1 get stored in EBX. We can substitute the registers for our variables to make it easier to understand. So, EBX holds (i*4 + buffer*1). We can actually ignore the *1 since that will not affect anything in this case. If this notation looks weird you're not alone. This was a little confusing to me as well. What's happening here is buffer is being indexed and stored in the EBX register. By the name, we expected buffer to hold characters but it appears that buffer will hold integer values. Integers are 4 bytes which explains why i gets multiplied by 4. This will ensure that we get to the next element in the array. We can simplify the indexing by simply translating the craziness to buffer[i]. Alright so buffer[i] is placed in the EBX register. Let's keep that in mind. Next, we see rand() is called. Recall, since the seed was static, this will not be a truly random number. This means if we were to create a function, initialize it with 0x1c and call random as many times as this hash function does we will get the exact same "random" numbers. After rand() is called, we can see a lot of craziness that I cannot decompile myself. The instructions from 0x4014AF to 0x4014CF take the result of rand() and mod it by 10. That is EDX will hold rand() % 10. Then we see EDX gets stored in EBX and lastly we see i is incremented. We can translate this loop to the following C code:


Luckily, we don't have any crazy modulus to worry about in this loop but we it is still a little confusing. Just like the previous loop we will go through this step-by-step. First, we see user_input[j] gets stored in the EAX register. This in turn gets stored in a local variable local_20. We then see our key get indexed by j as well. Next we see key[j] is added to local_20 which holds user_input[j]. So local_20 holds user_input[j] + key[j]. This is beginning to look similar to a shift cipher. The result of this is stored in the ECX register at address 0x401510. We then see another new stack variable local_52. This new variable gets indexed by j and then user_input[j] + key[j] is stored. So, let's rename this to modified_user_input. We then see j is incremented by 1. The above loop can be roughly translated to the following C code:

3a8082e126
Reply all
Reply to author
Forward
0 new messages