Secplicity Blog

Cybersecurity Headlines & Trends Explained

My CTF Ventures: picoCTF, Reverse Engineering

 

Moving forward with the picoCTF challenge platform, after completing the General Skills room I opted for the Reverse Engineering room. This room actually stood out first, even before General Skills. I’ve dabbled in reverse engineering (RE) and it’s a fun but complex and challenging process. Fret not, I committed to it and, well, read further to see what I thought about it! Upon entering the Reverse Engineering room, it’s nearly pitch black and you can’t see much. The entrance is semi-illuminated and there’s a sign nearby that reads, “this is not for the faint of heart.” You’re able to walk through the darkness and you can see servers throughout the area. I eventually found my way to a room with a computer to start with the challenges after walking around a bit. One note is that I wrote each question down in order after completing the skills room, but not necessarily the order in which they were originally presented. That said, I didn’t number the questions as they jumped around. Some challenges were unlocked only after completing another challenge.   Reverse Engineering Challenge Room Title: vault-door-training (50 points) Description: Your mission is to enter Dr. Evil’s laboratory and retrieve the blueprints for his Doomsday Project. The laboratory is protected by a series of locked vault doors. Each door is controlled by a computer and requires a password to open. Unfortunately, our undercover agents have not been able to obtain the secret passwords for the vault doors, but one of our junior agents obtained the source code for each vault’s computer! You will need to read the source code for each level to figure out what the password is for that vault door. As a warm-up, we have created a replica vault in our training facility. The source code for the training vault is here: VaultDoorTraining.java Answered: Yes; picoCTF{w4rm1ng_Up_w1tH_jAv4_87f5aa43e4b} Answer: The Java file mentioned at the end of the description is downloadable, and it’s the source code. Upon opening it, the password was there in a Java method. It was fairly straightforward once looking in the file. I only used the hint after the fact to document for this blog. Hint: The password is revealed in the program’s source code   Title: vault-door-1 (100 points) Description: This vault uses some complicated arrays! I hope you can make sense of it, special agent. The source code for this vault is here: VaultDoor1.java Answered: Yes; picoCTF{d35cr4mbl3_tH3_cH4r4cT3r5_03b7a0} Answer: Following the same steps as before, I downloaded and reviewed the source code. Sure enough, there was another Java method that returned a scrambled version of a password’s sequence but ensured each character was checked against its corresponding index. The method also checked that the password was 32 characters long. I expand on this concept in the Pro Tip below. Simply putting the character checks in a numerical sequence was enough to extract the password. Hint: Look up the charAt() method online. Pro Tip: In most programming languages, strings are sequences of characters. Hence strings index each character, starting with zero (computers LOVE starting with zero), as do lists and other data types. For example, the string “CTF” has three characters (one, two, three; human-friendly counting) with two indexes (zero, one, two; computer-friendly counting).   Title: asm1 (200 points) Description: What does asm1(0x610) return? Submit the flag as a hexadecimal value (starting with ‘0x’). NOTE: Your submission for this question will NOT be in the normal flag format. Source located in the directory as /problems/asm1_1_95494d904d73b330976420bc1cd763ec Answered: Yes, sort of; 0x621 Answer: Wow, this was probably the hardest question so far, at least for this skill room. I am not terribly familiar with assembly and even after reading the hint and spending my “hacker points” to acquire the walkthrough, I was still left feeling lost. Alas, I did look up the answer but the write-up I read didn’t have the same hexadecimal value in the description. After getting the gist of assembly using the write-up as a guide, I actually figured out the answer by myself! Hint: assembly conditions (hyperlink) Pro Tip: Assembly is huge in reverse engineering. I aim to get more familiar with assembly over time.   Title: vault-door-3 (200 points) Description: This vault uses for-loops and byte arrays. The source code for this vault is here: VaultDoor3.java Answered: Yes; picoCTF{jU5t_a_s1mpl3_an4gr4m_4_u_7f35db} Answer: This question was more challenging than the previous two, but it was fun nonetheless! Yet again, we have a Java method verifying a password. I understood the first half of the method, the second half wasn’t as straightforward – this called for my thinking cap. After realizing the for-loop parameters, the method essentially checked part of the password starting from the left, then switched it up and started checking it from the right working backwards. Hint: Make a table that contains each value of the loop variables and corresponding buffer index that it writes to.   Title: asm2 Description: What does asm2(0xc,0x15) return? Submit the flag as a hexadecimal value (starting with ‘0x’). NOTE: Your submissions for this question will NOT be in the normal flag format. Source located in the directory at /problems/asm2_1_909e8254810b229a481cafb41b58a005 Answered: No; 0x105 Answer: Well now, that was quite the challenge! I tried following the same layout from the previous challenge, but this challenge had two parameters and that threw me off. The hint was no help and the previous walkthrough purchase wasn’t worth it last time, so I tried online searches. There were a few write-ups using different hexadecimal values, but I couldn’t follow along with what was being done. I did find this resource with the answer and I accepted the fact that I’m not a assembly programmer. Hint: assembly conditions (hyperlink)   Title: vault-door-4 (250 points) Description: This vault uses ASCII encoding for the password. The source code for this vault is here: VaultDoor4.java Answered: Yes; picoCTF{jU5t_4_bUnCh_0f_bYt3s_b9e92f76ac} Answer: I don’t think this was as challenging as the previous question and called for a refresher of the different encodings from the General Skills category. Once again this is a Java method that checks a password but encodes different portions of the password into different encodings. Some of the characters were checked in ASCII, another set of characters in hexadecimal, a different set against octal, and the last set was standard text. Hint: Use a search engine to find an “ASCII table”. Hint: You will also need to know the difference between octal, decimal, and hexadecimal numbers. Pro Tip: Being able to differentiate between different encodings is important, especially when it comes to capture-the-flag competitions.   Title: asm3 (300 points) Description: What does asm3(0xc264bd5c,0xb5a06caa,0xad761175) return? Submit the flag as a hexadecimal value (starting with ‘0x’). NOTE: Your submission for this question will NOT be in the normal flag format. Source located in the directory at /problems/asm3_1_b7abaa5cc92e3f7061f23957206b434 Answered: Yes, sort of; 0xa4e1 Answer: Still trying to wrap my head around the previous two assembly challenges, I am still feeling lost. I honestly immediately looked up some answers for a reference. I noticed that write-ups have the same challenge but with different hexadecimal values – it’s time to learn how to solve the answer versus simply looking for the answer. I saw this resource and buckled up. It’s time to write and compile some C code, and adjust the assembly instructs from the source file. All in all, it was a fun process that did require researching the errors that arose, but that was easier than trying to understand the assembly code! Hint: more(?) registers (hyperlink) Pro Tip: Learning the process to finding the solution is sometimes better than just finding the answer. Who knows how long I could scour the Internet and not find the exact write-up with the same hexadecimal values provided. However, since I learned how to arrive at the solution, I was able to adapt it and find the answer for my specifically given hexadecimal values.   Title: droids0 (300 points) Description: Where do droid logs go. Check out this file. You can also find the file in /problems/droids0_0_205f7b4a3b23490adffddfcfc45a2ca3. Answered: Yes; picoCTF{a.moose.once.bit.my.sister} Answer: Finally, some redemption! After the asm challenges, I feel a lot better having been able to get this answer completely on my own! I’ve done Android app reverse engineering but the app that you download was different than any I’ve looked at before. Sparing the details, I managed to get the app opened in Android Studio, checked out the logcat tab, ran the app and sure enough, the flag was in the “Info” logcat option. Hint: try using an emulator Hint: https://developer.andoird.com/studio   Title: reverse_cipher (300 points) Description: We have recovered a binary and a text file. Can you reverse the flag. It’s also found in /problems/reverse-cipher_3_57c1a6a27fa6528507f57b3f445287bb on the shell server Answered: No; picoCTF{r3v3rs369806a41} Answer: After reading the hint, I tried my hand with objdump (never used it before) but wasn’t sure how to go about it. I also tried Ghidra (there was a typo in the hint, no biggie though) but haven’t really used it, so I just clicked around and managed to figure out how to load the provided binary file into Ghidra. After poking around for a bit, I couldn’t figure it out, so I resorted to looking online. Even after reading this answer, I still don’t quite understand how it was achieved but it’s a matter of practice and experience I am sure. Hint: objdump and Gihdra are some tools that could assist with this   Title: vault-door-5 (300 points) Description: In the last challenge, you mastered octal (base 8), decimal (base 10), and hexadecimal (base 16) numbers, but this vault door uses a different change of case as well as URL encoding! The source code for this vault is here: VaultDoor5.java Answered: Yes; picoCTF{c0nv3rt1ng_fr0m_ba5e_64_0f309d40} Answer: Feeling determined to make up for the assembly challenges, I was able to get the provided source code and break down the requirements. There was a Java method that had base 64-encoded strings, which in turn were URL encoded as well. After decoding the base 64 strings to a URL encoding, I decoded that and got the answer. Hint: You may find an encoder/decoder tool helpful, such as https://encoding.tools/ Hint: Read the Wikipedia articles on URL encoding and base 64 encoding to understand how they work and what the results look like.   Title: droids1 (350 points) Description: Find the pass, get the flag. Check out this file. You can also find the file in /problems/droids1_0_b7f94e21c7e45e6604972f9bc3f50e24. Answered: Yes, sort of; picoCTF{pining.for.the.fjords} Answer: This wasn’t as straightforward as the other challenge and required some outside-the-box thinking. Despite the hints, I actually used JADX to reverse the code and manually reviewed it, followed the code logic and was headed in the right direction, but I was just looking in the wrong area. After looking up a reference on how to solve it (I didn’t get the answer directly), this post provided a different area to look within the app structure. In doing so, I found the String that was being requested, entered it into the app, and got the flag. Essentially there was an integer-valued strings file (where I looked at first) but there is also a human-readable strings file (in another section of the app structure that I was reminded of from the reference). The latter provides the “password” to use within the app to reveal the flag. Hint: Try using an emulator Hint: https://ibotpeaches.github.io/Apktool/ Hint: https://developer.android.com/studio   Title: vault-door-6 Description: This vault uses an XOR encryption scheme. The source code for this vault is here: VaultDoor6.java Answered: Yes; picoCTF{n0t_mUcH_h4rD3r_tH4n_x0r_57c2892} Answer: After downloading and reading the source code, I realized this challenge was more difficult than the other vault doors. Even having read the hint a few times and working out some thoughts, I hit a wall. Then I read the hint one more time and realized the formula provided and the formula used within the Java method. Then the light bulb turned on and I was able to reverse the equation, this yields a list of ASCII numbers. After converting to text, I got the flag. Hint: If X ^ Y = Z, then Z ^ Y = X. Write a program that decrypts the flag based on this fact.   Title: B1ll_Gat35 (400 points) Description: Can you reverse this Windows Binary? Answered: No; PICOCTF{These are the access codes to the vault: 1063340} Answer: At this point, I realize I need to work on my reverse engineering. I know a bit already, but it seems like I’ve only scratched the surface. I used this resource to complete this challenge. Hint: Microsoft provides windows virtual machines https://developer.microsoft.com/en-us/windows-downloads/virtual-machines Hint: Ollydbg may be helpful Hint: Flag format: PICOCTF{XXXX}   Title: Need For Speed (400 points) Description: The name of the game is speed. Are you quick enough to solve this problem and keep it above 50 mph?  need-for-speed Answered: Yes, sort of; PICOCTF{Good job keeping bus #236cb1c9 speeding along!} Answer: Wow, this challenge was great – it was really difficult to follow but introduced me to radare2. I’ve heard of it but never used it personally. From the get-go I was lost here, so I used this reference guide but couldn’t follow along. After trying the answer provided, no go – the same was true for any online answer. I was left with no other choice other than to keep trying, giving up was not an option. While going back through the guide, I started following along with the process and matching numbers. After quite a few trial-and-errors using different guides as well, I finally figured it out. That said, I believe each answer may be unique to each participant. Hint: What is the final key? Pro Tip: There are many open source reverse engineering tools available online. After going this far through this challenge room, I realize the need to expand out and just try different tools. Radare2 was pretty cool but seemed overwhelming at first, but then again so did Ghidra. However, I personally believe one can accomplish anything with enough time, practice, and patience.   Title: Time’s Up (400 points) Description: Time waits for no one. Can you solve this before time runs out? times-up, located in the directory at /problems/time-s-up_3_37ba6326d772bf884eab8f28e480e580. Answered: Yes, sort of; picoCTF{Gotta go fast. Gotta go FAST. #1dcd7f16} Answer: I wasn’t really sure how to proceed with this either, but I at least ran the program (giving it executable permissions; chmod +x times-up) to see what it’s all about. The hint was no use, but I did read though this reference guide on how to go about solving this challenge. Again, each answer appears to be different, so I didn’t necessarily get the answer online, rather how to solve it. I did learn about some neat Linux utilities along the way though! Hint: Can you interact with the program using a script?   Title: asm4 (400 points) Description: What will asm4(“picoCTF_376ee”) return? Submit the flag as a hexadecimal value (starting with ‘0x’). NOTE: Your submission for this question will NOT be in the normal flag format. Source located in the directory at /problems/asm4_2_0932017a5f5efe2bc813afd0fe0603aa. Answered: No; 0x24d Answer: It’s clear by now that I need to start looking into programming in assembly and C. I had a really tough time even trying to repeat solution steps from other write-ups but managed to FINALLY find a resource with the same flag I had mentioned in the description. Unfortunately, the output was the incorrect answer, but the author mentioned deviating a bit from that program’s output and ended up getting the right input of “0x24d”. Hint: Treat the Array argument as a pointer   Title: droids2 (400 points) Description: Find the pass, get the flag. Check out this file. You can also find the file in /problems/droids2_0_bf474794b5a228db3498ba3198db54d7 Answered: Yes; picoCTF{what.is.your.favourite.colour} Answer: After using JADX again (I highly recommend this for ease of use in following Java code), I followed the app’s coding logic, ran through its list slicing and mathematical jumps and hoops, and managed to extract the input string the app desired. Without giving the answer to the string the app is looking for (despite already having the answer above), there is a list of strings. The simple math exercises revealed the order of how the indices should be entered into the mobile app. Hint: Try using an emulator Hint: https://ibotpeaches.github.io/Apktool/ Hint: https://developer.android.com/studio   Title: vault-door-7 (400 points) Description: This vault uses bit shifts to convert a password string into an array of integers. Hurry, agent, we are running out of time to stop Dr. Evil’s nefarious plans! The source code for this vault is here: VaultDoor7.java Answered: Yes; picoCTF{A_b1t_0f_b1t_sh1fTiNg_df5f8ed440} Answer: I didn’t mention until now, but the source code for this vault-door series had some nice commentary, and also subtle hints. This challenge was no different, though I must confess I didn’t quite understand what was being said in this particular scenario. However, simply trying to reverse the strings in the source code got me the answer and helped me somewhat understand what the challenge was about. In essence, characters can be represented by a byte’s worth of data (eight bits). Integer numbers can store 32 bits of data, or four bytes. Therefore, in an int’s (short for integer, a programming data type) worth of data, you can store up to four individual characters. For example, the decimal number “1681142832” converts to the binary number “1100100001101000011010000110000” and the hexadecimal value of “64343430”. Considering the hints, I translated the hexadecimal value to their text value and sure enough got four characters at a time. Oddly, directly converting from binary didn’t reveal the same results, so that kind of stuck out to me. Hint: Use a decimal/hexadecimal convertor such as this one: https://www.mathisfun.com/binary-decimal-hexadecimal-converter.html Hint: You will also need to consult an ASCII table such as this one: https://www.asciitable.com   Title: Time’s Up, Again! (450 points) Description: Previously you solved things fast. Now you’ve got to go faster. Much faster. Can you solve *this one* before time runs out? times-up-again, located in the directory at /problems/time-s-up—again-_3_f7219b295d1ce306013aea2d0ab82c27 Answered: Yes, sort of; picoCTF{Hasten. Hurry. Ferrociously Speedy. #1dc758f2} Answer: This was another challenge requiring a unique answer. At this point, I realize that I still have a lot to work out and it’s amazing to see how intelligent others out there are! I used this resource as a guide to obtain my unique answer. Hint: Sometimes, scripts are just too slow. You’ve got to have much more control. Pro Tip: How I see it, many folks in the real world use others’ programs and only slightly change them for their suited needs. I still aim to give credit to others, unless I come up with the solution on my own. That said, use others’ solution code but try to also understand the code as well.   Title: droids3 (450 points) Description: Find the pass, get the flag. Check out this file. You can also find the file in /problems/droids3_0_b475775d8018b2a030a38c40e3b0e25c Answered: No; picoCTF{tis.but.a.scratch} Answer: I knew exactly what needed to be done, but I was having issues rebuilding the app and couldn’t figure it out. After reversing the code like usual, I followed the logic, which was simpler, and figured out what needed to be done. There was a method call to the incorrect method; changing which method was called should’ve revealed the correct flag. I know you can use apktool to decode an apk as well as building it again. However, even if I decompiled the app and didn’t make changes, I wasn’t able to rebuild the app. I used this resource to get the flag. Hint: Try using an emulator Hint: https://ibotpeaches.github.io/Apktool/ Hint: https://developer.android.com/studio   Title: vault-door-8 (450 points) Description: Apparently Dr. Evil’s minions knew that our agency was making copies of their source code, because they intentionally sabotaged this source code in order to make it harder for our agents to analyze and crack into! The result is a quite a mess, but I trust that my best special agent will find a way to solve it. The source code for this vault is here: VaultDoor8.java Answered: Yes, sort of; picoCTF{s0m3_m0r3_b1t_sh1fTiNg_ad0f0c833} Answer: Okay, so this challenge’s source code was definitely more difficult to follow than any other by far. For one, it was not organized with spacing and such. For two, even after cleaning it up, the Java method’s code logic that checks the password was new to me. As for how to clean up the source code, there are online beautifiers, or you can manually do it. I researched a few things and semi got the gist, but since I don’t have experience, I wasn’t sure my head was grasping this. I looked online for how to solve it, but not necessarily looking for the answer – remember, I am trying to figure out how to solve the challenges, not just necessarily answering them. I used this resource that describes what the user did to solve it. Yes, it provides the answer, but I didn’t check against it until afterwards. Hint: Clean up the source code so that you can read it and understand what is going on. Hint: Draw a diagram to illustrate which bits are being switched in the scramble() method, then figure out a sequence of bit switches to undo it. You should be able to reuse the switchBits() method as is. Pro Tip: During this whole challenge room, I kept thinking just how important it is to know the basics of programming, and also how to programmatically answer some of these questions. That said, the more you do CTFs and realize the repeat challenge formats, creating a custom program doesn’t sound like a bad idea. For example, create a program that takes in an input, checks the type of input it is (is the input a hexadecimal value, binary value) and then converts to whatever is necessary (say from ASCII to text). Obviously, there are online resources, but this is a great way to build your skills too!   Title: Forky (500 points) Description: In this program, identify the last integer value that is passed as parameter to the function doNothing(). The binary is also found in /problems/forky_2_f5458a96a325b1440ca36dffe4ceaff7 on the shell server. Answered: Yes, sort of; picoCTF{-721750240} Answer: I used various resources to find different answers or guides to the different questions. Not all resources had all challenges, so I jumped around. At first, I found one that involved assembly – huge deterrent. I then found this guide where the author creates a C program to interpret the results - way easier to follow in my opinion. In trying this approach, I was able to get the answer myself! Case in point, I’d rather write C than try to understand assembly as of now. Hint: What happens when you fork? The flag is picoCTF{IntegerYouFound}. For example, if you found that the last integer passed was 1234, the flag would be picoCTF{1234}   Title: Time’s Up, For the Last Time! (500 points) Description: You’ve solved things fast. You’ve solved things faster! Now do the impossible. Times-up-one-last-time, located in the directory at /problems/time-s-up—for-the-last-time-_6_6d438fa0e8ed90fd72f5bc4b9aa6678b Answered: Yes, sort of; picoCTF{And now you can hack time! #151c8af2} Answer: Another unique input is required, and I did my best to understand this code’s logic and how it provided the answer. Hint: Sometimes, if some approach seems impossible, it means a different perspective might be needed. Is there anything interesting about how the program behaves?   Title: droids4 (500 points) Description: reverse the pass, patch the file, get the flag. Check out this file. You can also find the file in /problems/droids4_0_99ba4f323d3d194b5092bf43d97e9ce9 Answered: Yes; picoCTF{not.particularly.silly} Answer: Following suite of droids3, I followed the code logic and figured out what I needed to do. This was two part. Part one involved making a simple Java program to reveal the password the input field was expecting. This was the easy part because I only needed to modify the Java source code slightly. Part two was the tricky part. I used droids1 as a reference to modify the Smali code but was having issues building the app afterwards like in the previous droids challenge. In my determination, I actually figured out a work-around that let me build the app by not decoding the resources (-r flag). I then replaced the original APK with my modified APK, installed and ran it, entered the expected input, and this triggered a Java Native method call revealing the flag! Pro Tip: When in doubt, try things out! I was stuck in droids3 and felt I tried quite a few things to rebuild the APK. After trying various online searches and ensuring software was up to date, no progress. However, facing this issue again, I couldn’t help but keep trying and alas, I tried a few apktool flags to work around the issue! Small accomplishments like this are great and yes, I did pat myself on the back!   Conclusion and Thoughts In review of this challenge room, it’s clear that I need to work on C and assembly programming languages. It was fun learning them in this context and I hope to continue the learning journey. C was way easier between the two, assembly was really difficult. I gave it my best shot and ended up with the results I received. I was definitely humbled here and that’s a good thing, I know I don’t know everything, but I can strive to! The bonus with this challenge room is that I did well on the vault-door and droids series. I remember when I first learned to program in school, we used Java and I hated it then. Now I realize I’ve taken it for granted and preferred it especially to assembly, but even C a bit due to my familiarity with Java. What was cool about the duo is that Android programming is done so using either Kotlin or Java, to which the latter is the language I use. Lastly, as you and/or I partake in more CTFs, we’ll notice a trend in the challenges. The concept will be the same, being the need to understand different encodings or how to analyze source code, but the answers will obviously be different. This is one main reason I iterated my desire to learn the process versus going straight for an answer a few times throughout this post. I hope you enjoyed reading this post as much as I did writing it!

Filed under: Research