🚀 Space Heroes 2022 CTF write-up
Tags: ctf, challenge, hacking, space
Published: 2022-04-04 17:34:00

[**Original post**](https://krypton.ninja/Space-Heroes-2022-CTF-write-up)

The Space Heroes 2022 CTF was an online CTF from April 1st (4pm UTC) to April 3rd (9pm UTC) 2022. It was hosted by [FITSEC ](https://ctftime.org/team/65296) and it even was their first time organizing such an event! Lots of applause to them for their hard work 👏 As a newbie CTF player, there were lots of challenges to have fun on and to successfully solve. This of course will improve my experience with CTFs and get me even more motivated to do more. The entire CTF was space themed, which made me even more motivated since I love space :D
I've solved much more challenges compared to the [Insomni'hack 2022 CTF](https://krypton.ninja/2022/03/28/Insomnihack-2022-CTF-write-up/), one reason is that there was more time; and also that some challenges were much more easier. This was an overall awesome CTF, especially for me as a newbie. I've learned a lot and hope to participate in their future CTFs!
As always, all flags had the same format which was `shctf{...}`. Let's get right into the write-up:

## 🆗 k?
This was a warm up challenge. The description said:
> MEE6 was busted! Help us out and unlock the flag in #mee6...

So here it's pretty obvious, let's head over to `#mee6` on their Discord server and see what we can try out. When using the `/help commands` commaannd, you can see a list of custom commands made by the Discord server administrators. There was a command that looked interesting: `!k (optional text) - An awesome command!`.
When typing `!k` you will get the flag sent in your private messages by the bot: `k? shctf{WhY_iS_K_BaNnEd}  😭`. Free points for that one!

## 💬 Discord
Another challenge on Discord, this time the flag was hidden _somewhere_ in the Discord server. I've seen lots of people trying random things in the `#mee6` channel to get that flag while it said _somewhere_. So I've used the search function to search for some flags; nothing. I looked at every channel topic and pinned messages; nothing alarming. But when I went back on the `#mee6` channel, I clicked on MEE6's profile; and there it was. MEE6 had a custom role named: `shctf{4ut0b0ts_r013_0u7}`.

<figure>
  <img alt="Evil MEE6..." src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/discord.png" />
  <figcaption>Evil MEE6...</figcaption>
</figure>



## 🛡️ Guardians of the Galaxy
We are given a netcat connection and the binary of the program ([Download here](https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/files/guardians.bin)). When testing the program locally it crashes, but why? Let's investigate by opening the file in a disassembler.

<figure>
  <img alt="The crash source" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/crash.png" >
  <figcaption>The crash source</figcaption>
</figure>


This is the source of the crash, and it's really easy to understand. If `fopen` returns `0x0`, then the file doesn't exist, and therefore the binary crashes. So let's create a dummy `flag.txt` file with the content `FLAG_____FLAG`. But before running the binary again, we can see that the data for the file is stored at the location `rbp-0x30` with a size of `0x20`.

<figure>
  <img alt="Calling convention matters" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/fgets.png">
  <figcaption>Calling convention matters</figcaption>
</figure>

To confirm that, we can run the file with gdb and check the content:

<figure>
  <img alt="Confirmed" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/gdb.png" />
  <figcaption>Confirmed</figcaption>
</figure>

The binary prints **exactly** what we send with `printf` according to this assembly code:

<figure>
  <img alt="Our text is repeated" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/printf.png" />
  <figcaption>Our text is repeated</figcaption>
</figure>

So let's use some string formats such as `%x` or others. When using `%p` we get a nice hexadecimal representation of the address returned. So let's print lots of them.

<figure>
  <img alt="Spam, spam, spam..." src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/string_format.png" />
  <figcaption>Spam, spam, spam...</figcaption>
</figure>

When looking at the data being given back, we can see some hexadecimal values of ASCII characters. Starting at `0x6d697b6674636873` and ending at `0x55f6d2000a7d`. So let's write a Python script to extract that data:

```python
"""
Useless data:

0x7ffd7417b6f0
0x55f6d353b2a0
0x2570257025702570
0x2570257025702570
0x2570257025702570
0x70257025702570
---------------

Important data:

0x6d697b6674636873
0x636172747369645f
0x756f795f676e6974
0x55f6d2000a7d
"""

from binascii import unhexlify

flag = b"".join(
    [
        unhexlify("6d697b6674636873")[::-1],
        unhexlify("636172747369645f")[::-1],
        unhexlify("756f795f676e6974")[::-1],
        unhexlify("55f6d2000a7d")[::-1],
    ]
)

print(flag)
```
[Code](https://gist.github.com/kkrypt0nn/7bda0bc626c9ca5f0d127a8fcabdaa1c)

This gave back: `b'shctf{im_distracting_you}\n\x00\xd2\xf6U'`, and there we have the flag, `shctf{im_distracting_you}`.

## 🧑‍🚀 Space traveler
We were given a URL: `https://spaceheroes-web-explore.chals.io`. When going on the website we could hit the `Guess The Flag` button. We had to give a flag as input and it would say if it's valid or not. Looking at the network tab in the developers tool, not external requests were made. So the check is done locally. When looking at the source code there was some obfuscated source:
```javascript
var _0xb645 = ["\x47\x75\x65\x73\x73\x20\x54\x68\x65\x20\x46\x6C\x61\x67", "\x73\x68\x63\x74\x66\x7B\x66\x6C\x61\x67\x7D", "\x59\x6F\x75\x20\x67\x75\x65\x73\x73\x65\x64\x20\x72\x69\x67\x68\x74\x2E", "\x73\x68\x63\x74\x66\x7B\x65\x69\x67\x68\x74\x79\x5F\x73\x65\x76\x65\x6E\x5F\x74\x68\x6F\x75\x73\x61\x6E\x64\x5F\x6D\x69\x6C\x6C\x69\x6F\x6E\x5F\x73\x75\x6E\x73\x7D", "\x59\x6F\x75\x20\x67\x75\x65\x73\x73\x65\x64\x20\x77\x72\x6F\x6E\x67\x2E", "\x69\x6E\x6E\x65\x72\x48\x54\x4D\x4C", "\x64\x65\x6D\x6F", "\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x42\x79\x49\x64"];

function myFunction() {
    let _0xb729x2;
    let _0xb729x3 = prompt(_0xb645[0], _0xb645[1]);
    switch (_0xb729x3) {
        case _0xb645[3]:
            _0xb729x2 = _0xb645[2];
            break;
        default:
            _0xb729x2 = _0xb645[4]
    };
    document[_0xb645[7]](_0xb645[6])[_0xb645[5]] = _0xb729x2
}
```
When looking at it, we can see it's obfuscated, so let's [deobfuscate it](https://deobfuscate.io)!
```javascript
function myFunction() {
  let azante;
  let karynna = prompt("Guess The Flag", "shctf{flag}");
  switch (karynna) {
    case "shctf{eighty_seven_thousand_million_suns}":
      azante = "You guessed right.";
      break;
    default:
      azante = "You guessed wrong.";
  }
  ;
  document.getElementById("demo").innerHTML = azante;
}
```

Well, that's much more readable and we can see the flag in plaintext: <code>shctf{eighty_seven_thousand_million_suns}</code>.

## 🕵️‍♂️ Curious?
This challenge was pretty straight forward, it was an OSINT challenge. For this one is was basically _"Who can search better on Google?"_. Well in my case, I used [TinEye](https://tineye.com) since we were given a picture:

<figure>
  <img alt="Isn't Curiosity amazing?" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/curiosity.png" />
  <figcaption>Isn't Curiosity amazing?</figcaption>
</figure>

When searching for that picture, there were some websites that had this picture. Here is a list of them:
~~http://www.dailytechinfo.org/tags/%C7%E0%E4%E5%F0%E6%EA%E0/~~ - Russian, nothing important for the challenge
~~https://dailytechinfo.org/space/5613-marsohod-curiosity-napolovinu-preodolel-voznikshee-pered-nim-prepyatstvie.html~~ - Russian, nothing important for the challenge
~~http://news.discovery.com/space/the-moment-when-curiosity-breached-a-mars-dune-140205.htm~~ - Offline
https://www.hjkc.de/_blog/2014/02/05/2391-mars-curiosity-chroniken---curiosity-news-sol-529-533/ - Could be interesting
https://www.space.com/24592-mars-rover-curiosity-dune-jump.html - Could be interesting

When looking at the last result, it clearly has as title _"The Moment When Curiosity Breached a Mars Dune"_. Considering the flag format was given, <code>shctf{SOL_xxx}</code>, we can see that this picture was taken at SOL 533. So pretty simple, right? <code>shctf{SOL_533}</code> is the flag.
The other website, hjkc.de also contained the SOL 533 picture, you just have to scroll _a lot_.

## 🚀 Launched
Another OSINT challenge, this time we are given the picture of a rocket that just launched.

<figure>
  <img alt="Just awesome to see that.." src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/launched.jpg" />
  <figcaption>Just awesome to see that..</figcaption>
</figure>

Considering the flag format was `shctf{rocket_payload}`, it's pretty easy to know we need to find the rocket and its payload name. It's also the first time I know payloads can have names 🤯
So let's get _exiftool_ in my hands. When looking at the data we got back, we can see some interesting information:
```
ExifTool Version Number         : 12.40
File Name                       : launched.jpg
...
Date/Time Original              : 2019:04:11 18:36:33
Create Date                     : 2019:04:11 18:36:33
...
```
One of them being the exact date and time when the picture was taken. So we can see that the rocket was launched at `2019:04:11 18:36:33`. Just need to find the rocket name and its payload now.
A simple Google search showed that the rocket was a [Falcon Heavy](https://www.cnbc.com/2019/04/11/livestream-watch-spacex-falcon-heavy-rocket-launch-and-landing.html). Now we need the payload name; let's try [Wikipedia](https://en.wikipedia.org/wiki/Falcon_Heavy#Launches_and_payloads). Yup, there we go:

<figure>
  <img alt="Interesting that payloads have names..." src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/payload.png" />
  <figcaption>Interesting that payloads have names...</figcaption>
</figure>

So now let's put everything in the flag format, <code>shctf{rocket_payload}</code>, and we get <code>shctf{falcon_heavy_arabsat-6A}</code>.

## 🌌 Flag in space
A web challenge. We are greeted with a website that has a grid with empty content. We URL was http://172.105.154.14/?flag=, so let's try to put some garbage in the GET parameter. When trying some characters you can see that some grids now contain the character that was correct, so if you put the `flag` parameter to <code>shctf{aaa</code>, you get the following:

<figure>
  <img alt="The flag is not encoded, phew" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/grid.png" />
  <figcaption>The flag is not encoded, phew</figcaption>
</figure>

Looking at the source code it's a basic `<div>s</div>` for every character. We could try each character ourselves but some flags are known to have special characters or numbers so it would take ages. Therefore I made a simple script that appends every character, and if it gets the `<div>` element, then it gets added in a variable `res`. I've already put the known characters as an element in the `res` variable.
Then we simply make a request with all the characters from `res` and append the currently looped character. Here is my source code, you might understand it better:
```python
import requests

flag = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "}"]
res = ["s", "h", "c", "t", "f", "{"]

for i in range(0, len(flag)):
    for j in range (0x21, 0x7d):
        char = chr(j)
        url = "http://172.105.154.14/?flag=" + "".join(res) + char
        r = requests.get(url)
        response = "".join(r.text.split())
        previous = ""
        for k in range(0, len(res)):
            previous += "<div>" + res[k] + "</div>"
        if f"{previous}<div>{char}</div>" in response:
            res += char
            print("".join(res), end="\r")
            break
print("".join(res))
```
[Code](https://gist.github.com/kkrypt0nn/6bc38756350cb3d7443b3cea831831fd)

After quite some time, the script gives the following flag back: <code>shctf{2_explor3_fronti3r}</code>.

## 🤖 R2D2
Looking back at this one, it was pretty obvious... We are greeted on a website that looks like that:

<figure>
  <img alt="I personally don't like Star Wars :D" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/r2d2.png" />
  <figcaption>I personally don't like Star Wars :D</figcaption>
</figure>

Looking at the source code, nothing. Looking at the local storage, nothing. Looking at the cookies, nothing. I decided to run _gobuster_ on the website with a [wordlist](https://github.com/kkrypt0nn/Wordlists/blob/master/directory_scanner/common.txt). Guess what kind of file was detected... **robots.txt**, of course......

<figure>
  <img alt="This shows my lack of experience" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/gobuster.png" />
  <figcaption>This shows my lack of experience</figcaption>
</figure>

Getting on that file gives the flag back, <code>shctf{th1s-aster0id-1<span>$</span>-n0t-3ntir3ly-stable}</code>.

## 🌟 Starman
Another OSINT challenge. This time the description says already a lot:
> How far away from earth was the space car on January, 20 2021 at 1515 UTC? Enter distance in terms of Million Km. (Rounded to two decimals) (e.g shctf{12.34})

Searching up on Google what the _space car_ is, I came across [this website](https://theskylive.com/roadster-info). And at the right we can give a date and time, and we get an [awesome map](https://theskylive.com/planetarium?obj=roadster&date=2021-01-20&h=15&m=15). When looking at the map we see that it was at `56.68` million km away from earth. Therefore the flag was: <code>shctf{56.68}</code>.

## 🐕 Space Buds
> One of the puppies got into the web server. Can you help find out who it was?

With that description there also was a picture of the Space Buds.

<figure>
  <img alt="Cute dogs :)" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/spacebuds.jpg" />
  <figcaption>Cute dogs :)</figcaption>
</figure>

There also was a website, that pretty much contained _nothing_. But when inspecting the source code, there was a hidden input element.

<figure>
  <img alt="The background is horrible" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/hacker.png" />
  <figcaption>The background is horrible</figcaption>
</figure>

So I searched up on the Internet what the names of the puppies were and put them one by one in the input field. But still nothing. However, when sending the form, there was a request made to `/getcookie`. So maybe there's something in my cookies?

<figure>
  <img alt="Nothing big. Right?" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/cookies.png" />
  <figcaption>Nothing big. Right?</figcaption>
</figure>

But we can **change** the value of that cookie, so let's put the name of each dog in the cookie and reload the page. When typing *Mudbud*, there was a flag given. 

<figure>
  <img alt="Please next time put some better quality" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/mudbud.png" />
  <figcaption>Please next time put some better quality</figcaption>
</figure>

After literally *decrypting* that flag, it results to <code>shctf{tastes_like_raspberries}</code>.

## 🛰️ Cape Kennedy
This was a reversing challenge. We were given a Python file that contains a password check.

```python
import sys

def main():
  if len(sys.argv) != 2:
    print("Invalid args")
    return

  password = sys.argv[1]
  builder = 0
  
  for c in password:
    builder += ord(c)
  
  if builder == 713 and len(password) == 8 and (ord(password[2]) == ord(password[5])):
    if (ord(password[3]) == ord(password[4])) and ((ord(password[6])) == ord(password[7])):
        print("correct")
    else:
        print("incorrect")
  else:
    print("incorrect")

if __name__ == "__main__":
  main()
```
[Source](https://gist.github.com/kkrypt0nn/67cfbf20500b9452fd5d6ff4573369ff)

This one was quite easy to reverse. The password must have a length of 8. The characters and index 2 and 5 must be the same, the characters at index 3 and 4 must be the same and the characters and index 6 and 7 must be the same. The sum of the hexadecimal value of the characters must be 713.
Let's make a bruteforce script:
```python
import random
from string import ascii_letters

pwds = []

def solve():
    while True:
        s = ["A"]*8
        s[0] = random.choice(ascii_letters)
        s[1] = random.choice(ascii_letters)
        s[2] = random.choice(ascii_letters)
        s[5] = s[2]
        s[3] = random.choice(ascii_letters)
        s[4] = s[3]
        s[6] = random.choice(ascii_letters)
        s[7] = s[6]
        builder = 0
        
        password = "".join(s)
  
        for c in password:
            builder += ord(c)

        if (builder == 713 and len(password) == 8 and (ord(password[2]) == ord(password[5]))):
            if (ord(password[3]) == ord(password[4])) and ((ord(password[6])) == ord(password[7])):
                if password not in pwds:
                    pwds.append(password)
                    with open("moon.txt", "a") as f:
                        f.write(password + "\n")
solve()
```
[Source](https://gist.github.com/kkrypt0nn/0d4f658978524fb3a7c77e2395ca341f)

And yes, there was **A LOT** of valid passwords, over 3 millions.
Considering it was space themed (It was mentioned in the description of the challenge again.), I searched what happened at Cape Kennedy and that was related to the moon, since the file was named `moon.py`. It didn't took long until I've found that Apollo 11 started from there, a historic moment in space exploration! Looking at the results in `moon.txt` I've found a string generated that was `APOllOaa`. So with the knowledge of before and that valid string, the flag is simply <code>shctf{Apollo11}</code>.

## ⭐ Star Pcap
There was no description, just a pcap file ([Download here](https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/files/star.pcap)). When opening the file with Wireshark, we can see that there is just one slight change in all those ICMP packets, which is the ICMP code.
Using `pyshark` it was easy to put all these codes together, convert them to an decimal value and then to a character.

```python
import pyshark

capture = pyshark.FileCapture("star.pcap")
data = ""
for packet in capture:
    data += chr(int(packet.layers[2]._all_fields["icmp.code"]))

print(data)
```
[Source](https://gist.github.com/kkrypt0nn/adb3595e2ec5bbfd991724fae1cec68f)

This resulted in the following string: `c2hjdGZ7TDBnMWMtaSQtdGgzLWJlZ2lOTmluZy0wZi13aSRkb019`. Typical for CTFs, the data is base64 encoded. After decoding it, we can get the flag: <code>shctf{L0g1c-i<span>$</span>-th3-begiNNing-0f-wi<span>$</span>doM}</code>.

## 👁️‍🗨️ Mysterious Broadcast
Another web challenge.
> There used to be 8 Models of humanoid cylon but now there are only 7. We've located one of their broadcast nodes but we can't decode it. Are you able to decipher their technologies?

When going on the website, there is a random ID generated in the URL, it looks like this: http://173.230.134.127/seq/710a1f63-57b9-4b86-a880-f413418375d9
The website had nothing besides an `~` as response, interesting. When reloading; it turned to a 1, when reloading again; it didn't changed. But when reloading for the third time, it turned to a 0. Here is how it looked like:

<figure>
  <img alt="You probably don't want to write one by one" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/reload.png" />
  <figcaption>You probably don't want to write one by one</figcaption>
</figure>


**Binary!** But I don't want to write everything down as it might be a lot of 0's and 1's in the end, so let's make a quick Python script and save the output in a variable:
```python
import requests

binary = ""

while True:
    r = requests.get("http://173.230.134.127/seq/710a1f63-57b9-4b86-a880-f413418375d9")
    if (r.text == "~"):
        break
    binary += r.text
    print(binary)

print("\n[+] Received: " + binary)
# 1100011011001011010001101010110010010001111011010011011110100011011000100111011010101100001101011111011001001010110001101100001000101011001110100011101101110110001100001010101011001110100101101000110001011011011010010110100011000111101101101001001110011000011110011101111010111101
```
[Source](https://gist.github.com/kkrypt0nn/9ff087bc8fb5036231062a634d0211c2)

Here we go, we got the binary and now we can just decode it.

`ÆËF¬í7£bv¬5öJÆÂ+:;v0ªÎ[ihÇ¶yÞ½` ehhh, I don't think that's correct 🤔 Let's look at the description again - `There used to be *8* Models of humanoid cylon but now there are only *7*. [...]`. Remember, when representing a character, for example **A**, in binary there are **8** 1's or 0's such as `01000001`. And according the the description, there are now only **7**. So let's put a space every 7th character and decode that.
Most of the decoders give the same output, as they don't take in consideration the space. But [this one](https://rapidtables.com/convert/number/binary-to-ascii.html) did take in consideration the space. It resulted in `c2hjdGZ7QXNjaWlJc0E3Qml0U3RhbmRhcmR9Cg==`. Again, the `==` is typical for base64 encoding. So let's decode it: <code>shctf{AsciiIsA7BitStandard}</code>.

## 🐈 Space Captain Garfield
This one was more about OSINT at the beginning. We have the following picture:

<figure>
  <img alt="What on Earth is that..." src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/space_captain_garfield.png" />
  <figcaption>What on Earth is that...</figcaption>
</figure>

There was just the number `2254` not _encrypted_. So by searching `garfield dreaming 2254` on Google I've found this picture:

<figure>
  <img alt="The fun is coming..." src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/garfield.png" />
  <figcaption>The fun is coming...</figcaption>
</figure>

So yes, what had to be done was to map each character to its sign and then reconstruct the flag in the last picture. I started and got `shctf{lasa..alo.er}`, after some guessing for the last ones it was <code>shctf{lasagnalover}</code>.

## 🚩 Netflix and CTF
This one was very similar to the Star Pcap challenge above. We are given a pcap file ([Download here](https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/files/netflix-and-ctf.pcap)) and we have to analyze it. When looking at it, there is always request made to `http://10.10.100.124:8060/keypress/Lit_X` where `X` always varies. Sometimes there is a request made to `/browse`, this puts a line between the keypresses, and show names.
So let's make a Python script using _tshark_ again and save the output of each show in a list:
```python
import pyshark
import urllib.parse

capture = pyshark.FileCapture("netflix-and-ctf.pcap")
data = []

show_data = ""
for packet in capture:
    try:
        if "browse" in packet.layers[3]._all_fields["http.response_for.uri"]:
            data.append(show_data)
            show_data = ""
            continue
        show_data += urllib.parse.unquote(packet.layers[3]._all_fields["http.response_for.uri"].replace("http://10.10.100.124:8060/keypress/Lit_", ""))
    except:
        pass

for show in data:
    if "shctf" in show:
        print(f"Special show found: {show}")
        break
```
[Source](https://gist.github.com/kkrypt0nn/aa1b77498c73f841c9e7ddcb25f15a9b)

The special show found was: <code>shctf{T1m3-is-th3-ultimat3-curr3Ncy}</code>.

## 🚦 Strange Traffic
My favorite forensics challenge. We were given again a pcap file ([Download here](https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/files/strangetraffic.pcap)). There also was a free hint, so let's take it:
> Hint: alt,esc,1,2,3,4,5,6,7,8,9,0,-,=,backspace,tab,q,w,...

All right, now let's investigate the pcap file.

<figure>
  <img alt="Only UDP packets, this one will be easy." src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/strange.png" />
  <figcaption>Only UDP packets, this one will be easy.</figcaption>
</figure>

The number encircled in purple is the only number that changes and appears in all packets. So we need to get this value for each packet. For this example, the `35` is formed thanks to the `33` and `35` which if decoded to in the ASCII table, they are `3` and `5`. Now with `35` what can we do? Let's look at the hint again. It's clearly a keyboard layout. Now if we look at the query keyboard layout that was sent on Discord:

<figure>
  <img alt="I've never used such a keyboard" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/qwerty.png" />
  <figcaption>I've never used such a keyboard</figcaption>
</figure>

If we start counting each key and count up to `35`, we get the key `s`, which could fit for the `s` in the `shctf{...}` format. After checking with the other packets, this theory is right. Now let's code a script for that:

```python
import pyshark, binascii

capture = pyshark.FileCapture("strangetraffic.pcap")

# Map the entire keyboard
map = {
    "1": "`",
    "2": "1",
    "3": "2",
    "4": "3",
    "5": "4",
    "6": "5",
    "7": "6",
    "8": "7",
    "9": "8",
    "10": "9",
    "11": "0",
    "12": "-",
    "13": "=",
    "14": "<-",
    "15": "tab",
    "16": "q",
    "17": "w",
    "18": "e",
    "19": "r",
    "20": "t",
    "21": "y",
    "22": "u",
    "23": "i",
    "24": "o",
    "25": "p",
    "26": "[",
    "27": "]",
    "28": "enter",
    "29": "caps",
    "30": "a",
    "31": "s",
    "32": "d",
    "33": "f",
    "34": "g",
    "35": "h",
    "36": "j",
    "37": "k",
    "38": "l",
    "39": ";",
    "40": "'",
    "41": "#",
    "42": "shift",
    "43": "\\",
    "44": "z",
    "45": "x",
    "46": "c",
    "47": "v",
    "48": "b",
    "49": "n",
    "50": "m",
    "51": ",",
    "52": ".",
    "53": "/",
    "54": "ctrl",
    "55": "win",
    "56": "alt",
    "57": "space",
    "58": "alt",
    "59": "win",
    "60": "menu",
    "61": "ctrl",
}

flag = []

for packet in capture:
    payload = packet.layers[2]._all_fields["udp.payload"][75:].split(":") # Ignore the fist 75 characters from the payload
    for i in range(0, len(payload)):
        payload[i] = str(binascii.unhexlify(payload[i]), "ascii") # Coinvert to ASCII representation
    flag.append("".join(payload))

res = ""

for f in flag:
    res += map[str(f)]
print(res.replace("shift[", "{").replace("shift]", "}").replace("enter", "").replace("space", "_")) # Description said we can swap spaces with underscores
```
[Source](https://gist.github.com/kkrypt0nn/a616bab5b17ec8533dac4036fe855a56)

In the end we get the following flag: <code>shctf{thanks_f0r_th3_t4nk._he_n3ver_get5_me_anyth1ng}</code>.

## 🔮 Future Stego
For this challenge there were two pictures, one to download which was:

<figure>
  <img alt="The quality is insane" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/shuttle.jpg" />
  <figcaption>The quality is insane</figcaption>
</figure>

There also was another picture in the description, as a hint:

<figure>
  <img alt="I wasn't born when this was published x)" src="https://krypton.ninja/static/Space-Heroes-2022-CTF-write-up/newspaper.jpg" />
  <figcaption>I wasn't born when this was published x)</figcaption>
</figure>

After trying lots of steganography techniques, I couldn't find any that lead me to the flag. One of the last was to use `stegcracker`. I tried to bruteforce the password with the rockyou wordlist, but stopped at around 300'000 words tried. Nothing.
But the picture wasn't here for **nothing**.. Let's try some passwords that are in the news paper picture and use `steghide --extract -sf shuttle.jpg`. After playing around and trying some combinations such as `spacewoman`, `newsweek` or `sally k. ride`, I tried the file name: `sallyride`. This was the password and extracted a text file which contained the flag: <code>shctf{weightlessness_is_a_great_equalizer}</code>. It also would've worked with `stegcracker` and the right password in a text file.