見込み顧客がGitの組み込みフックを通じてリモートコードの実行を試みた事例。

見込み顧客がGitの組み込みフックを通じてリモートコードの実行を試みた事例。

SToFU Systems · インシデント調査 · 2026年10月20日

目次

  1. 始まりは開発に関する問い合わせだった
  2. ファイルのダウンロードと調査
  3. Gitのpost-checkoutフックが実行され得る仕組み
  4. Gitフックのダウンローダーが行うこと
  5. アーカイブ内にアプリケーションが隠されていたのか
  6. ダウンロードサーバーが返したもの
  7. 正当な補助ツールだった可能性はあるか
  8. 見慣れないGitリポジトリをレビューする際に
  9. アーカイブのレビューを終えて
  10. やり取りと証拠ファイル

始まりは開発に関する問い合わせだった

最初のメッセージは、2026年10月15日に当社のウェブサイトから届きました。送信者は金融不正を検知するプラットフォームの構築支援を求めていました。提案されたシステムは、取引リスクをスコア化し、行動分析を利用するもので、ほかにもブロックチェーンによる検証やレポート機能などが要件に含まれていました。

10月19日、ダウンロードリンクが届きました。添付のメールでは、アーキテクチャはconfブランチ、契約書はNDAブランチを参照するよう案内されていました。また、NDAを確認して署名するよう改めて依頼されていました。

Please review the project materials and review and sign the NDA in the NDA branch.

この指示に従うと、レビュー担当者はアーカイブを展開した後、Gitでブランチを切り替えることになります。メールでは、どちらの操作もドキュメントを読むための手順として説明されていました。ダウンロードしたプログラムの実行については、何も書かれていませんでした。

プロジェクトのアーカイブと、NDAブランチを開く指示が記載されたメール。特定につながる情報は灰色の長方形で覆っています。

プロジェクトのアーカイブと、NDAブランチを開く指示が記載されたメール。特定につながる情報は灰色の長方形で覆っています。

ファイルのダウンロードと調査

リンク先は通常のDropboxファイル共有ページでした。当社はAI-Fraud-Detection_Blockchain.tar.gzを隔離されたレビュー環境にダウンロードし、参照用に元のアーカイブを保管しました。共有URLの具体的な内容はここでは公開していません。

アーカイブの内容を一覧化し、提供されたGitオブジェクトを直接読み取りました。これにより、ブランチをチェックアウトしたり提供されたコードを実行したりすることなく、3つのブランチすべてからドキュメントを取り出せました。各ブランチのツリーには、合計15個のMarkdownファイルと1個のWord文書がありました。

ブランチ ファイル 確認できた内容
master Markdownファイル8個 README、プロジェクト概要、製品要件、業務上のユースケース。ほかのドキュメントでは、性能、セキュリティ、テスト、運用が扱われていました。
conf Markdownファイル7個 開発提案の作成指針、ブロックチェーンのアーキテクチャと連携、スマートコントラクトの要件、データとAPIの設計、AIリスクエンジン、納品に向けたマイルストーン。
NDA DOCXファイル1個 署名欄とテンプレートのプレースホルダーがある秘密保持契約書。

提案された製品は、取引分析、不正検知ルール、機械学習によるスコアを、ブロックチェーンによる検証と組み合わせたものでした。推奨技術スタックは、Node.jsとTypeScriptに加え、Express、PostgreSQL、Pythonの機械学習ライブラリ、Ethereumを使用する構成でした。納品に関するドキュメントには、24週間にわたる6つのマイルストーンが示されていました。提供されたツリー全体で計画書は見つかりましたが、レビュー対象となるアプリケーションの実装、学習済みモデル、スマートコントラクトのソースはありませんでした。

いくつかの点は詳しく確認する必要がありました。APIの例では、エンドポイントのパスに<built-in function id>と<built-in function hash>という文字列がそのまま含まれていました。NDAにもテンプレートのプレースホルダーが残っていました。こうした不整合から、資料がどの程度慎重に作成されたのか疑問が生じました。

より重大な発見は、実行可能な.git/hooks/post-checkoutファイルでした。コメントにはブラウザーまたは拡張機能の更新補助ツールと記されていましたが、このプロジェクトのレビューとの明らかな関連はありませんでした。スクリプトを読むと、外部のプログラムをダウンロードし、バックグラウンドで起動する指示が含まれていました。メールにあったブランチ切り替えの依頼により、NDAを読もうとしたレビュー担当者がこの実行経路に入る可能性がありました。

当社はリポジトリを動作させず、フックをテキストとして調査しました。以下に、関連するアーカイブのメタデータとスクリプトの動作を示します。

Gitのpost-checkoutフックが実行され得る仕組み

AI-Fraud-Detection_Blockchain.tar.gzの長さは779,429バイトです。100個のTARエントリのうち、60個が通常ファイルです。ドキュメントには完全な.gitディレクトリが同梱されていました。

hooksディレクトリには、通常の.sampleファイルと、post-checkoutという名前の実行可能ファイルが含まれていました。

AI-Fraud-Detection_Blockchain/.git/hooks/post-checkout

ファイル名に.sampleという接尾辞はありません。TARのモードは実行権限を含む0777で、長さは2,774バイトです。

Gitはpost-checkoutを、checkoutやswitchなどの操作によって作業ツリーを更新した後に呼び出します(フックの実行が環境で許可されている場合)。この実行条件はGitのドキュメントに記載されています。

アーカイブ内の.gitディレクトリが重要な理由

Pro Gitの説明にあるとおり、通常のgit cloneでは、元のリポジトリにあるクライアント側のローカルフックはコピーされません。今回の提供物は、既存の.gitディレクトリをアーカイブ内に含んでいたため、ローカルフックも一緒に届きました。

元のTARから直接読み取ったフックのパス、モード、サイズ。受け取ったディレクトリをGitリポジトリとして操作することはありませんでした。

元のTARから直接読み取ったフックのパス、モード、サイズ。受け取ったディレクトリをGitリポジトリとして操作することはありませんでした。

受け取ったリポジトリ上でcheckoutやswitchを実行せず、コンテナとGitオブジェクトを直接調査しました。

Gitフックのダウンローダーが行うこと

シェルスクリプトのコメントには、ブラウザーまたは拡張機能の更新補助ツールと記されていました。プロジェクトのドキュメントには、そのような補助ツールを必要とする要件は見つかりませんでした。スクリプトは難読化されていないプレーンテキストです。

使われていないサイズしきい値

スクリプトはTHRESHOLDを100に設定し、変更されたファイル名の一覧をGitに要求します。TRIGGERはゼロで初期化します。

THRESHOLD=100
FILES=$(git diff --name-only "$OLD_HEAD" "$NEW_HEAD")
TRIGGER=0

ループ内でSIZEを計算します。しかし、THRESHOLDとの比較も、TRIGGERを変更する代入もありません。ダウンロード処理のブロックは、TRIGGERがゼロのときに実行されます。

if [ "$TRIGGER" -eq 0 ]; then

このスクリプトの通常の実行経路では、変更されたファイルの一覧が空でも条件は真になります。しきい値はダウンロードを制限していません。

元の行番号を保持しています。TRIGGERはゼロのままです。THRESHOLDは宣言されていますが、比較には一度も使われていません。

元の行番号を保持しています。TRIGGERはゼロのままです。THRESHOLDは宣言されていますが、比較には一度も使われていません。

Linux、macOS、Windows向けの個別のダウンロード

uname -sが返す値により、ダウンロード先のパスとローカルのファイル名が決まります。

検出されたシステム サーバー上のパス ローカルのファイル名
Linux /api/l run-command.sh
Darwin / macOS /api/m run-command.sh
MINGW, MSYS, CYGWIN, Windows_NT /api/w run-command.cmd
認識されないシステム /api/l run-command.sh

これらのURLは同じホストを使用しており、ここでは<DOWNLOAD_DOMAIN>に置き換えています。未編集のフックは非公開で保管しています。条件分岐はLinux、macOS、Windowsに対応し、認識されないシステムの場合はLinux用にフォールバックします。これらのシステムで実行テストは行っていません。

ファイルのダウンロードと実行の試行

フックはファイルを${TMPDIR:-/tmp}に保存するためにcurlを使い、代替手段としてwgetを使います(curlが利用できない場合)。後続の実行指示の前に、署名や期待されるハッシュの確認は行いません。

chmod +x "$CMD_FILE"
"$CMD_FILE" > /dev/null 2>&1 &

末尾のアンパサンドにより、コマンドはバックグラウンドで起動します。標準出力と標準エラー出力はいずれも/dev/nullに送られます。

実行を試みた後、フックはazukuという文字列を、一時ディレクトリ内の.git-checkerに書き込みます。再度ダウンロードする前に、そのマーカーを確認することはありません。また、バックグラウンドプロセスの成功を待たずにファイルを書き込みます。そのため、実行の試みが失敗した後でもマーカーが存在する可能性があります。

元のダウンロード、chmod、バックグラウンド実行、マーカー書き込みの指示。この抜粋には第2段階のプログラムは含まれていません。

元のダウンロード、chmod、バックグラウンド実行、マーカー書き込みの指示。この抜粋には第2段階のプログラムは含まれていません。

末尾付近のコメントには、一時ダウンロードディレクトリを削除するよう書かれています。その下に削除コマンドはありません。

アーカイブ内にアプリケーションが隠されていたのか

ネットワーク経由のダウンロードを見て、別の疑問が生じました。Gitの履歴やNDAの中など、アーカイブ内にすでにアプリケーションが存在していたのでしょうか。当社はコンテナの境界を調査し、その後、提供されたGitオブジェクトをすべてデコードして、DOCXの内容を調べました。

アーカイブの境界

内容を調査する前に、元のアーカイブのSHA-256を記録しました。

6f44ff4e461828dd1fe6ede75ca8d9d4b579c2ac223463629e9a7537b9df5040

gzipをデータとして展開すると、890,880バイトのTARストリームが得られました。gzipストリームは正常に終端しており、その後に未使用のバイトはありませんでした。最後のTARエントリより後にある末尾5,120バイトは、ゼロによるパディングでした。

続いて、それらのコンテナエントリに対応するファイルとオブジェクトを調査しました。

保存したgzipのストリーム終端とTARのパディングの確認結果。サンプルに含まれるコードは実行していません。

保存したgzipのストリーム終端とTARのパディングの確認結果。サンプルに含まれるコードは実行していません。

TARヘッダーでのフックの特定

post-checkoutエントリのヘッダーは、展開後のTARの0xCF600、すなわち849,408から始まります。ファイルデータは849,920から始まります。これらのオフセットは、圧縮された.gzファイルではなく、TARストリーム内の位置です。

そのオフセットでは、ヘッダーはpost-checkoutへのパスから始まっています。

TAR / 16進ダンプ

000cf600  41 49 2d 46 72 61 75 64 2d 44 65 74 65 63 74 69  |AI-Fraud-Detecti|
000cf610  6f 6e 5f 42 6c 6f 63 6b 63 68 61 69 6e 2f 2e 67  |on_Blockchain/.g|
000cf620  69 74 2f 68 6f 6f 6b 73 2f 70 6f 73 74 2d 63 68  |it/hooks/post-ch|
000cf630  65 63 6b 6f 75 74 00 00 00 00 00 00 00 00 00 00  |eckout..........|
000cf640  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
000cf650  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
000cf660  00 00 00 00 30 30 30 30 37 37 37 00 30 30 30 31  |....0000777.0001|
000cf670  37 35 30 00 30 30 30 31 37 35 30 00 30 30 30 30  |750.0001750.0000|
000cf680  30 30 30 35 33 32 36 00 31 35 32 35 32 30 30 34  |0005326.15252004|
000cf690  33 30 37 00 30 32 34 30 37 35 00 20 30 00 00 00  |307.024075. 0...|
000cf6a0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|

TARヘッダーでは、modeはバイト範囲[100:108]、sizeは[124:136]を占めます。このエントリについてデコードした各フィールドを、ダンプの後に示します。

TARフィールド 生のバイト列 / 値
mode b'0000777\x00'
size b'00000005326\x00'
8進数のモード 0777
10進数のサイズ 2774バイト
保存されたチェックサム / 計算したチェックサム 10301 / 10301

8進数のサイズをデコードすると2,774バイトになります。保存されているヘッダーのチェックサムは10,301です。チェックサムフィールドをスペースで埋めて再計算すると、同じ結果になります。

フックの生のTARヘッダーと、デコードしたフィールド。コンテナのバイト列から、名前、権限、サイズを確認できます。

フックの生のTARヘッダーと、デコードしたフィールド。コンテナのバイト列から、名前、権限、サイズを確認できます。

このエントリから抽出したフックのハッシュも計算しました。

854b3b88b06fad9d9ffec36b35be0133b1d502084d4d7cce232eda2b2dd03092

記事にはTARエントリのダンプと匿名化したフックを同梱しています。上記のハッシュは、公開用に情報を伏せたコピーではなく、非公開で保管している未編集の原本を識別するものです。

checkoutを使わずにGitオブジェクトを読む

.git/objectsには24個のルースオブジェクトがあり、それぞれがzlibストリームに格納されています。展開後のデータは、Gitヘッダーと、それに続くオブジェクト本体で構成されます。

<type> <size>\0<body>

宣言された本体の長さを確認し、ヘッダーとNULバイトを含むデコード後のデータ全体についてSHA-1を計算しました。その結果は、ファイル名に含まれるオブジェクトIDと一致する必要があります。これはオブジェクトの完全性を確認するものであり、作成者について何かを示すものではありません。

各オブジェクトについて、宣言された長さと本体の長さを比較し、デコード後のデータ全体のハッシュを検証しました。

expanded = zlib.decompress(compressed_object)
header, body = expanded.split(b"\0", 1)
kind, declared_size = header.decode("ascii").split()

assert len(body) == int(declared_size)
assert hashlib.sha1(expanded).hexdigest() == object_id

zlibストリームの終端も確認しました。オブジェクトの内訳はblobが16個、treeが5個、commitが3個でした。3つのブランチの先端から親コミットと子ツリーをたどることで、24個すべてを確認できました。提供されたオブジェクトの中に、到達不能なblobはありませんでした。

Git / コミット間の関係

master 4bc26f6c18910ca777c8238d2f88f6e725fcdc3f
  tree   feb0feaf7b8e826b085e90dea5399772d7b91f02
  parent (none)

conf   239b9aa2edc8c5e21fddeea5ed0e937496ae013f
  tree   048b51f9673f94354251ce16a78e663c71667a4c
  parent 4bc26f6c18910ca777c8238d2f88f6e725fcdc3f

NDA    a1311875d86bf6f1a6b9f2fee6527abbd1ce647d
  tree   cc020d922090835ea4ac3a3e418d0213d7a2ad94
  parent 239b9aa2edc8c5e21fddeea5ed0e937496ae013f

完全なオブジェクト一覧には、現在の作業ツリーに含まれないオブジェクトも記載しています。

全24個のGitオブジェクト一覧

オブジェクトID 種類 本体のサイズ(バイト)
08e2cda2f440c1792c7c35a3499bfd1ade3e9bad blob 6497
22bb86aacf377c17c7ad0d52c5cefeeb93dfa13e blob 5123
2a7091bdd006a2f98a8c795fd7d2a04c8ee53056 blob 2610
39e13459086f36bc7c933d4e7b5d249a22db24bd blob 3061
3f50e45c67dee5aac77147a5418afe551e8871be blob 2433
476dc872c6def747dcdac549b67a8dc80948b7e1 blob 3191
5a51550933b593eb65da458bbdd579f85c082dab blob 752100
5e53fd0880963e1767ad23fb8612b76e31f04003 blob 2807
60a7cbff83445488fd34b12de1814dc56c956963 blob 2054
74d479352822f5cc1d03552f517cfb5b2d7aa6d3 blob 2281
84e694473554c8a7c01f038a1b6ef8d9355405f7 blob 2033
bb7b5d8bc28c4a6257f7d87a685c61ba16a3789c blob 2425
d83c8e0c416766be34276013944f5b94726e8c8f blob 2776
dfd0f171bca257780eb0d9e22ba2eda1db9d4b68 blob 8402
e3b57e48010fc25fd12e7f5f25e952aca843e537 blob 6316
ed325750862eb6cdc92b216258a00a784312d793 blob 3062
239b9aa2edc8c5e21fddeea5ed0e937496ae013f commit 213
4bc26f6c18910ca777c8238d2f88f6e725fcdc3f commit 165
a1311875d86bf6f1a6b9f2fee6527abbd1ce647d commit 212
048b51f9673f94354251ce16a78e663c71667a4c tree 438
2cb70db8d9317603cb5f0fee0029b66581a7162e tree 104
61874365e5498a30c8b61ef63bbb1d28b4cf4e22 tree 320
cc020d922090835ea4ac3a3e418d0213d7a2ad94 tree 57
feb0feaf7b8e826b085e90dea5399772d7b91f02 tree 104

各オブジェクトの元のGitエンコーディングに対して、長さとSHA-1を検証しました。24件すべての検証に合格しました。


NDAをツリーからバイト列までたどる

NDAブランチは、Non-Disclosure-Agreement.docxという1個のファイルを含むツリーを指しています。Gitのツリーエントリは、モードとファイル名をテキストとして格納し、その後にNULと、blob IDを表す20バイトの生データが続きます。このエントリをツリー本体から直接解析しました。

Git tree / 16進ダンプ

00000000  31 30 30 36 34 34 20 4e 6f 6e 2d 44 69 73 63 6c  |100644 Non-Discl|
00000010  6f 73 75 72 65 2d 41 67 72 65 65 6d 65 6e 74 2e  |osure-Agreement.|
00000020  64 6f 63 78 00 5a 51 55 09 33 b5 93 eb 65 da 45  |docx.ZQU.3...e.E|
00000030  8b bd d5 79 f8 5c 08 2d ab                       |...y.\.-.|

NDAツリーの生のバイト列と、デコードしたDOCXのblobへの参照。

NDAツリーの生のバイト列と、デコードしたDOCXのblobへの参照。

このエントリは、次のblobを参照しています。

5a51550933b593eb65da458bbdd579f85c082dab

zlibで展開した後のオブジェクトはblob 752100\0で始まります。ヘッダーの直後には50 4b 03 04というバイト列があり、これはZIPコンテナのPKシグネチャです。

Git blob / zlib展開後

00000000  62 6c 6f 62 20 37 35 32 31 30 30 00 50 4b 03 04  |blob 752100.PK..|
00000010  0a 00 00 00 00 00 87 4e e2 40 00 00 00 00 00 00  |.......N.@......|
00000020  00 00 00 00 00 00 09 00 00 00 64 6f 63 50 72 6f  |..........docPro|
00000030  70 73 2f 50 4b 03 04 14 00 00 00 08 00 87 4e e2  |ps/PK.........N.|
00000040  40 a5 76 12 16 69 01 00 00 7b 02 00 00 10 00 00  |@.v..i...{......|
00000050  00 64 6f 63 50 72 6f 70 73 2f 61 70 70 2e 78 6d  |.docProps/app.xm|
00000060  6c 9d 92 c1 4e c3 30 10 44 ef 48 fc 43 94 7b 62  |l...N.0.D.H.C.{b|

圧縮されたオブジェクトのバイト列、デコードしたGitヘッダー、DOCXの冒頭。長さとオブジェクトIDは、オブジェクト全体を対象に確認しました。

圧縮されたオブジェクトのバイト列、デコードしたGitヘッダー、DOCXの冒頭。長さとオブジェクトIDは、オブジェクト全体を対象に確認しました。

本体の長さは752,100バイトです。そのSHA-256は、分析用に別途保存したDOCXと一致します。

9d85170d2c0aa7a9b90dfc3855715a31d971bba7abb563e9efa1153fdc15634f

これらのオブジェクトにより、NDAブランチから文書のバイト列までの経路を確認できます。

全16個のblobを確認する

15個のblobはUTF-8のMarkdown形式のプロジェクト文書としてデコードされます。残る1個は上記のDOCXです。PE、ELF、Mach-Oのヘッダーで始まるものはありません。

ツリー内のパス サイズ(バイト) 種類 / 先頭のバイト列
04-solution-proposal-guidance.md 2054 UTF-8テキスト · 23 20 44 65 76 65 6c 6f 70 6d 65 6e 74 20 43 6f
06-blockchain-architecture.md 6497 UTF-8テキスト · 23 20 42 6c 6f 63 6b 63 68 61 69 6e 20 41 72 63
07-blockchain-integration-specification.md 2807 UTF-8テキスト · 23 20 42 6c 6f 63 6b 63 68 61 69 6e 20 49 6e 74
08-smart-contract-specification.md 2610 UTF-8テキスト · 23 20 53 6d 61 72 74 20 43 6f 6e 74 72 61 63 74
09-data-and-api-architecture.md 2776 UTF-8テキスト · 23 20 44 61 74 61 20 26 20 41 50 49 20 41 72 63
11-ai-fraud-and-risk-engine.md 3062 UTF-8テキスト · 23 20 41 49 20 46 72 61 75 64 20 44 65 74 65 63
14-deliverables-acceptance-and-milestones.md 6316 UTF-8テキスト · 23 20 44 65 6c 69 76 65 72 61 62 6c 65 73 2c 20
Detailed/03-business-and-use-cases.md 3061 UTF-8テキスト · 23 20 42 75 73 69 6e 65 73 73 20 52 65 71 75 69
Detailed/05-non-functional-requirements.md 2033 UTF-8テキスト · 23 20 4e 6f 6e 2d 46 75 6e 63 74 69 6f 6e 61 6c
Detailed/10-security-and-privacy-requirements.md 2433 UTF-8テキスト · 23 20 53 65 63 75 72 69 74 79 20 26 20 50 72 69
Detailed/12-testing-and-quality-requirements.md 2425 UTF-8テキスト · 23 20 54 65 73 74 69 6e 67 20 26 20 51 75 61 6c
Detailed/13-deployment-monitoring-and-operations.md 2281 UTF-8テキスト · 23 20 44 65 70 6c 6f 79 6d 65 6e 74 2c 20 4d 6f
Intro/01-project-overview.md 8402 UTF-8テキスト · 23 20 50 72 6f 6a 65 63 74 20 4f 76 65 72 76 69
Intro/02-product-requirements.md 3191 UTF-8テキスト · 23 20 50 72 6f 64 75 63 74 20 52 65 71 75 69 72
Non-Disclosure-Agreement.docx 752100 DOCX/ZIP · 50 4b 03 04 0a 00 00 00 00 00 87 4e e2 40 00 00
README.md 5123 UTF-8テキスト · 23 20 41 49 20 46 72 61 75 64 20 44 65 74 65 63

提供された16個のblobをすべて分類しました。ツリーにはプロジェクト文書が含まれており、製品の実装は見つかりませんでした。

提供された16個のblobをすべて分類しました。ツリーにはプロジェクト文書が含まれており、製品の実装は見つかりませんでした。

シグネチャの確認に加え、テキストの本体も読みました。DOCXは唯一の非テキストblobであり、別途コンテナの調査が必要でした。

DOCXをZIPとして開く

文書には25個のZIPエントリがあり、17個のファイルパーツと8個のディレクトリで構成されています。すべてのファイルパーツを読み取り、それぞれのCRCを確認しました。

DOCXパーツ サイズ(バイト) CRC32
[Content_Types].xml 1482 ec936159
_rels/.rels 737 1f222201
customXml/_rels/item1.xml.rels 296 7a393f74
customXml/item1.xml 400 4ed0e3fe
customXml/itemProps1.xml 327 457b4363
docProps/app.xml 635 161276a5
docProps/core.xml 595 d5626da7
docProps/custom.xml 722 8d44908d
word/_rels/document.xml.rels 1086 22475620
word/_rels/settings.xml.rels 398 e5802c0c
word/document.xml 91835 4df71596
word/fontTable.xml 4234 2796cccd
word/media/image1.png 712863 09063019
word/media/image2.png 10193 3aea21cf
word/settings.xml 4116 34faa9ef
word/styles.xml 30020 b4e9edbd
word/theme/theme1.xml 6329 ed5975e1

DOCXパーツの名前、長さ、CRC32値。Officeで文書を開かずに、ZIPとXMLのデータを調査しました。

DOCXパーツの名前、長さ、CRC32値。Officeで文書を開かずに、ZIPとXMLのデータを調査しました。

パーツ一覧にvbaProject.binやOLE添付ファイルはありません。2個のPNGファイルには、ロゴと署名画像が含まれています。XMLのリレーションシップも調査したところ、文書作成者のマシン上にあるローカルのOfficeテンプレートのパスへの参照が見つかりました。その参照先の解決や読み込みは行いませんでした。

署名画像とGitの作成者フィールドは、送信者を確実に特定する手段にはなりません。どちらもコピーや置き換えが可能です。

提供された内容に、別のアプリケーションや製品の実装は見つかりませんでした。フックは、次のプログラムをネットワーク経由で取得します。ただし、当社のコンテナ調査は、考えられるすべての脆弱性悪用やステガノグラフィの手法を排除するものではありません。

ダウンロードサーバーが返したもの

3つの正確なURLから、応答を実行せず、リダイレクトにも従わず、データとして取得しました。10月19日の17:29:27~17:29:28 UTCに、いずれもHTTP 200を返しました。3つの本文はすべて、同じ21バイトのメッセージでした。

Permanently suspended

保存した3つのエンドポイントの観測結果。この記事の準備中に、ダウンローダーのURLへ追加のリクエストは行っていません。

保存した3つのエンドポイントの観測結果。この記事の準備中に、ダウンローダーのURLへ追加のリクエストは行っていません。

リバースエンジニアリングの対象となる第2段階のバイト列は手元にありません。また、これらのエンドポイントが以前に、別の訪問者に対して、あるいは異なるリクエスト条件で何を返していたかも分かりません。サービス停止を示すメッセージからは、停止理由について検証済みの説明は得られません。

フックは外部ファイルのダウンロードと実行を試みます。パスワード、トークン、ソースコード、ウォレットが盗まれたという主張には、当社が持っていない証拠が必要です。

正当な補助ツールだった可能性はあるか

内部のアップデーターが誤ってアーカイブに入ることはあり得ます。Gitフック、バックグラウンドプロセス、curlには、いずれも正当な用途があります。

今回の提供物では、メールが明確に別のブランチへの移動を求めていました。この操作は提供されたダウンローダーを呼び出す可能性がありますが、ブランチを変更する理由として示されていたのは契約書を読むことでした。メールには実行についての記載がありませんでした。また、ブラウザーのアップデーターと提案されたシステムとの関連は見つからず、スクリプトのサイズ確認も不完全でした。

当社はこれを、コードを送り込む攻撃の試みと判断し、フックが実行されないようにしました。この評価を見直すには、ダウンロードされるファイルのソースと、NDAの確認のために受託者がそれらを実行する必要があった理由について、検証可能な説明が必要です。

操作者の身元は特定していません。送信元アドレス、コミットのメタデータ、文書内の名前だけでは、攻撃主体の特定には不十分です。

提供されたフックに記述されている実行手順の分析図。

提供されたフックに記述されている実行手順の分析図。

見慣れないGitリポジトリをレビューする際に

メールの指示に従う開発者は、まだプロジェクトについて読んでいる段階で、実行の引き金となる操作に到達する可能性がありました。提案されたアプリケーションをビルドしたり起動したりする必要はありませんでした。

本番環境のSSH鍵やクラウドのトークンがあるマシンで顧客からの提供物をレビューすると、予期しないスクリプトがそれらのリソースにアクセスできる可能性があります。使い捨ての環境では、これらの認証情報にアクセスできないようにする必要があります。レビュー用マシンのブラウザーセッションについても、同様の配慮が必要です。

エンジニアが普段のコマンドを使い始める前に、提供された.gitディレクトリとIDEの自動処理もレビューする必要があります。インストールスクリプトにも精査が必要です。ホストのログでは、Gitやシェルがファイルを一時ディレクトリにダウンロードし、その後実行する動きを確認します。curlプロセスが単独で存在するだけでは、分かることははるかに少なくなります。

元のメールとアーカイブを保管しておくと、後のレビュー担当者が実際に何が届けられたのかを確認できます。ハッシュとホストのイベントは、マシン上で何が起きたかを確かめる助けになります。マーカーがないことだけでは、プログラムが一度も実行されなかったとは証明できません。

アーカイブのダウンロードや展開で、このフックは実行されるのか

ダウンロードや通常の展開それ自体が、Gitのpost-checkoutフックを呼び出すことはありません。このサンプルで確認されている実行条件は、フックの実行が許可されている状態で、Gitがcheckoutまたはswitchによって作業ツリーを更新することです。当社はそれらの操作を呼び出さず、提供されたオブジェクトを直接調査しました。

アーカイブのレビューを終えて

次のやり取りでは、アーキテクチャや納期について話すことになると考えていました。しかし、実際にはフックについて返信し、さらなる調査のために資料を保管しました。リモートのプログラムが何をしたのか、誰が運用していたのかは、今も分かりません。依頼されたGitの作業手順を中止するには、このフックだけで十分な理由がありました。

SToFU Systemsと当社のソリューションは、5年以上にわたり企業のシステム保護を支援してきました。その対象には、業務上のやり取りや開発資料を通じて届けられる攻撃も含まれます。当社のセキュリティ監査では、コードやアクセス権がどのように悪用され得るかを調べます。また、チームが見慣れないソフトウェアを理解する必要がある場合には、リバースエンジニアリングも提供しています。

リポジトリやバイナリに疑問がある場合は、通常の開発環境に持ち込む前に、技術的なレビューについて当社チームにご相談ください。

やり取りと証拠ファイル

以下の4通のメッセージでは、個人名、アドレス、第三者の身元情報、特定につながるリンクをプレースホルダーに置き換えています。それ以外の、各新規メッセージの文面は保持しています。各メールを個別に掲載しているため、重複する引用は省略しています。ウェブフォームのサービスIPと、無関係な受信者のアドレスも非公開にしています。

1. 当社ウェブサイトからの最初の問い合わせ

メール / 特定につながる情報は置換済み

Date: Thu, 15 Oct 2026 12:55:21 +0000
From: SToFU Site Form <TEAM_EMAIL>
To: <TEAM_EMAIL>
Subject: SToFU Systems - Contact by <SENDER_NAME> <SENDER_EMAIL>
Reply-To: <SENDER_NAME> <SENDER_EMAIL>

Time: 2026-10-15T12:55:21+00:00
IP: [redacted]
Page: /contact
Name: <SENDER_NAME>
Email: <SENDER_EMAIL>
Attachments: none
Message:
We are currently developing an AI-powered FinTech fraud detection platform designed to help financial organizations identify suspicious transactions, assess potential risks in real time, and strengthen their fraud prevention and investigation processes.
The planned platform will incorporate AI/ML-based fraud detection, transaction risk scoring, behavioral analysis, configurable fraud-detection rules, blockchain-based verification, automated alerts, investigation support, and reporting and analytics.
We are looking to connect with an experienced technology partner with expertise in blockchain, financial technology, AI/ML, and scalable web platform development to help us bring this product to life.
We would welcome the opportunity to discuss your team’s capabilities, experience, and potential role in the project. The specific scope of your team’s involvement, technical responsibilities, and collaboration model can be determined through our discussion, based on your expertise and recommendations.
If this opportunity aligns with your team’s capabilities and interests, I’d be happy to share the project overview and technical roadmap for an initial review.
---

当社ウェブサイトからの最初の問い合わせ。保管しているメールを匿名化した公開用の表示。

当社ウェブサイトからの最初の問い合わせ。保管しているメールを匿名化した公開用の表示。

非公開で保管する未編集EMLのSHA-256:bf7d0f3a59b84f509ca436e0750640e844e9731ce363a42a99d5be60cdf8597e


2. 資料の提供をお願いした当社の返信

メール / 特定につながる情報は置換済み

Date: Sat, 17 Oct 2026 19:46:28 -0000
From: <TEAM_MEMBER_NAME> <TEAM_EMAIL>
To: <SENDER_NAME> <SENDER_EMAIL>
Subject: Re: Your AI fraud detection platform
Cc: [redacted: third-party addresses]

Hi <SENDER_NAME>,

Thank you for getting in touch through our website. I'm <TEAM_MEMBER_NAME>, <TEAM_MEMBER_ROLE> of SToFU Systems (<COMPANY_WEBSITE>). You can find me on <PROFESSIONAL_NETWORK> here:
<PROFILE_URL>

Your fraud detection platform sounds like a great project. Helping financial teams spot suspicious transactions and investigate them more effectively is a worthwhile problem to solve, and we'd be very happy to help you bring it to life.

We'd be glad to help with the architecture, development, security, and ongoing maintenance. We'll do everything we can to get the platform launched and keep it running reliably as it grows.

If you plan to seek investment, we can also help prepare the technical side for those conversations, including a working product or demo, clear architecture and documentation, and a practical development roadmap.

Please send over the project overview and technical roadmap you mentioned. It would be helpful to understand what you've already built and what you'd like to tackle first.

I'd be happy to arrange a call to discuss the project and how we could work together. What day and time would suit you? Please include your time zone so we can find a slot that works for both teams.

Thank you again for reaching out, and have a great day!

Best regards,
<TEAM_MEMBER_NAME>
<TEAM_MEMBER_ROLE>
SToFU Systems
<COMPANY_WEBSITE>

資料の提供をお願いした当社の返信。保管しているメールを匿名化した公開用の表示。

資料の提供をお願いした当社の返信。保管しているメールを匿名化した公開用の表示。

非公開で保管する未編集EMLのSHA-256:1e5330dd82e02911254722744a3202e9b761c8c1d2950be937cd5d539c1bcad9


3. NDA / confブランチを指定したアーカイブ送付メール

メール / 特定につながる情報は置換済み

Date: Mon, 19 Oct 2026 09:03:41 +0000
From: <SENDER_EMAIL>
To: <TEAM_EMAIL>
Subject: Re: Your AI fraud detection platform

Hi <TEAM_MEMBER_NAME>,
Thank you for your interest in our AI-powered FinTech fraud detection platform.
I’ve also reviewed your <PROFESSIONAL_NETWORK> profile, and I’m confident that you and your team can make a valuable contribution to our project.
I’m happy to share the project materials for your review.
We’ve prepared the project overview, technical roadmap, and NDA, which provide the key information needed to understand the project, its objectives, and the proposed technical direction.
The platform focuses on AI-driven fraud detection, transaction risk assessment, behavioral analysis, fraud prevention, blockchain-based verification, automated alerts, investigation support, and financial risk analytics.
This is the Link:
<FILE_SHARE_URL>
Please review the project materials and review and sign the NDA in the NDA branch.
The NDA is required because the project materials contain confidential business, technical, architectural, and product information.
So, please send me the signed NDA as soon as possible.
In particular, we would appreciate your initial technical assessment of the proposed system architecture and timeline. The detailed documentation and specifications related to these areas are available in the conf branch.
After your review, we would like to arrange a meeting to discuss your technical observations, recommendations, questions, development approach, and potential partnership opportunities in more detail.
Once you have completed your review, please let me know your preferred meeting date and time and provide the signed NDA.
Please feel free to take the time you need to review the materials thoroughly. I look forward to receiving your feedback and speaking with you about the project.
Kind regards,
<SENDER_NAME>

NDA / confブランチを指定したアーカイブ送付メール。保管しているメールを匿名化した公開用の表示。

NDA / confブランチを指定したアーカイブ送付メール。保管しているメールを匿名化した公開用の表示。

非公開で保管する未編集EMLのSHA-256:f7007ed3053d3ba2ef71ea01c74ec0c4aebfd48417f757ecec8d9d7d5884bf33


4. フック発見後の当社の返信

メール / 特定につながる情報は置換済み

Date: Mon, 19 Oct 2026 19:37:58 +0200
From: SToFU Systems <TEAM_EMAIL>
To: <SENDER_NAME> <SENDER_EMAIL>
Subject: Re: Your AI fraud detection platform

Hi <SENDER_NAME>,

We reviewed the materials you sent. Unfortunately, we found no application source code or working implementation, only planning documents and an NDA.

Execution of the supplied Git post-checkout hook was disabled during our review. The hook downloads and runs platform-specific files from <DOWNLOAD_DOMAIN>, hides their output, and writes a local marker. Our security policies do not allow the execution of untrusted third-party hooks.

Thank you for your time and for the elaborate attempt to deliver malicious code.

We have traced the technical delivery chain and preserved the archive, hook, download responses, correspondence, and author names and email addresses recorded in the repository. The relevant evidence will be passed to the competent law enforcement authorities in the applicable jurisdictions.

SToFU Systems

フック発見後の当社の返信。保管しているメールを匿名化した公開用の表示。

フック発見後の当社の返信。保管しているメールを匿名化した公開用の表示。

非公開で保管する未編集EMLのSHA-256:31df91adb2eb52be2171836d3e26610328a0a1a1273dbf7d56efe4354bb62e19


フック全体の匿名化表示

ソースの全101行の行番号を保持しています。特定につながる情報は灰色の長方形で覆っています。

ソースの全101行の行番号を保持しています。特定につながる情報は灰色の長方形で覆っています。


未編集の原本は非公開で保管しています。公開する証拠ファイルではプレースホルダーを使用し、スクリーンショットでは不透明な灰色の長方形を使用しています。「原本」と表示したハッシュは、編集した公開用コピーではなく、非公開の元資料を識別するものです。図はローカルの証拠表示画面のスクリーンショットで、レンダリング前に特定につながるテキストを除去しています。受け取ったコードは実行していません。

SToFU Systems

SToFU Systems

ブログに戻る

お問い合わせ

会話を始める

数行でかまいません。対象のシステム、いまの課題、止まっている判断を教えてください。直接 midgard@stofu.io にご連絡いただいても構いません。

0 / 10000
ファイルが選択されていません