In this challenge, the goal is to reverse a NetBSD kernel module and get the flag. We are provided with a zip file which contains the kernel module, NetBSD disc img, and couple of scripts to setup qemu and gdb for the challenge. It would have been easier to solve the challenge dynamically by setting up qemu and gdb but due to no experience with NetBSD reversing i proceeded to analyze the kernel module statically with IDA.

Taking a look at the strings doesn’t reveal much, but there are interesting functions in the kernel module. The two functions which looked interesting were get_flag_ready and chall1_read.

So I decided to start the analyses from chall1_read. The disassembly of chall1_read is pretty interesting.

So the input here is getting compared with “give_this_to_get_flag” and then after that get_flag_ready is being called. Now taking a look inside get_flag_ready function reveals that 40 bytes are placed on stack (local array) at the starting of the function. There are 2 functions which are called after this namely, md5hash and sha1hash. I think the crucial part of this challenge was determining what were md5hash and sha1hash functions doing.

Code Snippet from md5hash:

After some analysis, it was clear that this function is calculating md5 hash of a string but now the question was which string. As we can see above strlen there is an operand “s”, that is an operand name generated by IDA and it references the input string which was being compared to give_this_to_get_flag. This can be confirmed by checking the chall1_read function. So now its clear that md5hash function calculates the md5 hash of “give_this_to_get_flag” which is 29c5d56f77a0d0369c55101c53005050. 

Code Snippet from sha1hash:

Now if we look carefully inside sha1hash function, we can see that it accesses the previously saved md5 hash and computes the sha1 hash of the md5 string. The sha1hash is 001b6a634bee73d9fe2d88bb4435fb1ee3ad7918.

After computing both md5 and sha1 (of md5) we are back in get_flag_ready_function. We can see from above image that the binary xor’s the earlier copied 40 bytes with the sha1 string we got from the sha1hash function. Here is a simple script to get the flag:

This gives us the flag: flag{netB5D_i5_4ws0m3_y0u_sh0uld_7ry_i7}