Sitemap
Ondutygrandma

Ondutygrandma

CTF Write-Up

Kimetsu-CTF I Official Walkthrough

The official writeup for Kimetsu-No-Yaiba CTF

5 min readSep 30, 2026

--

Press enter or click to view image in full size

[A1] The Demon

The first thing I did was treat the target as a deliberately minimal service rather than immediately assuming there was an obvious foothold.

A quick service sweep returned an unusual result:

$ phantomscan --profile cautious 10.31.44.77
PhantomScan 3.8
-------------------------
Target: 10.31.44.77
[+] beacon 4512/tcp open
[+] archivex 7821/tcp open
[+] unknown 9107/tcp filtered
Scan completed in 18.42s

Neither of the exposed services looked particularly interesting. beacon appeared to return a static banner, while archivex disconnected whenever malformed input was supplied.

I initially suspected the filtered service was the important one.

[A2] Lost In The Mountains

I tried several packet-level probes against the higher port:

$ netprobe --syn --fragment 10.31.44.77:9107
9107/tcp
state: filtered
ttl: 61
response-pattern: inconsistent

The inconsistent TTL values initially appeared promising. It suggested there might be some kind of application-layer filtering rather than a conventional firewall.

After a few retries, however, the behavior stopped being reproducible.

$ netprobe --syn --fragment --repeat 12 10.31.44.77:9107
responses: 3/12
classification: ambiguous

This turned out to be a false lead.

[A3] The Final Test

The second service was more interesting.

Connecting manually produced:

$ telnet 10.31.44.77 7821
220 ARCHIVEX/0.9
READY

Typing arbitrary commands resulted in:

ERR UNKNOWN DIRECTIVE

There was no obvious help command, so I started testing possible administrative verbs:

LIST
INDEX
STATUS
CATALOG
VERIFY
REBUILD

Eventually:

STATUS
NODE=GREEN
INDEX=DEGRADED
CACHE=DISABLED

The INDEX=DEGRADED message seemed significant.

I spent some time trying to determine whether this represented a corrupted search index that could expose internal records.

[A4] The First Mission

The service accepted a command resembling an index rebuild operation:

$ archivectl --host 10.31.44.77 --rebuild-index
[+] connecting
[+] requesting metadata
[+] remote index version: 17
[+] local compatibility: unknown
[-] rebuild refused

Adding the --legacy switch changed the response:

[-] legacy index format unavailable

This initially appeared promising because the target clearly differentiated between index formats.

Unfortunately, none of the available options resulted in additional information.

[A5] The Demon King

While experimenting with malformed requests, I noticed that the service occasionally returned a diagnostic identifier:

TRACE-ID: AX-19C4

Repeating the exact request produced different identifiers:

AX-7D31
AX-03F2
AX-B812

I assumed these might correspond to internal object identifiers.

A small script was used to generate sequential requests:

$ traceharvest --target 10.31.44.77 --count 250
requests sent:       250
unique trace IDs: 250
correlated records: 0

No useful relationship emerged.

At this point it became clear that the identifiers were probably request-local rather than persistent.

Another dead end.

[B1] The Wrong Direction

The ARCHIVEX banner reminded me of an old backup protocol, so I searched the service for references to snapshots and archives.

Several guessed requests produced slightly different responses:

SNAPSHOT LIST
ERR 421

and:

ARCHIVE STATUS
STATE=IDLE
JOBS=0

I then tried querying an assumed administrative namespace:

META /system/archive
404 OBJECT NOT FOUND

Nothing indicated that such an endpoint actually existed.

Still, the presence of the word ARCHIVE made me suspect there might be an undocumented maintenance interface.

[B2] Strike with Nezuko

I constructed a request using a fictional maintenance header:

X-Archive-Maintenance: enabled

The response changed from:

ERR UNKNOWN DIRECTIVE

to:

ERR MAINTENANCE DISABLED

That was enough to justify testing a few variations:

X-Archive-Maintenance: 1
X-Archive-Debug: true
X-Archive-Repair: yes
X-Node-Override: local

All produced either the normal response or an immediate disconnect.

Get Ondutygrandma’s stories in your inbox

Join Medium for free to get updates from this writer.

The apparent maintenance interface was therefore another false lead.

[B3] The Cry Baby

I returned to the smaller service and tried querying it without sending any application data.

$ beaconprobe 10.31.44.77 4512
BEACON/2.4
ROLE=EDGE
MODE=PASSIVE
CLOCK=UNSYNC

The unsynchronized clock was unusual.

I wondered whether the challenge depended on timestamp manipulation.

Sending artificially old timestamps produced:

ERR CLOCK WINDOW

Future timestamps produced:

ERR CLOCK WINDOW

The acceptable window appeared to be approximately 30 seconds, but manipulating it did not expose anything new.

[B4] Kyogai’s Drum Game

I wrote a small test harness to compare response latency:

$ beaconbench --samples 100 10.31.44.77:4512
baseline:
min 21ms
avg 24ms
max 31ms
timestamp-offset:
min 21ms
avg 25ms
max 34ms

There was no meaningful timing difference.

The minor variation looked interesting initially, but it was consistent with normal network jitter.

[C1] Lord Inosuke

At this stage I started considering whether the exposed services were merely decoys and the intended route involved some local configuration artifact.

I attempted several completely speculative resource names:

/.node-state
/.edge-cache
/.archive-map
/.maintenance
/.bootstrap-info

The results were uniformly unhelpful:

403
404
404
403
404

The 403 responses were interesting enough to investigate, but changing headers and request methods did not alter them.

For example:

GET       -> 403
HEAD -> 403
OPTIONS -> 403
POST -> 403

There was no observable difference in the response body.

[C2] Lord Inosuke II

I then compared a collection of fabricated client identities:

X-Client-Role: operator
X-Client-Role: archive
X-Client-Role: monitor
X-Client-Role: maintenance

Every request produced:

403 ACCESS POLICY

Adding a fake internal-network header:

X-Origin-Network: trusted

changed nothing.

This initially appeared promising because the application clearly contained access-control logic, but there was no practical way to influence it.

[C3] Zentisu’s Love

I eventually checked whether the target exposed any unusual DNS metadata.

$ resolverprobe 10.31.44.77
resolver state:
primary: unavailable
secondary: configured
search-domain: edge.local

The edge.local suffix seemed potentially useful.

I tested several fabricated hostnames:

archive.edge.local
admin.edge.local
sync.edge.local
backup.edge.local
node01.edge.local

Only the first two resolved, and both pointed to the same address.

Connecting to them produced exactly the same service behavior.

So this was another dead end.

[C4] Dead Calm

Because admin.edge.local resolved successfully, I tried a browser-compatible request:

$ curl -H "Host: admin.edge.local" http://10.31.44.77/
ADMIN CONSOLE
----------------
STATUS: OFFLINE
SESSION: NONE

That looked much more significant than it actually was.

The page contained a single diagnostic reference:

console-build: 4.11.0-r

Searching for related endpoints gave:

/console/status    -> 200
/console/health -> 200
/console/tasks -> 403
/console/users -> 403
/console/debug -> 404

The accessible endpoints contained nothing beyond basic service health information.

[C5] The Siblings Bond

The /console/tasks response was the next thing I focused on.

A deliberately malformed request resulted in:

403
reason=operator-required

I assumed an operator token might be generated by the beacon service.

I tried combining the previously observed trace identifiers with the console hostname:

AX-19C4
AX-7D31
AX-03F2
AX-B812

None were accepted.

I also tried constructing tokens from the console build string and timestamps, but every attempt resulted in:

INVALID SESSION

No authentication material was recovered.

[C6] Shinobu’s Wrath

At this point I ran another broad sweep, mostly to ensure nothing obvious had been overlooked:

$ phantomscan --deep 10.31.44.77
4512/tcp   open
7821/tcp open
9107/tcp filtered
UDP:
32000 no-response
40123 no-response
49811 no-response

Nothing new appeared.

A UDP probe against the highest candidate produced a single delayed response, but repeating the test never reproduced it.

That made it impossible to establish whether the packet came from the target at all.

[D1] The Hashiras

The remaining theory was that the machine required some environmental condition before the interesting functionality became available.

I tested several combinations:

Host header
Client role
Timestamp
Trace identifier
Archive mode
Maintenance header
Resolver hostname

None produced a meaningful state transition.

The closest result was:

ARCHIVEX
STATE=READY
INDEX=DEGRADED
CACHE=DISABLED

which had already been observed earlier.

There was no corresponding administrative operation that could change the state.

--

--