Women Unite Over CTF - Solving Challenges
The winner of the Women Unite Over CTF, Jaime Lightfoot, quickly posted writeups about how she solved the challenges. These posts (networking challenges, reverse engineering, and Linux exploitation) are excellent for the same reasons I enjoyed the event in general: my main barrier to entry is not knowing what tools to use or what to look for.
I thought of including details of my own problem-solving approach in my last post, but I didn’t have the forethought to take any screenshots. Since I was working in a provided VM, I don’t even have any of the challenge files or tools on my own computer. However, I ended up solving exactly the same problems as two of Jaime’s posts, so here I will simply talk about how my solutions differed from hers.
(See Women Unite Over CTF - Networking Challenges for Jaime’s solutions, with screenshots.)
I opened up the networking challenges because technical difficulties delayed the start of the reverse engineering walkthroughs. I hovered over random icons in the Kali Linux VM, hoping that one of them was a tool for looking at network information. Luckily Wireshark was prominently placed!
I have literally never used Wireshark before, but it’s the tool everyone talks about so it seemed an obvious choice. I solved these pretty slowly, but now that I know a little bit about Wireshark I expect to be faster next time.
level 1: helpfulwine
As soon as I opened the file and selected a packet at random, the flag showed up in the bottom pane. My first flag! It took a bit of trial and error to figure out how to copy it—I eventually had to paste whatever I copied into a text editor in order to strip out all the extraneous content before pasting the flag into the form.
level 2: rhetoricalairplane
frame contains "flag" in all of these to narrow down which packet contained the flag text, but I just clicked around randomly until I found it.
level 3: numberlesslove
Again I just clicked around randomly looking for something called “flag”. Used the exact same strategy as Jaime here, which is heartening!
level 4: warmsong
This is where I slowed down a lot, because I didn’t know about the Export Objects function. I could see from the headers that it was a .docx so I assumed I had to extract the doc and open it…but I didn’t know how. I tried looking at a bunch of different packets, right clicking on things, copying and pasting the bytes into a file…eventually I realized this must be a common problem and started looking for an export function.
Once I successfully save the .doc, my next challenge was how to open a Word document in an unfamiliar OS. I searched for something like “how to open word doc linux command line” and learned
level 5: savoryhill
Now that I knew about Export Objects function this went quickly. Export object as PNG, do a quick search to figure out what kind of program on Linux can open PNGs. The first search result suggested that
xdg-open is a good way to open a file in its default program.
Reverse engineering challenges
(See Women Unite Over CTF – Reverse Engineering Challenges for Jaime’s solutions, with screenshots.)
The reverse engineering challenges had walkthroughs on the live stream, which is good because I definitely wouldn’t have gotten anywhere without them!
level 1: calculateerratic
I followed Nada’s walkthrough and used Binary Ninja, using the
View > Strings option Jaime mentions in the next problem. Nada talked about the
strings command but I never tried it.
level 2: dustyabandon
The walkthroughs were also available as PDFs shared in the event Slack, so I started working a little ahead of the livestream. I spent a bunch of time in Binary Ninja, clicking on different views and trying to remember everything I ever knew about assembly.
I found the password-constructing subfunction (
sub_40100 highlighted in Jaime’s writeup), and the PDF said something about using
R in Binary Ninja to switch to character representations, but I wasn’t able to make heads nor tails of this code and didn’t know what I was supposed to be switching. I waited for Nada’s livestream to catch up. It seemed obvious as soon as Nada pointed out the hex codes!
Definitely don’t recognize hex values in the ASCII range off the top of my head, but maybe that’s a skill to acquire?
level 3: etherealshop
By now I expected a program with a similar design to the first two and opened it up in Binary Ninja to verify the same pattern of password comparison. I kind of went down a rabbit hole trying to understand what assembly was doing and tuned into the livestream to get back on track.
This is where my solution differed from Jaime’s by a lot—the documentation suggested switching to dynamic analysis so I opened up the program in Ollydbg. (Sorry no screenshots for this part.) I used an address I had found in Binary Ninja to get to the right section of code, but mostly poked around trying to understand the interface until Nada started talking about setting a breakpoint.
Breakpoints I understand! The step-in/step-over commands are similar to every IDE debugger I’ve used, so it didn’t take long to step through until the flag showed up in a register.
level 4: expertquestion
By now the contest was well over, and the Escalate platform was actually quite responsive, so I decided to tackle one more difficult problem. This one didn’t have a walkthrough!
I started the same process I’d gone through with all the other RE problems. Like Jaime, I found that the password encryption now had three functions doing mysterious things to the encrypted password that looked very hairy to decipher in static analysis. Unlike Jaime, I did not have any insights over hard-coded bytes and encryption methods. Instead I opened up Ollydbg for some dynamic analysis.
This part was a bit of a slog. Unlike level 3, the password didn’t show up conveniently in the little window that seemed to hold the current instruction. When I stepped through the comparison of the user-entered text to the password, it instead went straight to the “You are not leet enough” message. I went back further and started stepping through the entire decryption function.
Throughout this I was trying to piece together more about how Ollydbg works. There’s a large pane in the top left that contains your program, and one on the top right that shows the contents of all the registers (as well as some other stuff that I never understood.) In the bottom right shows the stack—you can scroll down through it to see all the pointers in the call stack from other functions.
That left the pane in the lower left as being I assume the heap? While stepping through the decryption process I eventually saw stuff starting to change here. At first it appeared to be random gibberish, but it still looked like a clue.
The decryption has a bunch of loops, and I learned how to recognize what a loop looks like in assembly and skip to the next instruction if nothing relevant seems to happen inside. This was not the most efficient method, but I was worried if I skipped too far ahead I would miss the flag again!
After far too long of this, the flag unscrambled itself in the pane I decided was the heap. Victory!
Jaime’s walkthroughs were a great refresher and a beginner-friendly introduction to some new techniques. I look forward to reading more from her, and maybe—just maybe—I’ll remember to take some screenshots of my own next time.