The Swedish CERT, CERT-SE, hosted another CTF this year with the following scenario.

CERT-SE has come across network traffic from the fictional hacker group "MedelĂĄlders Sura Blackhats".
Can you find all the flags?


When opening the attached pcap file we can find a couple of IRC-sessions. Filtering out all the messages we end up with this conversation.

Kammen!user@ PRIVMSG #Priv-IRC :Well, it should be safe. This new free VPN-service is what all my buddies is using. 🙂
Kammen!user@ PRIVMSG #Priv-IRC :Just look at your IP, it's a private non-routable one.
Frissan!user@ PRIVMSG #Priv-IRC :If you say so... It seems too good to be true, I mean, why is it free?!?
Sippen!user@ PRIVMSG #Priv-IRC :It's a developer that want to help with our cause. He's on our side! He's developed encryption software to others before.
Hejarn!user@ PRIVMSG #Priv-IRC :Ok ok ok, stop arguing!
Hejarn!user@ PRIVMSG #Priv-IRC :Just send the broadcast.
Sippen!user@ PRIVMSG #Priv-IRC :Done!
Frissan!user@ PRIVMSG #Priv-IRC :Ok then, just make sure all your disks are encrypted...
Hejarn!user@ PRIVMSG #Priv-IRC :Of course! Do you think we're stupid?!?
Kammen!user@ PRIVMSG #Priv-IRC :Erm, wait... I need to reinstall...
Frissan!user@ PRIVMSG #Priv-IRC :Oh what a muppet!!!
Sippen!user@ PRIVMSG #Priv-IRC :Sigh...
Hejarn!user@ PRIVMSG #Priv-IRC :LOL!!!
Kammen!user@ PRIVMSG #Priv-IRC :Hey guys, I'm back! 🙂
Frissan!user@ PRIVMSG #Priv-IRC :Encrypted now?!?
Kammen!user@ PRIVMSG #Priv-IRC :Yeah... Sorry, I was in a hurry.
Sippen!user@ PRIVMSG #Priv-IRC :Ok, but no more slipups! Nyckelpiga 17173 is too important!!!
Kammen!user@ PRIVMSG #Priv-IRC :Yeyeye... I know. :-/
Hejarn!user@ PRIVMSG #Priv-IRC :Is everything set?
Sippen!user@ PRIVMSG #Priv-IRC :Yes, I'm ready!
Frissan!user@ PRIVMSG #Priv-IRC :Done, just waiting for the signal!
Kammen!user@ PRIVMSG #Priv-IRC :Almost, I just have to finish the last pieces...
Frissan!user@ PRIVMSG #Priv-IRC :Sigh, seriously?!?
Kammen!user@ PRIVMSG #Priv-IRC :Ehehe... Just kidding, of course I'm ready! Soon...
Sippen!user@ PRIVMSG #Priv-IRC :Come on!
Hejarn!user@ PRIVMSG #Priv-IRC :Just finish it already! We're about to go!
Kammen!user@ PRIVMSG #Priv-IRC :Well, let's just go. It's ready enough...
Hejarn!user@ PRIVMSG #Priv-IRC :Ok!
Sippen!user@ PRIVMSG #Priv-IRC :What's the URL?
Kammen!user@ PRIVMSG #Priv-IRC :
Frissan!user@ PRIVMSG #Priv-IRC :It's not encrypted!?!?!
Sippen!user@ PRIVMSG #Priv-IRC :?!? :-O
Kammen!user@ PRIVMSG #Priv-IRC :Well, it's the thing I didn't have time to finish. But it should be ok, we want prople to find it anyway.
Hejarn!user@ PRIVMSG #Priv-IRC :You better be right, but if this fails it's because of you...
Kammen!user@ PRIVMSG #Priv-IRC :Don't worry, I'm too 1337 for that to happen! 🙂
Sippen!user@ PRIVMSG #Priv-IRC :Ok, but shut the server down as soon as you see that the message is received.
Kammen!user@ PRIVMSG #Priv-IRC :Of course, that was the plan all along.
Sippen!user@ PRIVMSG #Priv-IRC :I'm a bit hesistant of the transmission... Will it work?
Kammen!user@ PRIVMSG #Priv-IRC :If it worked for Apollo and ISS it should do fine for us. The receiver knows what to expect.
Kammen!user@ PRIVMSG #Priv-IRC :By the way, can I you have the star-file?
Hejarn!user@ PRIVMSG #Priv-IRC :Sure, sending it to you now...
Hejarn!user@ PRIVMSG Kammen :\001DCC SEND Star!6.kmz 199 0 2363 106\001
Hejarn!user@ PRIVMSG #Priv-IRC :Done.
Kammen!user@ PRIVMSG #Priv-IRC :Thanks!
Hejarn!user@ PRIVMSG #Priv-IRC :I still would feel much safer if we'd use an encrypted transfer.
Kammen!user@ PRIVMSG #Priv-IRC :You're being paranoid! We're on a VPN! 🙂
Hejarn!user@ PRIVMSG #Priv-IRC :I hope you're right...
Sippen!user@ PRIVMSG #Priv-IRC :Me too!
Kammen!user@ PRIVMSG #Priv-IRC :We'll be in the lost island of Atlantis before they even start looking for us. X-D
Sippen!user@ PRIVMSG #Priv-IRC :Yeah, Atlantis rulez! ❤
Kammen!user@ PRIVMSG #Priv-IRC :Sure does! Great parties!
Frissan!user@ PRIVMSG #Priv-IRC :Anyway, too late to go back... Is the Debian-dump ready?
Kammen!user@ PRIVMSG #Priv-IRC :Erm, yes... I have it on my USB key... Here... Somewhere...
Kammen!user@ PRIVMSG #Priv-IRC :One sec...
Sippen!user@ PRIVMSG #Priv-IRC :Sigh...
Hejarn!user@ PRIVMSG #Priv-IRC :Oh come on!!!
Hejarn!user@ PRIVMSG #Priv-IRC :Oh damn, did you hear?!? This "free" VPN is a made by the feds!!! They've developed it just to be able to see our traffic! Disconnect and go back to our old method! NOW!
Frissan!user@ PRIVMSG #Priv-IRC :k
Sippen!user@ PRIVMSG #Priv-IRC :What?!? :-O
Sippen!user@ PRIVMSG #Priv-IRC :Ok.
Kammen!user@ PRIVMSG #Priv-IRC :Ok, sending the dump now.
Kammen!user@ PRIVMSG #Priv-IRC :Ok, transfer is completed from my side. Now we just wait for the response. 🙂
Kammen!user@ PRIVMSG #Priv-IRC :So, are we ready for the last step?
Kammen!user@ PRIVMSG #Priv-IRC :Guys?
Kammen!user@ PRIVMSG #Priv-IRC :Where did you go?!?
Kammen!user@ PRIVMSG #Priv-IRC :Oh no...

From this we now know that there are four people in the group, Frissan, Kammen, Sippen and Hejarn, and that they are part of an operation called Nyckelpiga 17173.

We also find out that two files are being transferred somewhere and one file is being send by DCC. We also get an URL to some page,

HTTP Traffic

Lets start by taking a look at the HTTP objects from

HTTP objects

Here we get our first flag, CTF[bra_start].

Saving and opening the file giveup.jpg we get a QR Code.


Decoding the QR Code just returns a YouTube link to Rick Astley – Never Gonna Give You Up.

Using steghide without a password to check for hidden data we get the file flag.txt which contains our second flag, CTF[chameleon].

DCC file

In the TCP stream 270 we find the file data for Star!6.kmz which is sent via DCC. Saving the file and searching for what file type kmz is we find out that it’s a format for Google Maps and Google Earth.

When opening the file in Google Maps we get the following pattern.

Star!6.kmz in Google Maps

Lets try to open it in Google Earth instead an see if we can get another perspective. When we open the kmz file in Google Earth and put the camera in the center of the pattern we see the this instead.

Star!6.kmz in Google Earth

Now it looks like characters. When we read all characters we get the string XGU[IVHRORVMH].

This looks like some kind och cipher, and when using a cipher identifier it tells us that it probably is a Beaufort Cipher.

Since we know that the three first characters of the string should be CTF we can use dCode‘s Beaufort Decoder to recreate the key.

dCode Beaufort Decoder

It seems that the key simply is Z. When we decrypt the string using the key we get the third flag, CTF[RESILIENS].

FTP Data

Now lets take a look at the other two files that were transferred. If we filter the packets on FTP we find two FTP sessions.

220 (vsFTPd 3.0.3)
USER sippen
331 Please specify the password.
PASS R0tmosp4stej
230 Login successful.
215 UNIX Type: L8
200 Switching to Binary mode.
PORT 192,168,122,186,141,47
200 PORT command successful. Consider using PASV.
STOR broadcast.7z
150 Ok to send data.
226 Transfer complete.
221 Goodbye.
220 (vsFTPd 3.0.3)
USER kammen
331 Please specify the password.
PASS sm0rdegstras1g
230 Login successful.
215 UNIX Type: L8
200 Switching to Binary mode.
PORT 192,168,122,177,227,133
200 PORT command successful. Consider using PASV.
STOR memdump4.7z
150 Ok to send data.
226 Transfer complete.
221 Goodbye.

Here we see that two files, broadcast.7z and memdump4.7z, is uploaded to the FTP server.

Filtering the packets on FTP-DATA we find the data streams for both of the files. Lets save them and take a look at the contents.


When we try to unpack broadcast.7z we see that it’s password protected, but we got some directories and files anyway.












The file names in the directory ranges from 1-11. That can mean that the files are the index of the character in the password.

If we arrange the directory names using the file in the directory as an index we get ch0kl4Dmoj5. Which is the password for the file.

When we unpack the file using the password we get two new files, Zipper/.secret/-/flag.txt and Zipper/.secret/!/broadcast.wav.

If we take a look at flag.txt we get out fourth flag, ctf[skulle_skippat_linbanan].

Listening to the file broadcast.wav we can hear some kind of signal. As hinted in the IRC conversation that the signal worked for Apollo and ISS, this should be a SSTV signal.

Decoding the signal using a SSTV decoder like QSSTV we get a picture.

Decoded SSTV signal

And we get our fifth flag, CTF[RYMDLJUD].


Now it’s time to take a look at the last file we found. And as hinted in the IRC conversation this is a Debian memory dump. So the first thing we need to do is to download a Volatility profile for Debian and then we can start our analysis.

If we run vol2 --plugins=profiles --profile=LinuxDebian94x64 -f memdump4.dmp linux_bash we see that there’s a program named SuperSecretLogonTool running.

To get the PID for the process we run vol2 --plugins=profiles --profile=LinuxDebian94x64 -f memdump4.dmp linux_bash and get the PID 414.

To dump the process image we run vol2 --plugins=profiles --profile=LinuxDebian94x64 -f memdump4.dmp linux_procdump -p 414 -D out and we get an ELF file.

Now we can open the dumped image in Ghidra for further analysis. After fixing the disassembly and strings we get the following strings.

SuperSecretLogonTool strings

Here we see a string that starts with “Bra gjort! Här kommer flag…”. If we check where that string is used in the code we find the following function.

void UndefinedFunction_004011d6(void)

  int iVar1;
  byte bVar2;
  undefined8 *puVar3;
  undefined8 uStack104;
  undefined8 uStack96;
  undefined8 uStack88;
  undefined8 uStack80;
  undefined8 uStack72;
  undefined4 uStack64;
  undefined2 uStack60;
  undefined *puStack48;
  undefined8 uStack40;
  int iStack32;
  int iStack28;
  iStack32 = 0x16;
  uStack104 = 0x4847464544434241;
  uStack96 = 0x504f4e4d4c4b4a49;
  uStack88 = 0x5857565554535251;
  uStack80 = 0x3534333231305a59;
  uStack72 = 0x2b2d402139383736;
  uStack64 = 0x3d5d5b5f;
  uStack60 = 0x2623;
  uStack40 = 0x15;
  for (puVar3 = &uStack104; puVar3 != &uStack104; puVar3 = (undefined8 *)((long)puVar3 + -0x1000)) {
    *(undefined8 *)((long)puVar3 + -8) = *(undefined8 *)((long)puVar3 + -8);
  *(undefined8 *)((long)puVar3 + -8) = *(undefined8 *)((long)puVar3 + -8);
  puStack48 = (undefined *)((long)puVar3 + -0x60);
  *(undefined4 *)((long)puVar3 + -0x60) = 0x5d;
  *(undefined4 *)((long)puVar3 + -0x5c) = 0xd6;
  *(undefined4 *)((long)puVar3 + -0x58) = 0x18c;
  *(undefined4 *)((long)puVar3 + -0x54) = 0x308;
  *(undefined4 *)((long)puVar3 + -0x50) = 0x740;
  *(undefined4 *)((long)puVar3 + -0x4c) = 0xe60;
  *(undefined4 *)((long)puVar3 + -0x48) = 0x1c80;
  *(undefined4 *)((long)puVar3 + -0x44) = 0x3c80;
  *(undefined4 *)((long)puVar3 + -0x40) = 0x4d00;
  *(undefined4 *)((long)puVar3 + -0x3c) = 0xbe00;
  *(undefined4 *)((long)puVar3 + -0x38) = 0x1cc00;
  *(undefined4 *)((long)puVar3 + -0x34) = 0x39000;
  *(undefined4 *)((long)puVar3 + -0x30) = 0x61000;
  *(undefined4 *)((long)puVar3 + -0x2c) = 0xd6000;
  *(undefined4 *)((long)puVar3 + -0x28) = 0x18c000;
  *(undefined4 *)((long)puVar3 + -0x24) = 0x308000;
  *(undefined4 *)((long)puVar3 + -0x20) = 0x740000;
  *(undefined4 *)((long)puVar3 + -0x1c) = 0xa60000;
  *(undefined4 *)((long)puVar3 + -0x18) = 0x16c0000;
  *(undefined4 *)((long)puVar3 + -0x14) = 0x2300000;
  *(undefined4 *)((long)puVar3 + -0x10) = 0x5400000;
  *(undefined4 *)((long)puVar3 + -0xc) = 0x8600000;
  *(undefined8 *)((long)puVar3 + -0x68) = 0x4013f8;
  for (iStack28 = iStack32 + -1; -1 < iStack28; iStack28 = iStack28 + -1) {
    iVar1 = *(int *)(puStack48 + (long)iStack28 * 4);
    bVar2 = (byte)iStack28;
    *(undefined8 *)((long)puVar3 + -0x68) = 0x401420;
    putchar(iVar1 >> (bVar2 & 0x1f));
  *(undefined8 *)((long)puVar3 + -0x68) = 0x401434;

Here we can see that the flag is calculated using a bunch of values and then is printed character by character.

The following Python script will print the flag for us.

idx = 0x15

flag = [

decoded = bytearray()

for char in flag:
    value = flag[idx] >> (idx & 0x1f)
    idx -= 1


And if we run the script we get the sixth and final flag, CTF[Stackars_Myrstack].