OperationBreadcrumbs
π Operation Breadcrumbs
| Category | Author |
|---|---|
| π Web | The Cyber Mentor |
Challenge Prompt
Operation Breadcrumbs
Welcome, operator. Your flag is prepared on demand, straight from the TCM flag service.
Request your drop with the button below. When it arrives, submit it in the field underneath.
Flags follow the format TCM{β¦}. Good luck!
Problem Type
- Web
- OSINT
- Cryptography
Solve
We start out with a page showing a Download Flag button, but when we click it, we get a toast notification with:
1
2
3
β οΈ Something went wrong
The flag service is temporarily unavailable. Our team has been notified.
If we click the button with the Developer Tools open (F12), under the console tab, we see:
XHR GET https://ctf.tcmsecurity.com/api/flag
If we expand that, under the response headers there is a x-debug-trace header with
1
aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9NYWx3YXJlQ3ViZS9mYjA3NDM0YzFmYmEzYjkxNDNjYWU4ZjAxMzA5YTU3Zi9yYXcvNTk4MTRkMGY0MTU4MTMyNWJhZTVjODBiMGRlOTg0NDk2M2Q0NGI0Ny9mbGFnLXNlcnZpY2UtZGVidWctbm90ZXMubWQ=
Also, the status returned is 418 (Iβm a Teapot).
If we put that into CyberChef and use the from Base64 recipe, we get:
1
https://gist.githubusercontent.com/MalwareCube/fb07434c1fba3b9143cae8f01309a57f/raw/59814d0f41581325bae5c80b0de9844963d44b47/flag-service-debug-notes.md
Visiting that site gives us a note with:
1
2
3
4
5
6
7
8
# upload worker - queue stalls
worker keeps choking on the bulk import. the per-item debug dump sits on the
internal api:
/api/internal/ff9d9e38a38333145e46b49aa4a5f4b6?_=1718041920473&rid=7f3c9a2b1e&debug=1
grabbed that this morning, was useful. came back after lunch and it's 404.
of course it is. this is what I get for vibe-coding the whole thing...
If we attempt to go to the API link, as suggested in the note, we get a 404 error.
Next I took a look at the API url:
ff9d9e38a38333145e46b49aa4a5f4b6 this looked like a hash, so I went to Crack Station to check it.
This turned out to be a MD5 hash for IMG27. From there I checked the API against hashes from 1 to 100:
1
for i in $(seq 1 100); do hash=$(echo -n "IMG$i" | md5sum | cut -d' ' -f1); echo "IMG$i ($hash): "; curl -s "https://ctf.tcmsecurity.com/api/internal/$hash"; echo ""; sleep 1; done
All of those except IMG28 resulted in a 404:
1
2
IMG28 (ce148ab4b8a20f6d0005775ad6320ceb):
{"auth_payload":"H4sIAAAAAAAA/wTA7wqCMBAA8He5z6kthUiISiEiUIJGfz6JXtOGbRd6wzR6935fuHkyzTxJrbIQQ/05hdGlwcRMeXFY7cXiuJRVc72bfI6ijZKIREJTCDN46Z61bSCGJ/O7j4NgGAZ/JMeuUj6SCbYyzc4KXad53GH5UGbc9K4qkGytO1OyJrsW8PsHAAD//71EzlGFAAAA","service":"image-processor","status":"ok"}
Back to CyberChef and this time I used the magic recipe to determine this was both From Base64 and Gunzip:
1
{"X-TCM-Token":"fxP34VgcBmzN_H9F12J7TbgWYmN0c1k4B4o1Boz3","listing":"https://www.youtube.com/@TCMSecurityAcademy?sub_confirmation=1"}
I visited the YouTube page and in the links near the header there was a link called BREADCRUMB.
This link directed us to https://ctf.tcmsecurity.com/tcm-prod-media/4ee5f8ff6d6a23deb9d829479b54c8e3.jpg
Which displayed an XML error page:
1
2
3
4
5
6
7
8
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>9F3A2C1D7E4B8A60</RequestId>
<HostId>
Uf3pK2mWqL8xY1nZ7bV4tR6sD0gH5jC9aE2oP1iM3kS8wB7vN4xQ6lT0yU2rA1c=
</HostId>
</Error>
Next I used curl to send the X-TCM-Token header and used -o to download the file:
1
2
3
4
5
curl https://ctf.tcmsecurity.com/tcm-prod-media/4ee5f8ff6d6a23deb9d829479b54c8e3.jpg \
-H "X-TCM-Token: fxP34VgcBmzN_H9F12J7TbgWYmN0c1k4B4o1Boz3" -o image.jpg
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 627.4k 0 627.4k 0 0 650.0k 0 0
Once I had the image I opened it up and saw that it was some leaves against a plain background:
I ran exiftool against it and found it had coordinates in the output:
1
2
3
GPS Latitude : 34 deg 8' 2.76" N
GPS Longitude : 118 deg 19' 17.40" W
GPS Position : 34 deg 8' 2.76" N, 118 deg 19' 17.40" W
I put this location into CalTopo and saw it was in Hollywood, CA:
Next I checked to see if it was really a JPG, and it was not:
1
2
file image.jpg
image.jpg: Zip archive, with extra data prepended
I renamed the file to a ZIP:
1
mv image.jpg image.zip
Then I unzipped the file revealing flag.xor:
1
2
3
4
5
unzip image.zip
Archive: image.zip
warning [image.zip]: 642481 extra bytes at beginning or within zipfile
(attempting to process anyway)
inflating: flag.xor
Back to CyberChef and I added the flag.xor file and then used the XOR operation with the key HOLLYWOOD to reveal the flag:
Alterative Solve
Since we know the flag starts with TCM{ we can try a known plaintext attack.
1
2
3
4
5
6
7
8
9
10
with open('flag.xor', 'rb') as f:
ciphertext = f.read()
known_plaintext = b"TCM{"
key_prefix = bytearray()
for i in range(len(known_plaintext)):
key_prefix.append(ciphertext[i] ^ known_plaintext[i])
print(f"[*] The first 4 characters of the key are: {key_prefix}")
This gives us that the first 4 characters are HOLL. Then we can use the Websterβs Dictionary to find words that start with HOLL. We could also use a file like rockyou.txt to do this too. We pick some words in that list that we think might be the key:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
with open('flag.xor', 'rb') as f:
ciphertext = f.read()
key = b"HOLL"
decrypted = bytearray([ciphertext[i] ^ key[i % len(key)] for i in range(len(ciphertext))])
print(f"[*] Testing exact 4-byte key 'HOLL': {decrypted}\n")
key = b"HOLLY"
decrypted = bytearray([ciphertext[i] ^ key[i % len(key)] for i in range(len(ciphertext))])
print(f"[*] Testing exact 4-byte key 'HOLL': {decrypted}\n")
key = b"HOLLYWOOD"
decrypted = bytearray([ciphertext[i] ^ key[i % len(key)] for i in range(len(ciphertext))])
print(f"[*] Testing exact 4-byte key 'HOLL': {decrypted}\n")
key = b"HOLLAND"
decrypted = bytearray([ciphertext[i] ^ key[i % len(key)] for i in range(len(ciphertext))])
print(f"[*] Testing exact 4-byte key 'HOLL': {decrypted}\n")
key = b"HOLLOW"
decrypted = bytearray([ciphertext[i] ^ key[i % len(key)] for i in range(len(ciphertext))])
print(f"[*] Testing exact 4-byte key 'HOLL': {decrypted}\n")
Flag
TCM{WH3R3_DR34M5_ARE_M4D3}