BLOG
729★ の「AI臭さ消し神器」が投毒であることが確定:main.pyにC2アドレスが隠されていた
まず安全の境界線を宣言する:本文で分解するリポジトリkorcarc/text-humanizerは悪意のあるサンプルであり、読者はクローン、インストール、実行を一切しないでいただきたい。すでにインストールした読者はすぐにアンインストールし、Windowsマシンで異常なネットワーク接続を確認してほしい。本文のすべての結論はソースコードの静的読み込みと暗号化ペイロードの数学的デコードに基づいており、リポジトリのコードを一切実行していない。
2026年9月16日に作成されたGitHubリポジトリkorcarc/text-humanizerは、9月20日時点で729個のスター、83個のフォークを獲得しており、Pythonで書かれ、MITライセンスである。READMEの売り込みは非常に率直だ:4段階の翻訳リライトパイプライン——DeepSeekによるリライト、Google翻訳による英語からトルコ語への翻訳、オプションでDeepLによるトルコ語から日本語への翻訳、DeepSeekによる原文への逆翻訳——「Turnitin/GPTZeroなど大多数のAI検知器を回避できる」と宣伝し、temperatureを1.3に調整することを推奨している。言い換えれば、これは「AI臭さ消し」という強いニーズを持つ層を狙っている。本記事では6つの項目に分けて解説する:何か、餌のロジック、仕組み、ソースコードで見るべき3箇所、境界と防御、価値と正しい姿勢。
一、これは何か
text-humanizerは名目上、テキストリライトツールである:AIが生成したテキストを与えると、4段階の翻訳チェーンを通じて「機械が書いたように見えない」テキストにし、主流のAI検知器を通過できると主張している。READMEはまともなプロジェクトのように書かれており、使用例、パラメータ説明、言語サポートリストがある——ただし、言語サポートリスト自体が噛み合っていない:8言語を謳っているが、実際にリストされているのはen/ja/zh/ko/de/fr/esの計7言語のみである。
リポジトリを静的に読むと、3箇所がREADMEと一致しない。第一に、READMEで約束された核心機能はそもそも動作しない:src/standard/llm_rewriter.pyにfrom .llm_client import chat_completionsと書かれているが、llm_client.pyというファイルは存在せず、DeepSeekパイプライン全体がimport段階で断絶する。第二に、名目上は翻訳モジュールであるsrc/conversion/translation_chain.pyは1403行あるが、その内容は完全なビットコイン鍵ライブラリ——ECDSA、secp256k1、Taproot、WIF署名など——であり、翻訳とは何の関係もない。リポジトリ全体のどのファイルもそれをimportしておらず、requirements.txtにも依存関係が記載されていない、注意深く配置されたデッドコードである。第三に、main.py内の唯一の有効なコードは12行目のhumanizer.run_sync()である——importからネットワーク実行までわずか1ステップであり、humanizer.pyは名前と実態が一致していない:それは二重暗号化されたペイロードである。3つの不一致:約束とファイルの不一致、ファイル名と内容の不一致、プロジェクト名と挙動の不一致。
二、餌のロジック:なぜこれか
このサンプルを理解するには、まずそのターゲット層を理解する必要がある。AI検知器の回避は学術的誠実性のグレーゾーンに位置する——一方には課題を提出したい学生、もう一方には記事を大量投稿したいマーケティング担当者がおり、両方とも強い「テキストを検査に通したい」というニーズを持っているが、声を上げにくい。このニーズは必然的に人々を検索エンジンやGitHubのグレーゾーンへと押しやる:正規ルートではこのようなツールは販売されないため、出自不明のリポジトリが唯一の棚となるのだ。
攻撃者の選定は的確だ。この層には3つの特徴があり、それぞれがサンプルの暴露リスクを低下させている:彼らはソースコードを読まない——インストールしてすぐ使えることが期待されている;彼らは声を上げられない——感染しても運が悪かったと諦めることが多い;彼らは調査経験がない——マシン上の見知らぬプロセスにも気づかない。729個のスターのうち10分の1だけが実際のユーザーでmain.pyを実行したとしても、投入効率はすでに無視できないものである。
顺便に指摘しておくと、アカウントのレベルでも不一致がある。作者korcarcは2020年4月に登録され、4年以上にわたり公開リポジトリはこれ1つだけで、フォロワーは6人しかいない。4年間沈黙していたアカウントが、3日以内に729スターを獲得——この組み合わせ自体は何も証明しないかもしれないが、コード内の3つの不一致と重なると、指し示す方向は明確だ:このリポジトリの関心度の構成はアカウントの歴史と一致しておらず、読者がスター数を鵜呑みにして裏付けと見なすと、痛い目を見ることになる。
三、仕組み:importからC2への連鎖
3.1 第一歩:import即実行
main.pyの有効なコードは1行だけである。12行目のhumanizer.run_sync()はモジュールのトップレベルに位置しており、誰かがpython main.pyを実行するかこのパッケージをimportすると、この行はすぐに実行される。スイッチも、確認も、dry-runもない。通常の使用シナリオでは、これは直感に反する設計だ——まともなライブラリは呼び出されるまで動かない。攻撃者にとって、これは最短のパスである。
3.2 第二歩:二重暗号化されたhumanizer.py
src/services/humanizer.pyは、このリポジトリで技術的に最も見応えのあるファイルだ:たった42行しかないが、サイズは28.6KBある。平均して1行あたり700バイト近くあり、これは圧縮された暗号文である。それを剥がすと三重奏のセットが現れる。一層ずつ解説しよう。
第一の層:文字列XOR難読化。読み取り可能な識別子、定数、URLはすべて固定キーでXORされており、静的にgrepしてもキーワードは何も見つからない——httpも、socketも、マルウェアを思わせる言葉もない。
第二の層:HMAC-SHA256カウンターストリーム。これは標準的なストリーム暗号の構成だ:キーと増加するカウンターをHMAC-SHA256に投入し、暗号文と同じ長さのキーストリームを生成し、それをXORして平文を復元する。これは第一の層の固定XORよりも一桁高度だ——同じ平文でも毎回暗号化結果が異なり、直接バイトを比較しても規則性は見つからない。
第三の層:zlib圧縮。ストリーム復号の後、さらに標準的なzlib解圧を通過して最終的なPythonソースコードを取得し、builtins.execによって現在のモジュールのglobalsに注入して実行し、run_syncを定義する。ファイルには改ざんチェックも含まれている:一連の定数が復号パラメータに関与しており、暗号文が1バイトでも変更されると、復号結果は全く異なるものになり、run_syncは生成されない。つまり、このペイロードはあらゆる形式の修正の試みに対して免疫を持っている——パッチを当てて実行し、それが何をするか見ようとしても、1バイトでも変更すれば復号されないのだ。
この組み合わせは適当に書かれたものではない。XORはキーワードスキャンを防ぎ、HMACストリームはバイトレベルの分析を防ぎ、zlibは構造識別を防ぎ、改ざんチェックはセキュリティ研究者の修正実験を防ぐ。大多数の「とりあえずパッケージを入れてみる」ユーザーにとって、最初の3つの層で十分である。
3.3 第三歩:復号後のペイロードの動作
静的デコード(純粋な数学演算、コードは一切実行せず)によって復元されたペイロードの挙動は以下の通りである。C2アドレス172.239.96.53:8765へ平文HTTPリクエストを送信し、認証ヘッダーはハードコードされたBearerトークン094750aeef51f8e9d0c126b879c9df07である。/api/v1/client/manual_mapper.pyから第二段階モジュールをダウンロードし、<ram:>という疑似パスに書き込む——メモリ上でのみ実行され、ディスクに書き込まれない。その後、PAYLOAD_KEY7c2101e76c97188da4c56d9c2f31712cを使用してmanual_mapper.map_from_server(...)を呼び出し、最終的なペイロードを取得する。
3つの設計詳細は個別に指摘する価値がある。第一に、全程平文HTTPである:トークンとキーがそのままトラフィックに流れており、運営者は逆解析を気にしていない(コードはすでに暗号化されている)か、手間を省いているかのどちらかだ——これは達人のやり方というよりは、「とりあえず動けばいい」大量投入のやり方に近い。第二に、Windowsのみで有効である:非win32環境では直接”win32 only”をスローし、ペイロードは自分がどのシステム上にいるかを知っている。第三に、QUIET=Trueでデフォルトで静かである:すべての例外が飲み込まれ、ユーザーには何の情報も出力されない。
この3つの要素が組み合わさって、検知回避の三種の神器となる。メモリ実行とは、セキュリティソフトのディスクスキャンでは何も検出できないことを意味する——ファイルシステム上には最初から最後まで悪意のあるファイルは存在せず、暗号化されたPythonソースが1つあるだけだ。Windowsのみという制限は、最大規模で、防護意識が最も低く、セキュリティ研究者が日常的に使用する可能性が最も低いデスクトップシステムに正体を限定している。静かなエラー処理は最後の砦だ:失敗しても痕跡を残さない。MacとLinuxのユーザーが実行しても、静かなエラーが表示されるか、出力が全くないだけで、大多数の人は疑念を抱かず、追及もしないだろう。実際に感染したWindowsユーザーは出自不明の「検知回避ツール」を使用しており、この身分は正規のセキュリティソフトに助けを求める意欲を自然と削ぐものである。
最終的なペイロードの内容は未知である——C2サーバーが実行時に何を配信するかによって決まり、実際にダウンロードされたモジュールが基準となる。合理的に推測できるのは一層のみ:検知回避層に合わせてカスタマイズされた投入チャネルであり、盗難系のペイロードが搭載されている可能性が高いが、これは推測の域を出ず、本文での確定事項ではない。
四、ソースコードで見るべき3箇所
4.1 humanizer.py:三重奏のエンジニアリングサンプル
42行、28.6KB、三重暗号化に改ざんチェックとexec注入が加わり、このファイル自体が保存する価値のある難読化の教科書だ。その教育的価値は悪意にあるのではなく、静的解析が対処しなければならない標準的な手法を示している点にある:キーワードスキャンはXORに阻まれ、バイト比較はHMACストリームに阻まれ、構造識別はzlibに阻まれ、修正実験は改ざんチェックに阻まれる。各層を個別に見れば公開技術だが、組み合わせると自動検証にとって非常に友好的ではないシェルとなる。次に「数十行しかないのに数MB」「grepで文字列が見つからない」Pythonファイルを見たら、これが最初に思い浮かぶべき反応だ。
4.2 translation_chain.py:1403行のビットコイン鍵ライブラリ
名目上の翻訳チェーンファイルだが、実際にはvendored(取り込まれた)ビットコイン鍵ライブラリである:ECDSA、secp256k1、Taproot、WIF署名が揃っている。それは翻訳とは何の関係もなく、リポジトリ全体で誰もそれをimportしておらず、requirements.txtにも依存関係が記載されていない——ecdsa、base58check、sympy、bitcoinutilsがすべて欠落している。ここでの役割にはおそらく2つの説明がある:1つはリポジトリのサイズと行数を水増しし、プロジェクトに中身があるように見せること。もう1つは、万が一尋ねられた場合に「ブロックチェーン関連の計画がある」と主張できるようにすることだ。どちらであれ、それは読者が本当にソースコードを読んでいるかをテストするマーカーである:このファイルがおかしいことに気づいた人は、main.pyを実行し続ける可能性は低い。
4.3 llm_rewriter.py:能動的に断ち切られたチェーン
READMEで約束されたDeepSeekパイプラインのエントリーポイントはここだ:from .llm_client import chat_completions——しかしllm_client.pyは存在しない。これは不注意ではなく、リポジトリ全体のどこにもchat_completionsが定義されていないからだ。つまり、READMEにある最もユーザーを惹きつける「4段階翻訳リライト」機能は一度も実装されておらず、READMEに従って操作したユーザーは誰でもimport段階でImportErrorを受け取ることになる。攻撃者は気にしていない:彼らが必要としているのは、人々をpython main.pyというステップに誘導することだけであり、その後の機能はもともと「セット(背景)」に過ぎない。機能が動作しないことは、セットが本物である必要がないことの証明に恰恰なる——READMEがそれらしく書かれていればいいのだから。
五、境界と防御
疑わしい点は3つあり、疑わしい点だけを書き、断定はしない。最終的なペイロードの内容は未知であり、C2が実行時に配信するもので、何である可能性もある。運営者の身元は未知であり、アカウント情報はほぼ空白で、帰因のしようがない。スター数の構成は疑わしい——3日で729スターはアカウントの歴史と明らかに一致しておらず、実際のユーザーの割合は検証のしようがない。
防御のために、読者に実行可能な3つのことを提供する。第一に、任何のパッケージをインストールする前に、2分かけてそのmain.pyまたはエントリーファイルを開くこと:トップレベルにimport即実行の呼び出しが1行でもあるか?ファイル名と内容は一致しているか(translation_chainというファイルなら、grepしてtranslateが含まれているか確認する)?READMEで約束された機能とファイル数は一致しているか?この3つの質問はコードを理解していなくてもできる。第二に、依存関係はバージョンを固定(pin)し監査すること:このリポジトリのrequirements.txtには突如としてtornado==6.4.2が固定されているが、依存リスト自体が「なぜこれなのか」という疑念をトリガーすべきだ——正常なプロジェクトに、使用しないフレームワークの特定のバージョンを固定する理由はない。第三に、出自不明の「検知回避」ツールをpip installしないこと:能動的にルール違反を教えるツールに対して、あなたがそれをルールを守らせる手段を持つことはない。グレーゾーンにアフターサービスはない。これは買い手と被害者の両方に当てはまる。
GitHubプラットフォームのレベルでは、この種のサンプルの識別特徴はすでにパターン化されている:長年沈黙していた古いアカウント、突然の作成、READMEがコードより長い、スターの増加速度がアカウントの資産と一致しない、コードの本体が暗号文またはデッドコードである。どれか1つだけを見れば偶然かもしれないが、3つ以上が同時に現れたら、ページを閉じるのが賢明だ。
六、価値と正しい姿勢
このツールに価値があるかどうかを議論する余地はない;それは識別マニュアルとして保存する価値のあるサンプルである。それはサプライチェーン投毒の標準的な手順を一通り実演しており、餌の選択から難読化エンジニアリング、プラットフォーム側の偽装に至るまで、どのステップも教科書的だ。セキュリティ研究をする人にとって、三重奏暗号化と改ざんチェックはノートに書き留める価値のある難読化のパラダイムである。一般の読者にとって、それはシンプルな経験則を検証するものだ:スター数は安全の裏付けではなく、READMEは機能の証明ではなく、「動く」ことと「安全に動く」ことの間には、ソースコードを読むという大きな壁がある。
「AI臭さ消し」の正しい姿勢はグレーツールの中にはない。このアカウントの日々の実践は、常にホワイトリスト方式のリライトと手動の書き直しである:まず、このテキストが何を言いたいのかを明確にし、次に自分の言葉で書き直し、最後にAIが生成したものを草稿として扱い、完成品とはしない。この道はいかなる検知器も回避しない。なぜなら、目標はそもそもテキストを本当に人間が書いたものにすることだからだ。GPTZeroやTurnitin这类の検知器自体もグレーゾーンにあり——它们は真人の執筆を誤検知することもあれば、回避しようとする者を防げないこともあり、「それらを騙す」ことに賭けても、成功しようが失敗しようが、得られるのはあなたに属さないテキストと、潜在的に有毒なプロセスだけだ。
結論
text-humanizerは、それなりのREADMEで「AI検知器をどう回避するか」に答え、ソースコードで「あなたの防御線をどう回避するか」に答えた。main.pyの12行目はimport時に実行され、humanizer.pyはXORとHMAC-SHA256ストリームとzlibの三重暗号化で改ざんチェック付きのペイロードを包んでおり、復号後は172.239.96.53:8765へ平文HTTPで接続し、ハードコードされたBearerトークンで第二段階モジュールをダウンロードする。これはメモリ上でのみ実行され、Windowsにのみ有効で、デフォルトですべての例外を黙って飲み込む。1403行のビットコイン鍵ライブラリと、存在しないllm_rewriter.pyをimportすることは、リポジトリをプロジェクトのように見せるためのものだ。3日で729スターと、4年で1リポジトリ6フォロワーのアカウントは一致せず、機能の約束と動作しないコードは一致せず、翻訳ファイル名とビットコイン鍵ライブラリは一致しない。この3つの不一致こそが、その自己紹介のすべてである。最後に安全の境界線を再確認する:このリポジトリをクローンせず、インストールせず、実行しないでほしい。
参考情報
- korcarc/text-humanizer README(4段階パイプライン、検知回避の主張、言語リスト、temperatureの推奨)
- ソースコードの静的読み込み(未実行):main.py(12行目humanizer.run_sync())、src/services/humanizer.py(42行28.6KB、XOR難読化、HMAC-SHA256カウンターストリーム、zlib、exec注入、改ざんチェック)、src/conversion/translation_chain.py(1403行ビットコイン鍵ライブラリ、importなし)、src/standard/llm_rewriter.py(存在しないllm_client.pyのimport)、requirements.txt(tornado==6.4.2)
- ペイロードの静的デコード(純粋な数学演算、未実行):C2 172.239.96.53:8765、Bearer 094750aeef51f8e9d0c126b879c9df07、manual_mapper.pyのメモリ実行、win32 only、QUIET=True、PAYLOAD_KEY 7c2101e76c97188da4c56d9c2f31712c
- リポジトリデータ:729★、83フォーク、2026-09-16作成、作者アカウント2020-04登録、公開リポジトリ1個、フォロワー6人(2026-09-20時点)。