With another great CTF for the Cypriot Cyber Security Challenge finished, I had a fun time solving interesting and hard challenges in various fields such as Web,Pwn,Crypto,RE,”Forensics” as well as privilage escalation, AI and blockchains.

Today I will be discussing on my approach to solve the challenges in the Reverse Engineering and Forensics categories.


Overall, this year the forensics challenges were underwhelming in comparison to last year. Considering there were 3 image files and 1 pcap, which most were solvable in 5 minutes. However, instead of showing the one line solution I will explain in more depth the proper forensics approach onto tackling challenges of this nature.

For the following challenges, we will be using the tools autopsy and wireshark.

The Janitor

Mr. Shaibel was devastated after he learned that Beth’s was adopted. He acted irrationally and shredded the adoptions papers can you help the headmaster retrieve them?

We are given the file “The Janitor.E01” and we are told to search some deleted files. There many tools out there in dead-box forensics, but using autopsy is easier as it is lighter, free and it has built in tools for carving deleted files from disks.

To begin, run autopsy, create a new case and a new data source as “Disk Image or VM File”. Click on the “The Janitor.E01” file and click next.

From the Ingest modules, you can unselect the ones I have as shown here as they are not really needed for the investigation.

Make sure you include Unallocated Space from the drop down menu from above.

Click next and wait for autopsy to do its magic. After its done we can find 3 files in the recycle bin.

Clicking into the folder, we can see 2 pictures and one ini file. One picture is corrupted while the second one is our flag:

The Janitor 2

What is going on with Shaibel? This time he burned the documents leaving no traces. I think he will be fired after this incident.

We are given another image and we are given the hint of “burned the documents” indicating that the file is somewhere in unallocated space or carved.

By adding the new data source using the “Add new data source” button on the top left and using the same ingest settings, we can now begin our investigation.

After running our ingestion modules we can see that there is one carved file.

Clicking onto the folder we see an xls file with our flag in plain sight, gaining some extra points as well as disappointment for this year’s forensic challenges.

One of a kind

Beth received a custom made chessboard from a famous woodworker. The carvings on the pieces are magnificent.

Again we are given an image file, so add it as a data source to go exploring. Judging from “carvings on the pieces are magnificent” I expect there is a file inside some of sort of chessboard.

At a first glance, we can see an xls file being carved, however for better or worse, this one challenge was not solved through 1 command or click.

The xls file carved was a red herring as:

However, we have some unallocated space too. Dumping it and looking at its strings, we can see an xls file, the one carved as shown before. However I saw some suspicious strings inside.

The above strings indicate that the flag could be in base64 format, so I looked for the “=” character within the strings and we found a base64 encoded string.


which decodes to:

CCSC{Chess can also be, beautiful.}

However, one could also export the xlsx file, enable macros and see the vba code attached as the flag is located there.


I can’t seem to open the file. Did Jolene corrupted it?

There are 2 ways to approach this, one being to fix the file using a partition recovery tool or a hex editor.

I chose the latter, since time is everything during a CTF. Looking through the strings one can easily detect the base64 flag and decrypt it.

Q0NTQ3tJ4oCZbSBnb25uYSBiZSBhIHJhZGljYWwufQ== -> 
CCSC{I’m gonna be a radical.}


Do you know that Shatranj is a proto-version of chess? But anyway, it’s time to move on to modern stuff.

We are given 2 files, one pcap and one .proto file. .Proto files contain Protocol Buffers, which is a method of serializing structured data. It is useful in developing programs to communicate with each other over a network or for storing data. We can utilise them to decode communications between two programs when monitoring packets using wireshark.

In this case, our .proto file contains the following:

syntax = "proto3";

enum EncType {
AES_ECB = 0;
AES_CBC = 1;
AES_CTR = 2;

message EncryptRequest {
bytes key = 1;
EncType mode = 2;

message FlagResponse {
bytes iv = 1;
bytes flag = 2;

service Encrypt {
rpc encrypt(EncryptRequest) returns (FlagResponse);

In essence, we can see that during a client requests an encrypted flag to be sent by specifying the encryption key and AES mode, with the response of the server return the encrypted flag as well as the IV used.

In order to use the .proto file, we need to tell wireshark how to handle the packets given. We can do that by clicking:

Edit -> Preferences -> Protocols -> ProtoBuf -> Protobuf search paths -> Edit

Finally adding the folder where your .proto file is located. After doing so wireshark can now show the communication between the two clients.

We can see lots of red herring traffic, primarily accessing Wikipedia. However, since we know that the GRPC protocol is used for the communication, then the server port is probably 50051 and HTTP2 is used. But since wireshark doesn’t know that, we need to specify it using Analyse -> Decode as…

Setting the values as shown we can now see the application traffic:

Following the HTTP2 stream, we can see the IV,key, encrypted flag and AES leading us to decrypting the flag finding:


Reverse Engineering

Make your move

Mr. Shaibel has left Beth a hidden message within this puzzle. Assemble all the pieces to decode the message.

Dam, what a really interesting challenge. We are given an uhhhh, xslx code piece I guess? I have no idea what the name is. Essentially it’s a programming language made by one of the mentors which can be found here

Ok lets slowly decrypt this message.

We begin with having a long line of text containing:


And since the documentation states:

Z,Var,Var2 <=> var = Var2

We can translate it to the following python code:

str[12] = str[14]
str[21] = str[23];
str[23] = str[27];
str[27] = t;

Originally, I started making a full decompiler, however due to having 1 hour left in the CTF I abandoned it mid way and started guessing by hand. However I utilized the part that worked and reversed the lines which passsed around the variables. That was the easy part.

The hard part however was to understand the 10 functions which were followed. So I took it step by step. To be honest, I had and still have no idea how functions are supposed to work. Maybe its due to lack of sleep or just pure lack of time so I tried to stitch things together by looking for clues.

The first function had some witchcraft which I did not understand, however after the tenth time I looked at the documentation I noticed a similar function in the example

Function given on the left vs Documentation provided on the right

These 6 lines have the purpose of xoring one list with another. So far so good. We now have this as the decryption process so far:

For x in range(0,len(str)):
str[x] = str[x] ^ key[x]
[Insert here the string swapping]

Now onto the next 2 functions:

I have absolutely no idea what’s happening rather than it goes through the list, it does something with b2 which is 2 and it does it 11 times.

I assumed it either shifts everything by 1 or 2 or adds 1 or 2 for every element. I was close.

The same process happens for the second function but doing it with b1 which contains 1 instead of 2.

So instead of trying to figure it out with the 15 minutes left, I made a small brute force script to see if I could guess the last two functions. Which I would have succeeded, if I realized that I was not shifting the encrypted text but the key instead.

I attempted to add, deduct ,left shift on each single encrypted character until I desperately tried to do the same with right shift, but somehow messing up by right shifting the key instead of the encrypted text. However after the competition I fixed the issue resulting with the following script:

for y in range(0, 30):  print('offset: ' + str(y))  straa = []  for x in range(0,len(key)):    straa.append( chr(key[x] ^ (strr[x]  >> y)))    t = straa[7]    [Insert character swapping]

which printed:

offset: 0
æ©Õé5īèĦùs{.↨♦Á'(E ÓR_H4rd_AF}
offset: 1
offset: 2
offset: 3

Recognizing the CCSC characters, in combination with the normal looking text at offset 1 and 0 we can make up the string after some trial and error:


Fortified Walls

Borgov’s knights tenaciously siege Beth’s castle. The rooks move forward in a bid to fortify the walls. Pressure is overwhelming, yet she must endure. Borgov’s head, ostensibly impenetrable, can you find a way read through his next moves?

Another great challenge, this time we are supposed to reverse engineer a encrypted binary by finding a way to bypass the pyarmor library used.

Anyone who has worked with creating cheats or reverse engineering games will have heard of it and its various anti debugging techniques it contains including time checks and the sorts. Making debugging the decryption process itself a very tall task. But why do it ourselves when we can have python do it for us?

Any python executable runs in c through the _PyEval_EvalFrameDefault function in ceval. Now, pyarmor is no exception meaning that after decrypting the contents of the assembly it will pass the raw program through that function… meaning we can just dump the object before it runs, right?

Well yes, we certainly can. This can be done by pulling the python3.7 repository, and modifying ceval with the following changes:

After running the botgov.py, and having the object dump we can run strings only to be met with too much information. I run strings and dumped it onto a file in order to make things easier, as I could now look for the prompt to have a point of reference by searching for “borgov” which suprisngly enough was next to a string “MySup3rS3cr3tX0rKey” indicating that there was something being xored.

Putting aside my ECSC flashbacks, I also noticed the string “base64”, which made me look for the characters “==” and easily enough I also found the following string


which decodes to


XORing the key with the whatever string this is gives us:

18. Bg5 Bxc4 19. dxc4 Qe6 20. Qd3 Rfd8 21. b3 Nh5 22. Be3 Nxg3 23. fxg3 h5 24. Qe2 Kg7

And finally sending on its way to the service provided gave us back the flag of:


(I forgot to take the picture while it was live sorry)

Reverse Gambit Challenge

Malware Researcher,coder and Musician