以下の内容はhttps://yocchin.hatenablog.com/entry/2026/02/09/082145より取得しました。


Pragyan CTF 2026 Writeup

この大会は2026/2/6 22:00(JST)~2026/2/8 22:00(JST)に開催されました。
今回もチームで参戦。結果は1250点で893チーム中125位でした。
自分で解けた問題をWriteupとして書いておきます。

Sanity Check (SanityCheck)

Discordに入り、#rulesチャネルでリアクションすると、たくさんのチャネルが現れた。
#primary-announcementsチャネルのメッセージにフラグが書いてあった。

p_ctf{WELCOMe7Opr@GY4N}

Lost in the Haze (misc)

OSINT問題で、問題文はこうなっている。

I remember stepping outside for a moment. The air felt heavy, the lights too bright, the streets unfamiliar.

All I know is that this location has a name.

Flag Format p_ctf{ward_name}

添付の画像は次の通り。

画像検索すると、以下のページに近い画像が見つかる。
https://kiji.life/vending-machine-in-japan/

この写真より前の文章を翻訳すると、どうやら場所は秋葉原らしいので、千代田区であることがわかる。

p_ctf{chiyoda}

R0tnoT13 (crypto)

問題文はこうなっている。

During a security audit of a custom cryptographic module, you obtain partial diagnostic logs from a faulty randomness subsystem.

The subsystem maintains an internal 128-bit state derived from AES, which is periodically 
inspected for integrity using bit-rotation consistency checks.

For specific, preconfigured rotation offsets k, the firmware records the value:

S ⊕ ROTR(S, k)

where S is the internal state at that time. 
These checks are intended only to verify hardware wiring correctness and were never meant to be exposed.

Due to a logging misconfiguration, only a small subset of these diagnostic frames was captured before the system crashed.

Given:

-Several leaked diagnostic frames of the form S ⊕ ROTR(S, k)

-The corresponding rotation offsets k

-Two anchor bits of the internal state

-A ciphertext encrypted using the internal state

Reconstruct the state and recover the flag.

challege.txtを見ると、ログはこうなっている。

== States ==
8 183552667878302390742187834892988820241
4 303499033263465715696839767032360064630
16 206844958160238142919064580247611979450
2 163378902990129536295589118329764595602
64 105702179473185502572235663113526159091
32 230156190944614555973250270591375837085

kのべき乗回転がすべてそろっている。アンカービットは不明だが、可能性があるビットは4パターンのみなので、ブルートフォースで復号する。

#!/usr/bin/env python3
from itertools import product

T = {
    2: 163378902990129536295589118329764595602,
    4: 303499033263465715696839767032360064630,
    8: 183552667878302390742187834892988820241,
    16: 206844958160238142919064580247611979450,
    32: 230156190944614555973250270591375837085,
    64: 105702179473185502572235663113526159091
}

def bits(x):
    return [(x >> i) & 1 for i in range(128)]

Tbits = {k: bits(v) for k, v in T.items()}

S = [None] * 128

S[0] = 0
for i in range(0,128,2):
    for k in Tbits:
        j = (i + k) % 128
        if j % 2 == 0:
            S[j] = S[i] ^ Tbits[k][i]

S[1] = 0
for i in range(1,128,2):
    for k in Tbits:
        j = (i + k) % 128
        if j % 2 == 1:
            S[j] = S[i] ^ Tbits[k][i]

cipher = bytes.fromhex("477eb79b46ef667f16ddd94ca933c7c0")

for even_base, odd_base in product([0, 1], [0, 1]):
    Sb = S[:]
    for i in range(128):
        if i % 2 == 0:
            Sb[i] ^= even_base
        else:
            Sb[i] ^= odd_base

    key = int("".join(map(str, Sb[::-1])), 2).to_bytes(16, "big")
    flag = bytes(a ^ b for a, b in zip(cipher, key))

    if b"{" in flag and all(32 <= c < 127 for c in flag):
        flag = flag.decode()
        print(flag)
        break
p_ctf{l1nyrl34k}



以上の内容はhttps://yocchin.hatenablog.com/entry/2026/02/09/082145より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14