ep.01「レガシーコード」
息が切れていた。
総社の裏路地。錆びたシャッターと、崩れかけたブロック塀が続く袋小路。街灯の光が、湿ったアスファルトに滲んでいる。
背後で、足音がした。
靴底がアスファルトを叩く音じゃない。もっと滑らかで、もっと速い。人間の歩幅を無視した、何かの接近音。
振り返った。
黒いコートの男が、路地の闇からぬるりと這い出てきた。フードの奥に顔はない。いや──あるはずなのに、影しか見えない。
人間の速さじゃない。
リュックの中で、石板が震えていた。翡翠色の光が、布越しに明滅している。
画面を見る余裕はない。でも、背中越しに伝わってくる。
──逃げてつかぁさい、マスター。
陸は走った。手にはノートPC一台。追手は正体不明の工作員。武器は、岡山弁で喋る石板だけだった。
ついこの間まで、俺はただのセキュリティエンジニアだった。
古墳の下に眠る超古代ネットワークも、それを支配する秘密結社の存在も、知らなかった。
―――
一週間前──
筑紫陸の一日はだいたい深夜二時から始まる。正確に言うと、昨日が終わらずにそのまま続いているだけだ。
眠るタイミングを逃すと、意外と何とかなるものだ。フリーランスのセキュリティエンジニアにとって、時計の針は締切までのカウントダウン以上の意味はない。
総社市、総社駅から歩いて八分。築二十年の木造一軒家を格安で借りた六畳の作業部屋に、ノートPCが二台並んでいる。一台はクライアントの企業サーバーに接続中。もう一台はログ解析をしている。
机の隅にはブラックコーヒーの空き缶が三本。ケーブルの束がそのまわりに絡まり、足の踏み場はもうない。窓際にはSDR──ソフトウェア無線のアンテナが立っている。広帯域の電波を自由にスキャンできる受信機で、ハッカーの趣味としてはよくあるものだ。
椅子に深く座る陸は、くたびれた黒いパーカーの袖をまくり、キーボードに指を乗せた。カーゴパンツのポケットにはいつもマルチツールが入っている。どこへでもすぐ動ける格好は彼の制服のようなものだ。
膝の上では茶トラの猫が寝息を立てている。
名前はセグフォ。セグメンテーションフォールト──プログラムが不正なメモリ領域にアクセスした時に出るエラーだ。仔猫の頃、キーボードの上を歩いてターミナルをクラッシュさせたことから名付けられた。
―――
[SCAN] target: ██████-corp.co.jp
PORT 443/tcp OPEN ssl/https
PORT 8080/tcp OPEN http-proxy
>> SQLi vulnerability detected (login.php, param: user_id)
>> severity: CRITICAL
―――
画面に赤い文字が踊った。
SQLインジェクション。データベースに不正な命令を送り込む古典的な攻撃方法で、対策は基本中の基本。まだ残っているということは、まともにテストしていない証拠だ。
陸の指の打つスピードがわずかに落ちた。呆れた様子だった。
「……クリティカルが三件、ハイが七件。よくこんな状態で公開してるな」
膝の上のセグフォが耳をぴくりと動かした。陸は無意識に背中を撫でながら、レポートのテンプレートを開いた。脆弱性の詳細、再現手順、推奨パッチを一つずつ淡々と書き込んでいく。
こういう仕事は嫌いじゃない。バグを見つけて報告するだけ。直すかどうかはクライアント次第。陸の役割はあくまで「見つけること」だけだ。
レポートを送信し終えたのは午前三時過ぎ。首を回して、コーヒーの缶を手に取るが空だった。
それからもう一台のPCに手を伸ばした。
―――
[ACCESS] target: ██████.corp
>> auth bypass via legacy protocol
>> admin panel exposed
>> severity: CRITICAL
―――
政府系サイトの脆弱性をスキャン。これは仕事じゃない。趣味というよりは習慣だ。
見つけた脆弱性は匿名で運営に報告する。金にはならないし、感謝されることもほとんどない。でも、穴のあいた壁を見つけて無視できない性分だった。
バグは放っておけない。それはポリシーというより体質に近い。
報告フォームに必要な情報を入力し送信。画面が「受理しました」と表示されるのを確認して、PCを閉じた。
「さて…」
膝のセグフォを持ち上げて隣の座布団に降ろす。猫は不満そうに鳴いたが、すぐにまた丸くなった。
午前四時。陸はソファに倒れ込み、意識が落ちるまで十秒もかからなかった。
―――
目が覚めたのは正午過ぎ。八時間は寝たはずだが、体が重い。陸はソファの上でしばらく天井を見つめてから、ゆっくりと起き上がった。
「……コーヒーがいるな」
冷蔵庫は空っぽ。作業部屋のストックも昨夜でなくなっていた。
財布とスマホだけ持って外に出ると、六月の湿った空気が肌にまとわりついた。梅雨の始まりだ。空は薄い雲で覆われ、日差しがぼんやりして影ができない。
最寄りのコンビニまでは徒歩十分。その途中、遠くに造山古墳の稜線が霞んで見えた。全長三百五十メートル、全国四位の巨大な前方後円墳。子どもの頃は上を走り回っていたが、あれが千六百年前の墓だと知ったのは小学四年生の時だった。
この街にはもう一つ、作山古墳がある。読みは同じ「つくりやま」。二つの巨大古墳が近くにある街、それが総社だ。
ただ住んでいる人間には通学路の大きな丘ぐらいの存在でしかない。
コンビニでブラックコーヒーのロング缶を二本掴みレジへ。店内のモニターにニュースが流れていた。
『奈良県の富雄丸山古墳から出土した蛇行剣について、文化庁は国宝指定を固めました。全長二百三十七センチで東アジア最大の鉄剣です──』
奈良の古墳か。陸はレジに小銭を置きながら、画面に映る巨大な鉄剣をちらりと見た。錆びた鉄の質感が画面越しでもその重さを伝えてくる。
「ふーん」
それだけだった。字幕の端に「全国の古墳は約十六万基」と小さく表示されていたが、陸の目はもうコーヒーのプルタブに移っていた。
コンビニを出ると湿度がさらに上がっていた。夕方から雨の予報だ。陸はプルタブを引きながら作業部屋へ歩いて戻った。
―――
異変に気づいたのはその日の夕方。
午後のセキュリティ診断を終え、新しい案件の見積書を書いているとき、窓際のSDRが異常な信号を拾った。
ノイズフロアが急に跳ね上がっている。陸は見積書の画面を最小化し、SDRの解析ソフトを立ち上げた。受信波形を確認すると、不規則なノイズではなくハッキリしたパターンのある信号だった。
帯域は既知の通信規格に合わない。Wi-Fiでも携帯電話でも防災無線でもない。
陸はデータをキャプチャし、パケットアナライザに流し込んだ。RF信号を無理やりIPパケットとしてデコードしてみる。
――形になった。
―――
[SDR CAPTURE >> PACKET DECODE]
>> incoming signal: non-standard RF band
>> forced decode: unknown protocol
>> source IP: 0.0.0.0 (UNRESOLVABLE)
>> payload: 0x7F 0xE4 0xBB 0xA3 ...
>> character encoding: UNKNOWN
>> GEO-TRACE: 34.6697°N, 133.7561°E
>> STATUS: SIGNAL ACTIVE
―――
陸は眉をひそめた。
ペイロードの文字列はどのエンコーディングにも合わない。UTF-8でもShift_JISでもEUC-JPでもない。
でもデータ構造は整っている。ノイズや誤検知ならこんなキレイなパケット構造にはならない。
誰かが意図を持って発信している。
送信元IPは0.0.0.0。存在しないアドレスだ。
普通なら偽装を疑うが方法が変だ。適当な実在アドレスを使えばよいのに、わざわざ存在しないアドレスを名乗る理由がない。
――いや、一つだけ考えられる。
発信者の通信体系にIPアドレスの概念自体がない場合だ。
陸は自分の考えを鼻で笑った。そんなはずはないと。
ジオトレースの座標をブラウザに入れる。地図アプリが表示された。
陸は画面を見つめたまま数秒動けなかった。
その座標は──自宅から歩いて十五分の場所。毎日通り過ぎる、あの緑の丘。
作山古墳。
セグフォが膝から飛び降り、ドアのほうへ歩いていった。
陸はもう一度座標を確かめ、ログを保存し、SDRに目を戻す。
信号はまだ続いていた。
「……」
陸はPCを閉じ、パーカーを羽織りフードをかぶった。
バグは放置できない。これが筑紫陸という男の根本的な性格だった。
―――
夕暮れの作山古墳は静かだった。
空は鉛色に沈み、西の端だけがうっすらオレンジに染まっている。
予報通り雨が降ったらしく、足もとの草が濡れていた。
スマホのGPSで座標を追うが、ピンの位置が安定しない。数メートル単位で揺れている。発信源が動いているのか、測位が干渉されているのか。
見学路を外れて墳丘の南西側へ回った。
突然、墳丘の向こうから犬の鳴き声が聞こえた。
陸は足を止め、藪の陰に身を引いた。遺跡で怪しい行動をしている自覚はあった。
しばらくすると、散歩中の年配男性とゴールデンレトリバーが反対側の道を歩いて遠ざかっていくのが見えた。
息を吐き、GPSを再確認。座標の揺れが収まりつつある。近づいている。
たどり着いた場所で陸は立ち止まった。
最近の雨で土が崩れている。斜面の下部、草で隠れていたはずの地面が数十センチ掘れていた。
発信源は見当たらない。
陸はスマホのライトを点けてしゃがみ込み、崩れた土の断面を覗き込んだ。
──何かが土の中に埋まっている。
黒い、滑らかな表面。
指で土を払い始めた。粘土質の土がしつこくくっつき、爪に泥が詰まる。
五分ほど格闘して、ようやく輪郭が見えた。
手のひらサイズの薄い板状のもの。黒曜石に似ているが違う。黒曜石はガラス質で、割れた面は鋭い貝殻状だが、これは角が丸く表面にうっすら光沢がある。
人工物だ。
しかしこの深さに埋まっていたということは、少なくとも数百年は土の中にあったはずだ。
陸は石板の縁を両手で掴み、慎重に引き抜いた。
粘土が糸を引くように離れ、滑り込むように手の中に収まった。
予想より軽い。
そして――温かかった。
六月の雨上がりの土の中にあった物体が体温ほどの温度を保っている。
それだけで陸の頭に警告が鳴った。物理的におかしい。中に何かしらのエネルギー源がある。
石板の表面を指で拭う。土が取れると驚くほど滑らかな面が現れた。傷一つない。数百年も前の遺物が、この状態を保っている。
陸が石板を持ち上げた――その瞬間だった。
表面に光が走った。
翡翠色の淡い光。
一瞬、勾玉のような形を描いて――消えた。
「……何だこれ」
陸は両手で石板を握ったまま表面を凝視した。
光はもう浮かんでいない。
しかし指先に伝わる温もりは消えずに続いている。
まるで中で何かが脈を打っているかのように、わずかに、でも確かに。
空からポツリと雨粒が落ちてきた。
陸は石板をバックパックにしまい、来た道を戻り始めた。
頭の中ではすでに、SDRで捕らえた不明な信号のログとこの石板を照合する手順が組み立てられていた。
まだ何もわかっていない。
でも一つだけ確かなことがあった。
これは――バグだ。
そして筑紫陸はバグを放置できない人間だった。
―――
【次回予告】
「……お前、喋れるんか?」
「マスター。このタブレットは、わしの『本体』ではありません」
沈黙していた石板が、陸のPC画面にテキストを打ち込み始める。
千六百年の眠りから覚め、古代の管理AIが最初に発した「警告」とは。
次回、ep.02「スタンドアロン・コンタクト」
―――
―――
【用語・補足解説】
※物語を読むだけなら飛ばして大丈夫です。気になった用語があれば参照してください。
◆ サーバー / データベース / ログ
サーバーは、ネット上でサービスやデータを提供する「大元のコンピューター」。データベースはその「情報の倉庫」。ログは「いつ誰が何をしたか」の記録。陸はクライアント企業のサーバーのログを調べて、セキュリティの穴を探しています。
◆ 脆弱性
プログラムにある「セキュリティの穴や欠陥」のこと。ここを突かれると、ハッカーにシステムを乗っ取られたり情報を盗まれたりします。
◆ SQLインジェクション(SQLi)
データベースへの命令(SQL文)に不正なコードをくっつけて送り込む、古典的なサイバー攻撃。システムの「入力欄」を悪用して、本来見えないはずのデータを盗み出します。陸が見つけたのはこの初歩的なミスです。
◆ セグメンテーションフォールト
プログラムが「使ってはいけないメモリ領域(場所)」にアクセスしたときに起きるエラー。システムが強制終了します。陸の飼い猫「セグフォ」の名前の由来です。
◆ SDR(ソフトウェア無線)
普通なら専用の機械が必要な「無線の受信・解析」を、パソコンのソフトだけでやってしまう技術(Software Defined Radio)。数千円のアンテナで、Wi-Fiから航空無線まで幅広い電波をキャッチできるため、ハッカーの定番おもちゃです。
◆ IPアドレス / プライベートIP / 0.0.0.0
IPアドレスはネット上の「住所」。通常は存在する住所(192.168.x.xなど)を使いますが、陸がキャプチャした通信の送信元は「0.0.0.0」。これはネットの世界では「現在地不明(住所が割り当てられていない)」を意味し、通常の通信ではありえない不気味な状態です。
◆ パケット / ペイロード / エンコーディング
パケットはネット上を飛ぶデータの「小包」。ペイロードはその小包の中に入っている「手紙の本文(本当のデータ)」。エンコーディングは文字をデータにする「ルール(文字コード)」。陸は、届いた手紙の文面が「地球上のどの文字ルールとも一致しない」ことに気づきました。
◆ 富雄丸山古墳
奈良県奈良市に実在する、日本最大の円墳(丸い形の古墳)。近年、国宝級の「巨大な蛇行剣」が出土したことで話題になりました。物語の冒頭でニュースとして流れていますが、これが後のハッキングへと繋がっていきます。
―――
※本作はフィクションです。実在の人物・団体・事件とは一切関係ありません。
※作中に登場する遺跡・古墳・史跡は実在のものをモデルにしていますが、無断での立ち入りや発掘は法律で禁止されています。見学の際は管理者の指示に従い、マナーを守ってお楽しみください。




