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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2022-41218 — CVE-2022-41218 の脆弱性詳細 | Kitploit
ツール/GitHubGitHub/tobey123/cve-2022-41218
脆弱性分析エクスプロイトバイナリエクスプロイト
GitHubtobey123/cve-2022-41218

CVE-2022-41218

CVE-2022-41218 の脆弱性詳細

リポジトリを見る
44年前未レビュー

人気

すべて見る →

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

すべてのツールを探索

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

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

はじめに

本脆弱性は、drivers/media/dvb-core/dmxdev.c に存在する競合状態の脆弱性です。 そのため、この dmxdev を使用する usb デバイスドライバでは競合状態が発生する可能性があります。

この脆弱性は、3つの UAF を引き起こすために使用される可能性があります。

脆弱性

1. vmalloc UAF 書き込み

まず、エクスプロイトの順序は次のとおりです(drivers/media/usb/ttusb-dec/ttusb_dec.c を使用してデバッグしました):``` cpu0 cpu1 cpu 2 1. dvb_dvr_open() 2. ttusb_dec_disconnect() ttusb_dec_exit_dvb() dvb_dmxdev_release() wait_event(dmxdev->dvr_dvbdev->wait_queue, …) 3. dvb_demux_open() dvb_demux_ioctl() dvb_usercopy() copy_from_user() <- userfaultfd stuck 4. dvb_dvr_release() 5. vfree(dmxdev->filter) 6. copy_from_user() <- userfaultfd release dvb_demux_do_ioctl() struct dmxdev *dmxdev = dmxdevfilter->dev; <- UAF!!

詳細なエクスプロイトの流れは以下の通りです。

1. デバイスノードの中で `dvr0` を `open()` します。これにより `dvb_dvr_open()` が呼び出され、`dvbdev->users++` が実行されます。
この場合、USBデバイスの取り外しによって `ttusb_dec_disconnect()` が実行されると、`wait_event(dmxdev->dvr_dvbdev->wait_queue, …)` の条件が捕捉されます。

2. USBデバイスを物理的に取り外します。
この場合、`ttusb_dec_disconnect()` 関数の実行中に、`wait_event(dmxdev->dvr_dvbdev->wait_queue, …)` で待機します。

3. `demux0` ノードを `open()` して、`dvb_demux_open()` 関数を呼び出します。
この関数も、ステップ1の `dvb_dvr_open()` 関数と同様に `dvbdev->users++` を実行します。
しかし、この不適切な参照カウントが発生するのは、現在待機中の `dvb_dmxdev_release()` 関数が `dvbdev->users` のチェックをすでに通過しているためです。```
void dvb_dmxdev_release(struct dmxdev *dmxdev)
{
        dmxdev->exit = 1;
        if (dmxdev->dvbdev->users > 1) {    // This check is bypassed. improper reference counting.
                wait_event(dmxdev->dvbdev->wait_queue,
                                dmxdev->dvbdev->users == 1);
        }
        if (dmxdev->dvr_dvbdev->users > 1) {
                wait_event(dmxdev->dvr_dvbdev->wait_queue,    // Currently wait()ing here.
                                dmxdev->dvr_dvbdev->users == 1);
        }

        dvb_unregister_device(dmxdev->dvbdev);
        dvb_unregister_device(dmxdev->dvr_dvbdev);

        vfree(dmxdev->filter);
        dmxdev->filter = NULL;
        dmxdev->demux->close(dmxdev->demux);
}

その後、demux0 に対して ioctl() を呼び出します。呼び出し時、第3引数は userfaultfd(または FUSE fs)によって設定されたユーザー空間アドレスを渡します。そして ioctl の実行中、dvb_usercopy() の copy_from_user() でハングします:``` int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, int (*func)(struct file *file, unsigned int cmd, void *arg)) { char sbuf[128]; void *mbuf = NULL; void *parg = NULL; int err = -EINVAL;

    /*  Copy arguments into temp kernel buffer  */
    switch (_IOC_DIR(cmd)) {
    case _IOC_NONE:
            /*
             * For this command, the pointer is actually an integer
             * argument.
             */
            parg = (void *) arg;
            break;
    case _IOC_READ: /* some v4l ioctls are marked wrong ... */
    case _IOC_WRITE:
    case (_IOC_WRITE | _IOC_READ):
            if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
                    parg = sbuf;
            } else {
                    /* too big to allocate from stack */
                    mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
                    if (NULL == mbuf)
                            return -ENOMEM;
                    parg = mbuf;
            }

            err = -EFAULT;
            if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))   // here
                    goto out;
            break;
    }
4. dvr0ノードをopen()したスレッドでそのfdをclose()します。  
するとdvb_dvr_release()が呼び出され、`dvbdev->users--`と`wake_up(&dvbdev->wait_queue)`が実行されて、.disconnectフローであるdvb_dmxdev_release()関数を起床させます。

5. .disconnectフローでは、dvb_dmxdev_release()関数内で`vfree(dmxdev->filter)`が実行されます。

6. userfaultfdを設定したdemux0 ioctlスレッドからuserfaultfdを解放します。  
これにより、.disconnectで解放したばかりの`dmxdev->filter`アドレスを読み取ることでUAFが発生します。  
これでUAFはdvb_demux_do_ioctl()のすべてのケースで利用可能になり、eBPFと組み合わせればLPEも可能です。
ツールをダウンロード