InCTFj Challenge Writeups
- iamomthegreat
- Dec 31, 2021
- 5 min read
Updated: Jan 1, 2022
This week I took part in InCTFj, and here are some writeups from the challenges I solved.
Use the links below to jump to a specific challenge:
Hashed
Challenge info
Description: Crackstation can be used to decrypt the hash you get.
Difficulty: Easy
Points: 150
Attachments: hashed
Solution
We start by analyzing the file using file command.
We can run this binary to see what it does.
If you are wondering, I simply tried to input an md5 hash since it's the most common one, (echo -n hacker | md5sum) and it accepted the length, so pretty sure it wants an md5 hash. The program takes a hash of length 32 and tells if it is correct or wrong.
We can use ltrace to trace the library calls this program makes.
We see a call to strcmp which compares our input hash with "04a5a2af0eb53473a4a2efb3dafa02df". This is probably the hash we are looking for, so let's go ahead and crack it using https://crackstation.net/.

So our flag is inctfj{mockingbird78209}
Swap
Challenge info
Description: we found a java compiled code can you get the source code and reverse it to get the flag
Difficulty: Easy
Points: 150
Attachments: solve.class
Solution
We start by analyzing the file using file command.
On googling "java decompiler" we get https://java-decompiler.github.io/. Download JD-GUI and open the solve.class file (I used the jar file on linux and ran it simply by ./jd-gui-1.6.6.jar).
We get the following java code:

The main function asks us to enter the flag, and strips off the first 7 bytes ("inctfj{") and the last byte ("}"). The remaining part of the flag is used as argument to check_1 function, and if it returns true then flag is correct else wrong.
check_1 checks if flag length mod 4 is 0, that is the flag length should be a multiple of 4 else the length is wrong. Then it calls check_2.
check_2 is the beef of this program. It takes our input, does some shuffling and bitwise operations on it, and then compares it to another array, which I guessed was the encrypted flag. We need to reverse this function and find the input which gives the encrypted flag as the output. We can also see that the length of the encrypted flag is 20, so our input needs to be 20 characters long.
First thing I did was port this over to python, as having these functions in python help to analyze them better.
Here I have only changed a few variable names, rest everything is same. Usually at this stage I try to analyze the function and find some patterns in it, so let's start.
I called the enc function twice with arguments b'A'*20 and b'B'+'A'*19.
Notice how changing one letter in the arguments changes only one number in the array.
Next, I did the same with the argument as b'AB' + b'A'*18:
We can use this technique to get the whole flag. How?
enc(b'BAAAAAAAAAAAAAAAAAAA') gives output [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 24, 40, 40], so the first position affects the 18th position of the array. So we can try all printable characters as the first character of the flag and compare enc(arg)[17] == enc_flag[17]. If this is true, then we have found the correct character for that position and can now move to the next character in the flag.
Below is the script to solve this challenge:
Flag: inctfj{d1d_1_5w4p_t00_much:}
Baby ASM
Challenge info
Description: We found this baby.asm file, but we're having some trouble figuring it out what it returns. Can you help me to find what it returns when func(0x1,0x25) is called? Note: It is not intended to be compiled, learn assembly to reverse the challenge by manually reading the code :)
Difficulty: Easy
Points: 150
Attachments: baby.asm
Solution
We are given the following `baby.asm` file:
We need to find the return value of func(0x1, 0x25), which is stored in the eax register when the function returns.
But before we start reversing the functions, we need to have a fair idea of how the stack will look like when the function is called with the correct arguments.
On 32 bit systems, the arguments of the functions are pushed in reverse order onto the stack, and then function is called. The following code calls func with the correct arguments:
So now we understand the layout of the stack, let's start reversing func:
I have added comments to describe in detail the assembly code.
Next the kek_boom function is called:
So we simply need to find the value of local_4 when the function returns. The local_4 variable is not modified at all in the kek_boom function, so looks like we will need to reverse the pepe_boom function:
This function only does some mathematical and bitwise operations on the local_4 variable, and increases arg1 by 0x64 on every call. In all, this is just a simple for loop with i = 0x1 at initialization , i <= 0xb158 being the check, and i being increased by 0x64 on every iteration.
With that, let's write this in python so we don't have to work out the value of local_4 by hand:
And that's how you blood this challenge ;). Flag: inctfj{931}
Crackme101
Challenge info
Description: I guess it's an easy crackme. can you crack me up? :))
Difficulty: Easy
Points: 150
Attachments: crackme101
Solution
We start by analyzing the file using the file command:
It's an executable binary file.
We can take a look at the strings in this binary:
We can try running this binary:
It prints a banner and asks for input, and says not enough if it is not the input that it wants. Judging by the strings, that binary will print the flag it the input is correct.
At this point we can open this up in ghidra or any other tool and analyze the functions and reverse them, but let's try to do this challenge through some other methods.
Looking at the strings, we see strcmp, so we can assume that this is the function being used to compare our input with the input it wants. We can try to use ltrace, but it did not print anything for me, and I have no idea as to why.
So below are the methods with which we can solve this:
GDB Using gdb, we can break at the call for strcmp, and can inspect the arguments being passed to the function, and get the required input that way.

Alternatively, we can break after the call to strcmp, and then set the return value to 0 in order to make it look like the check was successful and the strings are same. We can achieve this through the following command: set $eax=0.
LD_PRELOAD This is the technique that I liked the most. LD_PRELOAD is an environment variable which can be set to the path of any shared object file, and when we run any program, that shared object file will be loaded before any other .so file. Also, 2 functions in C cannot have the same name, but if 2 functions in different shared object files have the same name, then the function in the file which was loaded first will be called, and the other will be ignored. Using the above 2 mentioned points, we can hijack or hook the strcmp function in the following way: Create a file strcmp-hook.so with the following contents:
This function does nothing except return 0, and we could have also logged the arguments, but in this case we don't.
Compile the above using the command indicated in the comments, and then run the program after setting LD_PRELOAD. Give any input, but the strcmp check will always return 0, so the check will be successful and the binary will print the flag.
ANGR We can use the angr framework for this binary. If you already have a ready-made script to be used, it takes <10 seconds. I will not go over this method, but if you are interested, take a look at https://blog.notso.pro/2019-03-20-angr-introduction-part0/.
So, the required input is "InCTFj_is_l0v3_<3" and the flag is inctfj{w4sn't_th4t_an_3asy_chall????:)}.
Comments