Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 107 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,120 @@
# 🎓 High School Tasks 26
<div align="center">

Tasks for the 3rd edition of Hack4Krak CTF!
# 🎓 High School Tasks '26

> [!CAUTION]
> This repository contains **solutions** for CTF tasks!\
> Remember to **never** share this repository with anyone outside the **High School Tasks 26** team!
>
> *If this leaks, I will hunt you down - and you will be forced to use nothing but Windows, Copilot, and Edge for the rest of your tragically short life.*
### Task configuration & write-ups for **Hack4Krak CTF 2026**

## Documentation
*The 3rd edition of the Hack4Krak CTF 2026 - the biggest CTF for highschoolers in Poland 🇵🇱*

You can read about how to configure each task in [STRUCTURE.md](docs/STRUCTURE.md).\
Each task must be properly tested before submission - both manually and by writing automated tests, as described in [TESTING.md](docs/TESTING.md).
<br>

And if your name begins with `N` and ends with `orbiros`, and you are responsible for deploying tasks, check out [DEPLOYMENT.md](docs/DEPLOYMENT.md).
[![Edition](https://img.shields.io/badge/edition-III-7C3AED?style=for-the-badge)](#)
[![Tasks](https://img.shields.io/badge/tasks-35-22C55E?style=for-the-badge)](#task-catalog)
[![Discord](https://img.shields.io/badge/Discord-join%20us-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/ASPqckzEd8)
[![Website](https://img.shields.io/badge/hack4krak.pl-visit-7C3AED?style=for-the-badge)](https://hack4krak.pl)

## Architecture
- [tasks/](tasks/) - configuration for all tasks
- [config/](config/) - configuration for the specific CTF event
- [toolbox/](toolbox/) - our custom CLI for working with this repository
- [docs/](docs/) - documentation
</div>

> [!NOTE]
> **This edition has finished. The repository is archived.**
> It now stands as a complete record of every task, its configuration, and an official write-up. Browse, learn, and reproduce.

## By the numbers

<table align="center">
<tr>
<td align="center" width="180">
<h2>109</h2>
participants<br>took part
</td>
<td align="center" width="180">
<h2>29</h2>
teams captured<br>at least one flag
</td>
<td align="center" width="180">
<h2>676</h2>
flags submitted<br>during the CTF
</td>
<td align="center" width="180">
<h2>35</h2>
tasks across<br>9 categories
</td>
<td align="center" width="180">
<h2>2</h2>
teams solved<br>every single task
</td>
</tr>
</table>

<p align="center"><em>Over <strong>30 hours</strong> of non-stop hacking across two days.</em></p>

## Task catalog

Every task links to its **description** (the prompt players saw) and its **write-up** (how it was meant to be cracked).

| Task | Category | Difficulty | Write-up |
| :--- | :--- | :--- | :---: |
| [**Ankieterzy na Mogilskim**](tasks/ankieta/description.md) | `Misc` | 🟢 Rookie | [Solution](tasks/ankieta/solution.md) |
| [**flappykrak**](tasks/flappy-krak/description.md) | `Games` | 🟢 Rookie | [Solution](tasks/flappy-krak/solution.md) |
| [**No Handshake, No Flag**](tasks/handshake/description.md) | `Misc` | 🟢 Rookie | [Solution](tasks/handshake/solution.md) |
| [**Zakrzowek Fast Pass**](tasks/zakrzowek-fast-pass/description.md) | `Web` · `Misc` | 🟢 Rookie | [Solution](tasks/zakrzowek-fast-pass/solution.md) |
| [**900728**](tasks/900728/description.md) | `Misc` | 🔵 Easy | [Solution](tasks/900728/solution.md) |
| [**Co tam się odjaniepawla?**](tasks/co-tam-sie-odjaniepawla/description.md) | `Games` | 🔵 Easy | [Solution](tasks/co-tam-sie-odjaniepawla/solution.md) |
| [**Czemu to nie działa???**](tasks/czemu-nie-dziala/description.md) | `Web` | 🔵 Easy | [Solution](tasks/czemu-nie-dziala/solution.md) |
| [**Symulator Szewczyka Dratewki**](tasks/dratewka-simulator/description.md) | `Games` | 🔵 Easy | [Solution](tasks/dratewka-simulator/solution.md) |
| [**Ucieczka po Krakowie**](tasks/fly-you-fools/description.md) | `Misc` · `Reverse` | 🔵 Easy | [Solution](tasks/fly-you-fools/solution.md) |
| [**Strony nie z tego świata**](tasks/hidden-site/description.md) | `Misc` | 🔵 Easy | [Solution](tasks/hidden-site/solution.md) |
| [**Kraków Arcade Museum**](tasks/krakow-arcade-museum/description.md) | `Games` · `Misc` | 🔵 Easy | [Solution](tasks/krakow-arcade-museum/solution.md) |
| [**Linux Ain't Scary**](tasks/linux-aint-scary/description.md) | `Misc` | 🔵 Easy | [Solution](tasks/linux-aint-scary/solution.md) |
| [**Logika Nie Logikuje**](tasks/logika-nie-logikuje/description.md) | `Misc` | 🔵 Easy | [Solution](tasks/logika-nie-logikuje/solution.md) |
| [**Ale z niego poliglota!**](tasks/polyglot/description.md) | `Misc` | 🔵 Easy | [Solution](tasks/polyglot/solution.md) |
| [**Session Snack**](tasks/session-snack/description.md) | `Web` | 🔵 Easy | [Solution](tasks/session-snack/solution.md) |
| [**Shadows in the Light**](tasks/shadows-in-the-light/description.md) | `Web` · `Misc` | 🔵 Easy | [Solution](tasks/shadows-in-the-light/solution.md) |
| [**Yet Another Minecraft**](tasks/yet-another-minecraft/description.md) | `Games` | 🔵 Easy | [Solution](tasks/yet-another-minecraft/solution.md) |
| [**Bileciki do kontroli!**](tasks/bileciki-do-kontroli/description.md) | `Misc` · `Physical` | 🟠 Medium | [Solution](tasks/bileciki-do-kontroli/solution.md) |
| [**Krakowskie Kasyno**](tasks/casino/description.md) | `Pwn` | 🟠 Medium | [Solution](tasks/casino/solution.md) |
| [**Co to za numer**](tasks/co-to-za-numer/description.md) | `Web` | 🟠 Medium | [Solution](tasks/co-to-za-numer/solution.md) |
| [**Kradzież Rzeczywistości**](tasks/kradziez-rzeczywistosci/description.md) | `Reverse` | 🟠 Medium | [Solution](tasks/kradziez-rzeczywistosci/solution.md) |
| [**MOCAK**](tasks/mocak/description.md) | `Misc` | 🟠 Medium | [Solution](tasks/mocak/solution.md) |
| [**Kulisy Słowackiego**](tasks/slowacki-backstage/description.md) | `Reverse` · `Pwn` | 🟠 Medium | [Solution](tasks/slowacki-backstage/solution.md) |
| [**Smog4Shell**](tasks/smog4shell/description.md) | `Real World` · `Pwn` | 🟠 Medium | [Solution](tasks/smog4shell/solution.md) |
| [**Ucieczka z pudełka**](tasks/ucieczka-z-pudelka/description.md) | `Pwn` · `Real World` | 🟠 Medium | [Solution](tasks/ucieczka-z-pudelka/solution.md) |
| [**Jeszcze bardziej lepszy AES++**](tasks/unresonably-better-aes/description.md) | `Crypto` | 🟠 Medium | [Solution](tasks/unresonably-better-aes/solution.md) |
| [**Kto, gdzie i kiedy ukrył stronę?**](tasks/who-where-when/description.md) | `Web` · `OSINT` | 🟠 Medium | [Solution](tasks/who-where-when/solution.md) |
| [**Wolontariusze**](tasks/wolontariusze/description.md) | `Reverse` · `Web` | 🟠 Medium | [Solution](tasks/wolontariusze/solution.md) |
| [**1-800-OGŁUSZENIE**](tasks/1-800-ogluszenie/description.md) | `Misc` | 🔴 Hard | [Solution](tasks/1-800-ogluszenie/solution.md) |
| [**Akta Wiktora Popiołka**](tasks/akta-wikipopa/description.md) | `Misc` · `Crypto` · `Reverse` | 🔴 Hard | [Solution](tasks/akta-wikipopa/solution.md) |
| [**Bibliotheca Jagellonica**](tasks/bibliotheca-jagellonica/description.md) | `Misc` · `Web` | 🔴 Hard | [Solution](tasks/bibliotheca-jagellonica/solution.md) |
| [**Dziwna wiadomość**](tasks/dziwna-wiadomosc/description.md) | `OSINT` | 🔴 Hard | [Solution](tasks/dziwna-wiadomosc/solution.md) |
| [**Unemployment is over party**](tasks/employment/description.md) | `Web` | 🔴 Hard | [Solution](tasks/employment/solution.md) |
| [**Machina Exitii**](tasks/machina-exitii/description.md) | `Misc` · `Pwn` · `Crypto` · `Web` | 🔴 Hard | [Solution](tasks/machina-exitii/solution.md) |
| [**rybulbol**](tasks/rybulbol/description.md) | `Games` · `Reverse` | 🔴 Hard | [Solution](tasks/rybulbol/solution.md) |

## Development
*Required only for running Hack4Krak Toolbox*

### 1. Download all required dependencies
This repository follows the layout defined by [Hack4Krak/TasksTemplate](https://github.com/Hack4Krak/TasksTemplate/). Visit it for the technical background, or browse the [`docs/`](docs/) directory.

| Path | What's inside |
| :--- | :--- |
| [`tasks/`](tasks/) | Configuration, source, tests & write-up for every task |
| [`config/`](config/) | Configuration for the specific CTF event (timeline, labels, deployments) |
| [`toolbox/`](toolbox/) | Our custom CLI for working with this repository |
| [`docs/`](docs/) | Documentation — [structure](docs/STRUCTURE.md), [testing](docs/TESTING.md) & [deployment](docs/DEPLOYMENT.md) |

Running the **Hack4Krak Toolbox** locally:

```shell
# 1. Download all required dependencies
uv sync

# 2. Run the CLI
uv run toolbox
```

### 2. Run CLI
```shell
uv run toolbox
```
Got questions about tasks, configuration, or deployment? Join our [Discord](https://discord.gg/ASPqckzEd8). We'll be happy to help.

## Credits

Tasks were made by the [Hack4Krak team](https://hack4krak.pl/about_us): [Norbiros](https://norbiros.dev), [wojpo](https://github.com/wojpo), [Goteusz](https://github.com/goteusz-maszyk), [Sanielia](https://sanielia.dev) & [P0m1d00r](https://github.com/P0m1d00r).

Huge thanks to them for grinding out all the tasks down to the very last second, and thank **you** for participating. See you next edition!
Binary file added docs/assets/score-progression.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion tasks/1-800-ogluszenie/solution.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ hack4KrakCTF{C4LL-1-800-H4K-7OW}
Organizatorom nie udało się rozwiązać tego zadania całkowicie autonomicznie z użyciem modeli językowych.
Jeśli Tobie się udało, koniecznie pochwal się tym na naszym Discordzie!

## Informacje dodatkowe
### Informacje dodatkowe

Główna piosenka: **Taco Hemingway - Wielkomiejska Bezsenność**

Expand Down
15 changes: 6 additions & 9 deletions tasks/900728/solution.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
## Opis
Zadanie to było typowym przykładem LSB (Least Significant Bit) steganografii, czyli ukrywania informacji w najmniej znaczących bitach danych.
W tym przypadku podanym plikiem było: 8bit mono audio.

Zadanie to było typowym przykładem LSB (Least Significant Bit) steganografii, czyli ukrywania informacji w najmniej znaczących bitach danych.
W tym przypadku otrzymaliśmy 8-bitowy plik audio mono.

## Rozwiązanie

```
```python
from wave import open

audio = open("../assets/900728.wav", "rb")
Expand All @@ -17,12 +17,9 @@ bits = []
for frame in frames:
bits.append(str(frame & 1))

textbits = ''.join(bits)
textbits = "".join(bits)

text = ''.join(
chr(int(textbits[i:i+8], 2))
for i in range(0, len(textbits), 8)
)
text = "".join(chr(int(textbits[i : i + 8], 2)) for i in range(0, len(textbits), 8))


flag = text.split("hack4KrakCTF{")[1].split("}")[0]
Expand All @@ -31,4 +28,4 @@ print(flag)

Program ten odczytuje dane z pliku audio, a następnie wyciąga najmniej znaczące bity z każdego bajtu danych. Następnie łączy te bity w ciąg tekstowy, który jest dzielony na znaki ASCII. Ostatecznie, program wyszukuje flagę w formacie `hack4KrakCTF{...}` i wypisuje jej zawartość.

flaga, którą otrzymujemy po uruchomieniu tego programu, to: `hack4KrakCTF{t4c0_0p4n0wal_h4ck4kr4k}`
Flaga, którą otrzymujemy po uruchomieniu tego programu, to: `hack4KrakCTF{t4c0_0p4n0wal_h4ck4kr4k}`.
79 changes: 59 additions & 20 deletions tasks/akta-wikipopa/solution.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,73 @@
## Opis

Ten task jest wieloetapowy, wykorzystuje zarówno metody kryptografii jak i reverse engineering.
To zadanie jest wieloetapowe. Wykorzystuje zarówno metody kryptograficzne, jak i reverse engineering.

Plik `WPA000001.pdf` zawiera zasłonięty tekst czarnym paskiem jednakże ten PDF nie został spłaszczony przez co można bez problemu wydobyć tekst pod spodem np. kopiując go - [realny błąd rządu USA](https://www.redactable.com/blog/redacted-epstein-files-here-is-what-went-wrong)
Plik `WPA000002.pdf` zawiera wiadomość zaszyfrowaną przy użyciu szyfru podstawieniowego.

Plik `WPA000002.pdf` używa homofonicznego szyfru podstawieniowego

Plik `WielkiBrat.zip` zawiera plik `exe` aplikacji winforms, który można zdekompilować praktycznie do natywnego C#
Archiwum `WielkiBrat.zip` zawiera aplikację WinForms skompilowaną dla platformy .NET, którą można stosunkowo łatwo zdekompilować i przeanalizować.

## Rozwiązanie

1. Zapoznajemy się z prawem z pliku `ThePrawo.pdf`
2. Wyciągamy id czynów zabronionych przestępstwa z pliku `WPA000001.pdf` - 3 i 7 - liczymy lata programem `WielkiBrat.exe` - 58936329 lat
3. Odszyfrowujemy tekst pliku `WPA000002.pdf` za pomocą [analizy frekwencyjnej](https://en.wikipedia.org/wiki/Frequency_analysis) - z tekstu id czynów zabronionych przestępstwa: 1 i 2 - `WielkiBrat.exe`: 86304100 lat
4. W plikach od `WPA000003.pdf` do `WPA000005.pdf` nie znajdują się żadne istotne informacje - zawierają jedynie zabawne obrazki. Dopiero w pliku `WPA000006.pdf` można znaleźć notatkę, z której wynika, że rozpatrywane przestępstwo obejmuje czyny zabronione 2, 3, 6 oraz 7.
5. Wiemy, że program nie potrafi obliczyć kary dla przestępstwa obejmującego więcej niż dwa czyny zabronione. Konieczne jest więc ustalenie formuły wykorzystywanej przez aplikację do wyznaczania kary dla większej liczby jednoczesnych czynów zabronionych.
6. Jeśli posiadamy doświadczenie z platformą .NET, możemy szybko rozpoznać, że aplikacja została napisana w technologii WinForms. Nawet bez takiej wiedzy można łatwo potwierdzić ten fakt przy użyciu narzędzia Binary Ninja. Pozwala to stwierdzić, że mamy do czynienia z aplikacją .NET.
7. Skoro wiemy, że aplikacja jest samodzielnym plikiem wykonywalnym opartym na .NET, możemy spróbować wyodrębnić zawarte w niej zasoby i biblioteki. W tym celu używamy narzędzia sfextract, które rozpakowuje plik do wielu komponentów, w tym głównej biblioteki .dll.
8. Następnie otwieramy wyodrębnioną bibliotekę .dll w narzędziu DotPeek od JetBrains. Ponieważ kod .NET można stosunkowo łatwo zdekompilować, uzyskujemy dostęp do pełnej logiki aplikacji zapisanej w bliskim do natywnego C#'ie. Analiza tego kodu pozwala odtworzyć formułę wykorzystywaną do obliczania kary.
9. Zauważamy, że opiera się na słowniku gdzie kluczem jest id a wartościa treść czynów zabronionych, oraz na obliczaniu sumy wartości ASCII wszystkich znaków z treści tych czynów.
10. Wyciągamy formułe `(słownik[id1]+slownik[id2])*(slownik[id1]+slownik[id2])` i stosujemy ją na przestępstwie z czterema czynami zabronionymi za pomocą prostego skryptu w pythonie, który wyglądał by mniej więcej tak:
```
### Przygotowanie

Zapoznajemy się z plikiem `ThePrawo.pdf`. Dowiadujemy się, że przestępstwo może składać się z kilku czynów zabronionych, jeżeli zostały wykonane w tym samym czasie. Długość kary możemy obliczyć programem `wielkiBrat.exe`, który nie jest jednak w stanie obsłużyć przestępstwa składającego się z więcej niż dwóch czynów zabronionych.

Dowiadujemy się również, że końcowa kara to iloczyn kar za wszystkie przestępstwa danej osoby.

### `WPA000001.pdf`

PDF został ocenzurowany, ale nie spłaszczony. Można więc skopiować treść dokumentu, wkleić ją w innym miejscu i normalnie przeczytać.

Naciskamy `Ctrl+A` i `Ctrl+C`, wklejamy treść i odczytujemy identyfikatory czynów zabronionych: 3 i 7. Obliczamy karę programem `WielkiBrat.exe` i otrzymujemy 58936329 lat.

### `WPA000002.pdf`

Odszyfrowujemy tekst pliku `WPA000002.pdf` za pomocą [analizy frekwencyjnej](https://en.wikipedia.org/wiki/Frequency_analysis)

Na podstawie częstości występowania znaków, powtarzalnych wzorców słów oraz kontekstu językowego (struktury zdań, nazw własnych i typowych wyrażeń urzędowych) odtworzono mapowanie alfabetu szyfrowego na litery języka polskiego.

Dzięki rekonstrukcji podstawień możliwe było stopniowe odszyfrowanie całego dokumentu oraz uzupełnienie brakujących fragmentów na podstawie kontekstu gramatycznego. Ostatecznie uzyskano pełną treść raportu sądowego dotyczącego działalności Wiktora Aleksandra Popiołka.

Z tekstu wynika, że sprawa dotyczy czynów zabronionych oznaczonych jako przestępstwo 1 i 2.

Program `WielkiBrat.exe` zwraca 86304100 lat.

### `WPA000003.pdf - WPA000005.pdf`

W plikach od `WPA000003.pdf` do `WPA000005.pdf` nie znajdują się żadne istotne informacje - zawierają jedynie zabawne obrazki.

### `WPA000006.pdf`

W pliku `WPA000006.pdf` odnajdujemy notatkę wskazującą, że rozpatrywane przestępstwo obejmuje czyny zabronione 1, 2, 6 oraz 7.

Z dokumentacji wynika, że program nie potrafi poprawnie obliczyć kary dla przestępstw obejmujących więcej niż dwa czyny jednocześnie, co sugeruje konieczność odtworzenia stosowanej przez aplikację formuły obliczeniowej dla większych zestawów czynów zabronionych.

Na podstawie analizy środowiska wykonawczego można ustalić, że aplikacja została napisana w technologii .NET (WinForms). Nawet bez bezpośredniej wiedzy programistycznej można to potwierdzić przy użyciu narzędzia `Binary Ninja`, które ujawnia strukturę aplikacji jako aplikację .NET.

W kolejnym kroku ekstraktujemy zawartość pliku wykonywalnego za pomocą narzędzia `sfextract`, uzyskując zestaw komponentów aplikacji, w tym główną bibliotekę `.dll`. Następnie analizujemy ją w narzędziu `JetBrains DotPeek`, które pozwala zdekompilować kod zarządzany .NET do czytelnej postaci zbliżonej do C#.

Analiza zdekompilowanej logiki wskazuje, że aplikacja korzysta ze słownika, w którym kluczem jest identyfikator czynu zabronionego, a wartością — jego opis. Kluczowym elementem obliczeń jest suma wartości ASCII wszystkich znaków w opisie danego czynu.

Na tej podstawie rekonstruujemy wzór używany do obliczania kary dla dwóch czynów: `(slownik[id1] + slownik[id2]) * (slownik[id1] + slownik[id2])`.

Następnie rozszerzamy go na przypadek czterech czynów i obliczamy wynik za pomocą prostego skryptu w Pythonie:

```python
slownik = (skopiowany slownik)

def ascii(n):
suma = 0
for i in n:
suma += ord(i)
return suma
print((ascii(slownik[1])+ascii(slownik[2])+ascii(slownik[6])+ascii(slownik[7]))**2)

print((ascii(slownik[1]) + ascii(slownik[2]) + ascii(slownik[6]) + ascii(slownik[7]))**2)
```
11. Wychodzi nam z tego - 415385161
12. Zatem flaga to: 415385161 * 86304100 * 58936329

Otrzymujemy `415385161`.

### Końcówka zadania

Wyliczyliśmy osobne wartości kar za wszystkie przestępstwa: `415385161`, `86304100` i `58936329`.

Następnie obliczamy iloczyn tych kar i otrzymujemy flagę: `2112834536082418221972900`.
6 changes: 5 additions & 1 deletion tasks/ankieta/solution.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## Opis

Zadanie polegało na wypełnieniu ankiety podsumowującej wydarzenie.

## Rozwiązanie

Tu chyba nie ma wiele do tłumaczenia, po prostu trzeba było wypełnić ankietę przed końcem czasu.
Należało wypełnić ankietę przed upływem wyznaczonego czasu.
Loading