Cyber Security Challenge 2020

Behind the Scenes of the CTF - 9-10 October

Dear players, 
as you may know we held a huge Cyber Security Challenge this year, and since we are glad we have this active community of security experts, passionate and eager to learn, we prepared for you this page where you can re-live the most interesting behind the scenes "fan facts" starting from bugs we fixed to curiosities to be shared. 


What about the numbers of this community? 

The biggest CTF we held so far reached these interesting numbers: 


  • +10.000 new registered to the platform and 2380 competing teams.
  • 9176 submitted flags, 1283 of which scoring ones
  • Participants origin, first 5 countries: Italy 29%, GB 9%, Brasil 8%, India 7%, Germany 5%
  • 400 teams formed through the Random Queue and 100 teams thanks the dedicated Telegram Channel "Find your team-mate

60% of you is student, 40% professional :) 


But lets move into business now...


Plot twist in the leaderboard: CODING500

At the very end of the challenge (- 1 hours to close) we received support requests from team “Armia Prezesa” claiming a possible malfunctioning of the CODING500 challenge: “Space-time honeymoon”. In particular, they were submitting the same result provided by two different implementations of the MST algorithm, but it was being rejected by the challenge server.

We started our troubleshooting analysis, but there was no sufficient time before the CTF end :( 

After the end of the competition, we started a deeper analysis. We analyzed the logs and verified that only one team completed the challenge correctly and submitted the right answer during the competition. The instant when this occurred was before the CTF end and would have been sufficient to insert the flag into the system and receive 500 points + 32 first blood points. The connection information on our logging systems confirmed that the only team who solved the challenge was "Armia Prezesa". Kudos!


What was the error?

Since the operations required for this challenge could be pretty intensive to compute at runtime we pre-calculated all the possible messages to send as audio and all the strings to verify your responses to Romeo and Juliet.

The issue was in the final response verification because our pre-calculated value was incorrect due to a wrong parameter in the challenge generator program. This wrong parameter was making the generator calculating distances on a subset of the cities instead of the full set, giving a wrong value.


What was the wrong behavior?

In response to a correct final answer to the challenge the server was checking against the wrong pre-calculated value, so it has always replied with an error message.


Why didn’t we detect this error during testing phases, and load test?

The same wrong parameter was used also in the test solver program, making the solver calculate the same wrong value the server knew. Furthermore, no negative feedbacks were received during the cross-checking between categories, so we did not notice the error.


Lesson learned

Despite our testing efforts, we were not able to spot that bug earlier. The position of the bug in the very last step of the challenge is the reason why only one team noticed the problem and it was too late to have a proper debugging and fix. Lesson learned? Two rounds of testing are not Edsger Wybe Dijkstra once said: "testing can prove the presence of bugs, but not their absence".



This edition of the Reply CTF welcomed a mysterious and fascinating character from the past in the miscellaneous category: Poeta Errante (please don’t call him “wandering poet”, it’s just like spaghetti). As we expected, he captured the attention of the folks for the whole competition. His moving story touched the heart of most of the players, who couldn’t help but showing their love for our hero.

However, Zer0 has been a little devilish in this 1320 adventure, and hid the solution of the MISC100 challenge in the finest details. This apparently gave severe headaches to many players who began to speak esoteric languages.

However, thanks to our experts, we managed to undertake some kind of communication.


In the end, many teams were able to help Poeta Errante in this tough situation. Regarding the last TCP packets trick, Zer0 declared

Thought you guys were ready for that… your parents loved it.


The next level (MISC200) was again tricky for some teams, who probably haven’t put enough focus on the time travel topic. A website extracted from an old dump is probably not alive anymore! Luckily, we do have some kind of “time machine” in these cases! Well, let’s call it a Wayback machine.


MISC300 signals from the past. Only 2 teams solved this level. This challenge required knowledge about signals transmission and encoding, plus basic skills in reverse engineering. Despite some teams did not recognize the SLIP protocol, which should have led to publicly known tools, we appreciated the effort put into analyzing the observed encoding and rewriting the decoder.


Alas! We received no questions regarding the two last levels, MISC400 and 500, probably due to the lack of time, or the effort required for the other categories. BUT we’re pretty sure you’ll have the pleasure of finding them as level 100 and 200 next year  :-)



During the design of the challenges of the Crypto category, we focused on simple cryptography exercises, but also on some weird AES variations, aiming to set specific weaknesses on the proposed implementations, and finally on exercises requesting full protocol attacks.

To make things more interesting for our players, we designed some challenges to be real attacks to exposed services, instead of providing the usual problems to be solved statically.


The easier challenges were based on ancient encryption schemes or man in the middle attacks following most known cryptanalysis approaches and some guessing of specific problem requests. First challenge was starting with a request to our players to generate data from a map of images, known in south Italy tradition as Smorfia.

On the other hand, more difficult challenges focused the players attention on modern attacks on recent secure protocols, in some cases maybe a bit exotic. For example, a completely custom 180-bit elliptic curve was crafted to build the final crypto challenge.


The devil is in the details and even small errors can compromise a challenge.

In CRYPTO100 a simple typing error led to a wrong answer, in particular in the pdf initially released the weeks spent on the island were 5 instead of 15. Fortunately corrected and fixed in time.


A lot of teams managed to solve the first three crypto challenges, but no one reached the solution of the last two. Specifically, a crafted attack generating a lot of requests to the exposed server was requested to solve crypto400, and a big effort was needed for the cryptanalysis of the crypto500 protocol. With limited time due to the need to unblock such levels, the challenges proved to be hard. Next year we will work deeply to make more fun from our problems, although requiring our players to be math gods :) 



During this edition, web category has been the one with most network traffic load, as we expected.

Surprisingly, or maybe not so much, WEB100 attracted a lot of attention from automated tools such as dirbuster, nikto, rustbuster, and so on, even if the hint for the correct path (/graphql) was printed in the first (and only) line of the landing page :)

During the first 10 minutes of the challenge we temporarily banned over 60 IP addresses and still had to ban automatic scans all night long, having a blacklist of 10 IP addresses on average.

Fun fact: five minutes from the end of the competition, we still had 3 IP addresses in the blacklist, banned for using dirbuster, nessus (?) and sqlmap.


Another interesting fact is that for the web400 almost all the teams in the top 10 have won the race condition, which we thought would be the hardest part of the challenge.

The CRLF injection has been difficult to detect for everyone and probably almost nobody thought about a SQLi in the basic authentication.

At the end of the games, only 2 teams solved the web400, and one of them got the second position.



The arts of exploitation and reverse engineering require a lot of experience and technique. Finding bugs to exploit applications and understanding binary code of uncommon architectures are methodologies for people of great experience and an extreme ability in problem solving. 

The binary category was developed in order to simulate a potential undiscovered exploit or to retrieve sensible information in a IoT device. This is a daily routine for the IoT PenTest team in Reply.

This year we developed the binary category on a deep knowledge of the operating system and the capability of reading code of uncommon architectures. 


BINARY200 was a custom Boot Loader, the teams that solved this challenge proved a deep knowledge of how an operating system starts and how it is loaded in the memory. 


BINARY300 and 400 require multiple skills, the players must be able to find solutions to problems that they have never met. Emulation of arduino, read disassembly of uncommon CPUs, decompile SPIR-V code, execute and patch graphics binaries require an extraordinary problem solving ability. We really appreciate that boh the challenges were resolved by multiple teams, a special congratulations to the Armia Prezesa team which solved the BINARY400 in less than a couple of hours. 


The last challenge, BINARY500, was unsolved due to the lack of time available for the teams to solve the problem since this challenge was first unlocked at four hours from the end of the games. Although the time was running out, we checked that some teams tried to solve the most difficult binary challenge and they were on the right way! 

This challenge required a deep knowledge of how an operating system works and an extraordinary capability in writing exploits, this art is not for ordinary people. 


We really appreciated the effort of all the teams, especially the top ones who solved our binary challenges. We hope to see you next year, take care!


How many attacks did we receive?

As you can imagine, the Reply challenges platform is constantly exposed to external attacks. And these attacks become more and more frequent when we launch a new challenge and when we enlarge our community. Starting from September 9th (Registrations opening) to October 10th (end of the challenge) we collected a total of 173 attacks splittend in: SQL injection, cross-site scripting and illegal resource access - (mostly from? Ukraine!) 




Last but not least, the facts and figueres that matter: we ordered and drank +252 beers, ate 350 sandwiches, as they were not enough we added 40 pizzas, 50 crisps packs to accompany the countless time-travels with R-Boy.


So, the 2020 Cyber Securty Challenge has been a great adventure, take a look at the winners write-up and keep training.


What will R-Boy face next year? Only the best players will discover it. Kudos to all see you next year!