The Raven That Landed Twice challenge introduction

OSINT is my happy place. Thank you to all my fellow early 2Ks lesbians for teaching one another how to properly research.

Aircraft Registry

Challenge identifiers showing Mode-S 43E91C and callsign VLR602

The challenge started with two identifiers:

  • Mode-S hex: 43E91C
  • Callsign: VLR602

The Mode-S value looked like an Aircraft Registry key. The callsign sounded more ledger-appropriate.

The challenge application showing its record-system tabs

The in-browser view was above. I started with 43E91C.

No need to search. Aircraft Registry was one of the tabs.

Aircraft Registry tab opened for Mode-S 43E91C

Aha! A movement record at the bottom of the window.

Aircraft Registry record connecting Mode-S, registration, callsign, owner, and operator

Initial identity chain:

43E91C -> 2-RUNE -> VLR602

Surmised so far: the challenge wants us to ID the operator. Black Keep Leasing SPC definitely held the aircraft title, and Vaultrune Air Services Ltd operated the flight.

Movement History

Let's check the Movement History.

Movement History tab for VLR602

Only one entry.

Single Movement History result for VLR602

The Movement History for VLR602 contained an important entry:

Movement record showing VLR602 route, arrival time, stand, registration, and handler

We now know it's not two aircraft.

Here's what could be established from the Movement Record:

  • Callsign: VLR602
  • Registration: 2-RUNE
  • Mode-S: 43E91C
  • Route: SCF > CSE
  • Landed at 00:47
  • Parked at Stand 4B at 00:51
  • Ground handler: Crownspire Crown Aviation Services

Courier Mail

Let's check Courier Mail for VLR602.

Courier Mail search results for VLR602

Three new messages. Hmm...

Stand 4B carriage release... came from dispatch@crownaviation.val. The stand and sender matched the Movement History.

Bonus points: it had an attachment.

Stand 4B carriage release email with its attachment

Here's the attachment.

Airside carriage release filed under registration 2-RUNE

The attached airside release broke down the discordance.

The flight record used callsign VLR602. The carriage ledger used registration 2-RUNE.

The remaining details, however, still aligned:

  • Arrival at 00:47
  • On-block at 00:51
  • Stand 4B
  • Carriage CS-19
  • The same court order

The aligned time, stand, carriage, handler, and court order followed instructions to separate the aircraft's identities across systems.

Stand 4B was tagged as evidence, and I continued through the mailbox.

Let's check Fuel Uplift Billing.

Fuel uplift billing message with the matching carriage reference

The reference was identical to the airside release. Tagged it, then opened the gate log:

Gate log recording the physical handoff at Stand 4B

The gate record shed light on the physical handoff:

  • 00:51: aircraft on-block with the gate open at Stand 4B
  • Carriage CS-19, matching the dispatch attachment
  • Ledger signed under the registration

Courier Mail correlated the flight-side callsign to the ground-side registration using the same time, place, carriage, handler, and release process.

Skyglass Browser

We still needed to know who publicly used the flight.

Skyglass Browser opened in the challenge application Skyglass Browser search interface

Let's search for VLR602.

Skyglass search for callsign VLR602 Skyglass result connecting VLR602 to registration 2-RUNE

The first result confirmed that VLR602 ties to 2-RUNE in public-facing data. Ownership and departure remain unsolved mysteries.

Evidence Satchel

I opened the Evidence Satchel to see which findings remained unsupported.

Evidence Satchel opened after the record searches Evidence Satchel showing Registration, Operator, and Departure still missing

Aha! Registration, Operator, and Departure were still missing.

Re-examining the Registry and Movement Ledger unearthed that the evidence already contained the missing answers:

  • The Aircraft Registry correlated 43E91C to registration 2-RUNE.
  • The Registry distinguished Black Keep Leasing SPC from the operator on-record, Vaultrune Air Services Ltd.
  • The Movement Ledger recorded departure airport SCF.
  • The linked records all pointed to Stand 4B.

Back to the VLR602 Movement Ledger to tag Registration and Departure.

Hopefully we can collect the human Operator in the Registry. We're so close.

Registry evidence selected for the operator finding

Let's tag 'em, boys.

Movement evidence selected for registration and departure

Oath Submission

Back to Oath Submission.

Oath Submission showing the first supported finding Oath Submission showing another supported finding

And the last one.

Oath Submission ready for the Stand finding

4B.

Stand 4B submitted as the final finding

Click Evidence Review.

Evidence Review showing all four findings confirmed and the case complete

All four findings were accepted.

All findings confirmed. Case complete.

No flag.

The Missing Flag

I duplicated the challenge in Firefox. Dev Tools > Network > XHR > hard refresh.

Firefox Network panel after refreshing the completed challenge

Either HTB had designed a grandiose flag presentation, or I had opened a different challenge asset.

Network response belonging to the AWS or False Ferry challenge

It was the latter. AWS/False Ferry challenge.

Let's respawn.

The challenge still wouldn't give up the flag. I completed the case again, then ran this in the Firefox console. The completion message gave me a place to start:

fetch("/assets/index-dOxwAnh8.js")
  .then(r => r.text())
  .then(t => {
    const i = t.indexOf("All findings confirmed. Case complete.");
    console.log("position:", i, t.slice(i - 1500, i + 3000));
  })
Firefox console locating the challenge completion code in the Vite bundle

No flag yet. The client stored progress under:

court-eaves-progress-v1

Completion did not initiate an XHR or fetch request. The browser updated its local state, furnished the completion message, and the buck stopped here.

In a final attempt to secure the flag, I searched a bundle of the source code:

fetch("/assets/index-dOxwAnh8.js")
  .then(r => r.text())
  .then(t => {
    const app = t.slice(190000);
    console.log("bundle length:", t.length);
    for (const term of ["HTB", "flag", "atob", "btoa", "base64", "clipboard"]) {
      console.log(term, [...app.matchAll(new RegExp(term, "gi"))]
        .map(m => m.index + 190000));
    }
  })
Bundle search results showing clipboard as the only non-empty hit

Nothing. No HTB, flag, Base64, atob, or btoa. clipboard was the only hit.

I inspected it:

fetch("/assets/index-dOxwAnh8.js")
  .then(r => r.text())
  .then(t => console.log(t.slice(213700, 214900)))
Clipboard function copying ordinary evidence values rather than a flag

The function copied evidence values. No flag.

All four findings were accepted. The client made no flag request, and no flag appeared. I reproduced it on a fresh Docker and sent the screenshots and browser findings to HTB.

Attribution

I completed and documented this investigation during Hack The Box Cyber Apocalypse 2026 as a member of the CIAT Cybersecurity Club team.

I used AI to organize evidence, work through the client-side behavior, and draft the HTB report. I ran the challenge, selected and submitted the findings, reproduced the missing flag, collected the evidence, and handled communication with HTB.