Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2022-41218 — CVE-2022-41218에 대한 취약점 세부 정보 | Kitploit
도구/GitHubGitHub/tobey123/cve-2022-41218
Vulnerability AnalysisExploitationBinary Exploitation
GitHubtobey123/cve-2022-41218

CVE-2022-41218

CVE-2022-41218에 대한 취약점 세부 정보

저장소 보기
44년 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

Introduction

이 취약점은 drivers/media/dvb-core/dmxdev.c에서 발생하는 경쟁 조건 취약점입니다. 따라서 이 dmxdev를 사용하는 usb 장치 드라이버에서 경쟁 조건이 발생할 수 있습니다.

이 취약점은 3개의 UAF를 트리거하는 데 사용될 수 있습니다.

Vulnerability

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()을 호출합니다. 호출 시, 세 번째 인자는 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도 가능합니다.

커널 로그는 다음과 같습니다:
도구 다운로드