Skip to content

Instantly share code, notes, and snippets.

@radimkohout
Last active November 2, 2021 16:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save radimkohout/9ee18ff163d771cd586777873544e561 to your computer and use it in GitHub Desktop.
Save radimkohout/9ee18ff163d771cd586777873544e561 to your computer and use it in GitHub Desktop.
The Catch 2021 - write-up

We've been solving the Catch 2021 by CESNET with my friend Damian10012 ❤️ . We're ideal pair, since we complete each other. Our team was named "Podfukáři", and no, I'll not explain why 😁 . We've struggled in some challenges, but at the end, we've ended on 77th place with 30 points, which is nice for us.

We've been able to solve following challenges: Encrypted Archive, Problematic Executables, Unknown File, Cat Heads Language, The Services, Domain Name System, The Motivation, The Dark Side, The Geography, Private Network, Unknown server, Docker Image and Nomen Omen.

The unsolved challenges: Blogging Web Site, Social Network, File SHare, Phone Book and Torso of Web Server. In some of these cases, we have an idea, but we ran out of time.

This challenge is pretty hard to describe. We were given image, in which on each row, there were three cat heads and a character next to them. If the head is same as on the top of the picture, we'll write character in that row. The final result was:

FLAG{WISE-NICE-DEAR-CATS}

In this challenge, we've got a docker image in .tar file. The hint was to analyse the docker layers separatly, which we've done, and got one interesting python script:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Image generator
"""

__author__ = "G. I. Jane @ TCC"
__version__ = "1.0"

import sys
import argparse
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw

def get_args():
        """
        Cmd line argument parsing (preprocessing)
        """
        # Assign description to the help doc
        parser = argparse.ArgumentParser(\
                description='Image generator"')

        # Add arguments
        parser.add_argument(\
                '-f',
                '--filename',
                type=str,
                help='Target file',
                required=True)


        # Array for all arguments passed to script
        args = parser.parse_args()

        # Return arg variables
        return args.filename


def main():
        """
        Main function
        """

        # check python version
        if sys.version_info[0] < 3:
                print("ERROR: Python3 required.")
                sys.exit(1)

        # process args
        filename = get_args()

        # generate image
        var = ['651', '1L0', '5D0', '6D0', '301', '2A0', '3G0', '2r2', '4{0', '7K1', '1f2', '4}2', '9-1', '8L0', '8x1', '1K1', '0s2', '0m1', '0F0', '271', '5P1', '7m0', '4-1', '9-0', '3c2']
        tim = Image.new("RGB", (1024, 512), (0, 0, 0))
        font = ImageFont.truetype('cour.ttf', 32)
        draw = ImageDraw.Draw(tim)
        for v in var:
                draw.text((int(v[2])*300 + int(v[0])*30 + 3, 255), v[1], (255, 255, 255), font=font)
        try:
                tim.save(filename+".png")
        except Exception:
                print("File saving failed ...")
                sys.exit(2)

main()

#EOF

So I've ran it outside of the docker (with -f out), in python3, but there was an OSError, since font cour.ttf was needed in that folder. I've downloaded it, and got an output image, in which the flag was displayed: FLAG{DDmL-mK70-P5Kx-sfrc}

This challenge was kind of hard for us, it took us a long time to discover the solution. At first, we were able to discover, that by reverse DNS record, the domain for the given IP 78.128.216.18 is hamster.super.tcc The solution is to download zone transfer data for domain super.tcc from DNS at 78.128.216.18, which reported quite a few records. The interesting one for us, was base-64 encoded TXT record, which after decoding has given us the solution:FLAG{zh71-iouQ-bxms-jwHk}

In this challenge, we we're given two files: a text file with a lead to password and an encrypted zip file. In the text file, there was this string: 8fd2011515522f6879dddd55d18a83d7 , which after some Googling, we've found, that it is md5 password hash, and after pasting it in the md5 cracker, we've got a password mytreasure After unzipping the zip file, there was a markdown file with following content:

# Treasure map

1. Go to the temple of God #42
2. Find the south gate
3. Go to the south-west for 3 days and 3 night at constant speed 5 mph
4. Find closed cave entrance
5. Just right from cave entrance is letter-pannel
6. Enter code `FLAG{q5hi-Pa72-dxbp-wRHf}`
7. Profit

In this challenge, we've got self replicating binary, and the hint, that the number of combinations is limited. The binary replicates itself to %appdata%, so we've created c# program to copy them to temporary folder, and find the one that is flag.

static void Main(string[] args)
        {
            while (true)
            {
                string d1 = @"C:\Users\User\AppData\Roaming";
                string d2 = "app";
                DirectoryInfo dir1 = new DirectoryInfo(d1);
                DirectoryInfo dir2 = new DirectoryInfo(d2);
                List<FileInfo> list1 = dir1.GetFiles("*.exe", SearchOption.TopDirectoryOnly).OfType<FileInfo>().ToList();
                List<FileInfo> list2 = dir2.GetFiles("*.exe", SearchOption.TopDirectoryOnly).OfType<FileInfo>().ToList();
                while (list1.Count > 1)
                {
                    bool c = true;
                    for (int i = 0; i < list1.Count; i++)
                    {
                        if (!c) break;
                        for (int j = 0; j < list2.Count; j++)
                        {
                            if (list1[i].FullName.Substring(list1[i].FullName.LastIndexOf(@"\")) == list2[j].FullName.Substring(list2[j].FullName.LastIndexOf(@"\")))
                            {
                                list1.Remove(list1[i]);
                                c = false;
                                break;
                            }
                        }
                    }
                }
                if (list1.Count == 0 && list2.Count == 0) break;
                File.AppendAllText("names.txt",  Path.Combine(@"C:\Users\User\AppData\Roaming", list1[0].FullName)+"\n");
                System.Diagnostics.Process.Start(Path.Combine(@"C:\Users\User\AppData\Roaming", list1[0].FullName));
                Thread.Sleep(1000);
                String filename = list1[0].FullName.Substring(list1[0].FullName.LastIndexOf(@"\"));
                File.Copy(Path.Combine(@"C:\Users\User\AppData\Roaming", list1[0].FullName), d2 + @"\" + filename);
            }
            Console.WriteLine("This is the end");
        }

Then, after it crashed due to an uncaught exception(after file names got to repeat), I've found flag{fwsg-iboz-hmlt-pqhz} in names.txt

In this challenge, you're given server at 78.128.216.8 and the range 10.20.32.0/21, in which the web server should residate. On the 78.128.216.8 there is a squid proxy on port 3128. We've connected to it and written the following C# console app, to scan the whole range:

static void Main(string[] args)
        {
            bool b = true;
            for (int i = 32; i < 40; i++)
            {
                if (b) { 
                for (int j = 0; j < 255; j++)
                {
                    Console.WriteLine(i+"/"+j);
                    if ((i == 32 && j == 0) || (i == 39 && j == 255)) continue;
                    HttpWebRequest hwr = (HttpWebRequest)WebRequest.Create("http://10.20."+i+"."+j);
                    try { 
                    var v = hwr.GetResponse();
                    }
                    catch
                    {
                        continue;
                    }
                    Console.WriteLine("http://10.20." + i + "." + j);
                    b = false;
                    break;
                }
                }
            }
        }

The result was server http://10.20.35.11, which reported It took a long time, flag is FLAG{XG5T-WLWl-HqjH-2E7V}.

It this challenge there were 3 files present: binary for Linux, binary for Windows, and a part of a source code, that showed required arguments to correctly run the binary. These were:

executable(.exe) show-me-the-secret please 5

And the program returned:

Good usage!
GMBH|ncL5.ye1V.dOjq.47un~

This was string ascii shifted by 1, so we've written a C# program to shift it back:

        static void Main(string[] args)
        {
            string s = "GMBH|ncL5.ye1V.dOjq.47un~";
            string o = "";
            for (int i = 0; i < s.Length; i++)
            {
                o+=(char)((int)s[i]-1);
            }
            Console.WriteLine(o);
        }

The result was: FLAG{mbK4-xd0U-cNip-36tm}

In this challenge, we've been given thecatchu6jlyqgen3ox74kjcfr5lmwdc7jqj3vmekq6y45dmvo5xmad.onion, which is a Tor domain. After accesing that domain by Tor browser, we've got a very long string. After decoding it as a base-64 text(in.txt), we've got another base-64 code, but this time somewhat broken. After some time of struggling, We've written the following C# code, that takes the first letter, print it, and base-64 decode the string after the semicolon, until the program fells on exception(It doesn't have properly handed the length of the string):

            string base64 = "";
            base64 = File.ReadAllText("in.txt");
            while (true)
            {
                Console.WriteLine(base64[0]);
                base64 = System.Text.Encoding.Default.GetString(Convert.FromBase64String(base64.Substring(2)));
            }

And the program returned following: Here you are: FLAG{uNMI-DKSU-NKmq-7QE0}.

This challenge was pretty straight-forward, you have 120 seconds to change the country to which is presented to you by the page. The problem is, that the IP change invalidates your session, so you have to generate yourself a new one. Our solution was to use BurpSuite in Kali Linux, and while holding the session ID (cookie), change country, and than let it reload. The solution was: FLAG{OlFY-P2U0-86he-qU4q}

It this challenge, we've got an IP address 78.128.216.7. The hints say, that the server is from the begining of the Internet, and that in those times, the services ran on low ports. So we've nmapped the server by nmap -p T:1-1024 78.128.216.7, which reported following open ports:

PORT   STATE    SERVICE
17/tcp open     qotd
25/tcp filtered smtp

The SMTP was present in more challenges, so we've focused to the qotd(Quote of the day) service, and by telneting there, the server has returned some quote, and after a few tries, the server has returned: Once a correct sequence of connection attempts is received, the firewall rules are dynamically modified to allow the host. Sequence of three ports is 65000 + {DNS, LDAP, Syslog). Btw. look at 65000 again. - The Catcher So after a few unsuccessful tries, we've connected to the 65000 port by telnet, and then in other window quickly telnetted the 65053(65000+DNS), 65389(65000+LDAP) and 65514(65000+Syslog). The telnet at 65000 finally returned: FLAG{qC6Z-dQS7-4qoC-tR1m}

In this challenge, the IP 78.128.216.6 has been given to us. After analyzing it using nmap(nmap -p T:1-65535 78.128.216.6), we've discovered, that the following ports are open:

25/tcp    filtered smtp
2021/tcp  open     servexec
2022/tcp  open     down
2376/tcp  filtered docker
4445/tcp  open     upnotifyp
58080/tcp open     unknown

The smtp was on more challenges as well as docker, so we've ignored that. Instead, we've focused on the four remaining ports(2021,2022,4445,58080).

After telnetting the port 2021, the server has returned: FLAG4{YtRk1rMi00OXlXfQ==}

The same method can be applied to port 2022, where the SSH service have returned: FLAG3{czcV}

We've analyzed the port 4445 by nmap 78.128.216.6 -p T:4445 -A -sV, and the part of the flag here was in Workgroup: FLAG2{M3LV}

On port 58080, there is a webserver, so after accesing non-existing path, the Not Found page was returned and in the footer, there was: FLAG1{RkxBR3tZcm} Server at 78.128.216.6 Port 58080

After connecting the four parts together in right order(numerically), we can decode it as base-64 and get: FLAG{Yrc7-W3qV-FMk2-49yW}

In this challenge we've got a file of unknown type. After opening it in Notepad++, we can see mimetypeapplication/vnd.oasis.opendocument.spreadsheet after a few non-readable characters. We've opened it in the Libreoffice, and after coloring the cell containing the flag, in order to see it, we've got: FLAG{9Z5j-uAYr-ejUO-xwnY}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment