Kernel Race Condition Exploitation via Object Manager Slow Paths
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
๋ ์ด์ค ์ฐฝ์ ๋๋ฆฌ๋ ๊ฒ์ด ์ค์ํ ์ด์
๋ง์ Windows kernel LPE๋ ๊ณ ์ ์ ์ธ ํจํด check_state(); NtOpenX("name"); privileged_action();์ ๋ฐ๋ฆ
๋๋ค. ์ต์ ํ๋์จ์ด์์ ์ฝ๋ NtOpenEvent/NtOpenSection๋ ์งง์ ์ด๋ฆ์ ์ฝ 2โฏยตs ์์ ํด์ํ๋ฏ๋ก, ๋ณด์ ๋์์ด ์คํ๋๊ธฐ ์ ์ ๊ฒ์ฌ๋ ์ํ๋ฅผ ๋ณ๊ฒฝํ ๊ฑฐ์ ์๊ฐ์ด ๋จ์ง ์์ต๋๋ค. 2๋จ๊ณ์ Object Manager Namespace (OMNS) ์กฐํ๋ฅผ ์์ญ ๋ง์ดํฌ๋ก์ด๋ก ์๋์ ์ผ๋ก ์ง์ฐ์ํค๋ฉด, ๊ณต๊ฒฉ์๋ ์์ฒ ๋ฒ ์๋ํ ํ์ ์์ด ์ผ๊ด๋๊ฒ ๋ถ์์ ํ ๋ ์ด์ค์์ ์น๋ฆฌํ ์ถฉ๋ถํ ์๊ฐ์ ํ๋ณดํ ์ ์์ต๋๋ค.
Object Manager lookup ๋ด๋ถ ๋์(์์ฝ)
- OMNS ๊ตฌ์กฐ โ
\BaseNamedObjects\Foo์ ๊ฐ์ ์ด๋ฆ์ ๋๋ ํฐ๋ฆฌ๋ณ๋ก ์์ฐจ์ ์ผ๋ก ํด์๋ฉ๋๋ค. ๊ฐ ๊ตฌ์ฑ ์์๋ง๋ค ์ปค๋์ Object Directory๋ฅผ ์ฐพ๊ฑฐ๋ ์ด๊ณ Unicode ๋ฌธ์์ด์ ๋น๊ตํฉ๋๋ค. ์ฌ๋ณผ๋ฆญ ๋งํฌ(์: ๋๋ผ์ด๋ธ ๋ฌธ์)๊ฐ ๊ฒฝ๋ก ์์์ ๋ฐ๋ผ๊ฐ ์ ์์ต๋๋ค. - UNICODE_STRING limit โ OM ๊ฒฝ๋ก๋
Length๊ฐ 16๋นํธ ๊ฐ์ธUNICODE_STRING์์ ๋ด๊น๋๋ค. ์ ๋ ํ๊ณ๋ 65โฏ535 ๋ฐ์ดํธ(32โฏ767 UTF-16 ์ฝ๋ํฌ์ธํธ)์ ๋๋ค.\BaseNamedObjects\๊ฐ์ ์ ๋์ฌ๋ฅผ ๊ณ ๋ คํด๋ ๊ณต๊ฒฉ์๋ ์ฌ์ ํ โ32โฏ000 ๋ฌธ์๋ฅผ ์ ์ดํ ์ ์์ต๋๋ค. - Attacker prerequisites โ ๋ชจ๋ ์ฌ์ฉ์๋
\BaseNamedObjects๊ฐ์ ์ฐ๊ธฐ ๊ฐ๋ฅํ ๋๋ ํฐ๋ฆฌ ์๋์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ์ทจ์ฝํ ์ฝ๋๊ฐ ๊ทธ ์์ ์ด๋ฆ์ ์ฌ์ฉํ๊ฑฐ๋ ๊ทธ๊ณณ์ผ๋ก ์ฐ๊ฒฐ๋๋ ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉด, ๊ณต๊ฒฉ์๋ ํน๊ถ ์์ด๋ ์กฐํ ์ฑ๋ฅ์ ์ ์ดํ ์ ์์ต๋๋ค.
Slowdown primitive #1 โ Single maximal component
๊ตฌ์ฑ ์์๋ฅผ ํด์ํ๋ ๋น์ฉ์ ๊ธธ์ด์ ๊ฑฐ์ ์ ํ์ ์ผ๋ก ์ฆ๊ฐํฉ๋๋ค. ๊ทธ ์ด์ ๋ ์ปค๋์ด ๋ถ๋ชจ ๋๋ ํฐ๋ฆฌ์ ๋ชจ๋ ํญ๋ชฉ์ ๋ํด Unicode ๋น๊ต๋ฅผ ์ํํด์ผ ํ๊ธฐ ๋๋ฌธ์
๋๋ค. ์ด๋ฆ ๊ธธ์ด๊ฐ 32โฏkB์ธ ์ด๋ฒคํธ๋ฅผ ์์ฑํ๋ฉด NtOpenEvent์ ์ง์ฐ์ด ์ฆ์ ์ฝ 2โฏยตs์์ ์ฝ 35โฏยตs๋ก ์ฆ๊ฐํฉ๋๋ค (Windows 11 24H2, Snapdragon X Elite testbed).
std::wstring path;
while (path.size() <= 32000) {
auto result = RunTest(L"\\BaseNamedObjects\\A" + path, 1000);
printf("%zu,%f\n", path.size(), result);
path += std::wstring(500, 'A');
}
์ค์ฉ์ ์ธ ๋ ธํธ
- ์์์ named kernel object (events, sections, semaphoresโฆ)๋ฅผ ์ฌ์ฉํด ๊ธธ์ด ์ ํ์ ๋๋ฌํ ์ ์์ต๋๋ค.
- Symbolic links ๋๋ reparse points๋ ์งง์ โvictimโ ์ด๋ฆ์ ์ด ๊ฑฐ๋ํ ์ปดํฌ๋ํธ๋ก ๊ฐ๋ฆฌํค๊ฒ ํ์ฌ slowdown์ด ํฌ๋ช ํ๊ฒ ์ ์ฉ๋๋๋ก ํ ์ ์์ต๋๋ค.
- ๋ชจ๋ ๊ฒ์ด user-writable namespaces์ ์กด์ฌํ๊ธฐ ๋๋ฌธ์, payload๋ standard user integrity level์์ ๋์ํฉ๋๋ค.
Slowdown primitive #2 โ Deep recursive directories
๋ ๊ณต๊ฒฉ์ ์ธ ๋ณํ์ ์์ฒ ๊ฐ์ ๋๋ ํฐ๋ฆฌ ์ฒด์ธ(\BaseNamedObjects\A\A\...\X)์ ํ ๋นํฉ๋๋ค. ๊ฐ ํ์ directory resolution logic (ACL checks, hash lookups, reference counting)์ ํธ๋ฆฌ๊ฑฐํ๋ฏ๋ก, ๋ ๋ฒจ๋น ์ง์ฐ ์๊ฐ์ ๋จ์ผ ๋ฌธ์์ด ๋น๊ต๋ณด๋ค ํฝ๋๋ค. ๋์ผํ UNICODE_STRING ํฌ๊ธฐ๋ก ์ ํ๋๋ ์ฝ ~16โฏ000 ๋ ๋ฒจ์์ ๊ฒฝํ์ ํ์ด๋ฐ์ ๊ธด ๋จ์ผ ์ปดํฌ๋ํธ๋ก ๋ฌ์ฑ๋ 35โฏยตs ์ฅ๋ฒฝ์ ์ด๊ณผํฉ๋๋ค.
ScopedHandle base_dir = OpenDirectory(L"\\BaseNamedObjects");
HANDLE last_dir = base_dir.get();
std::vector<ScopedHandle> dirs;
for (int i = 0; i < 16000; i++) {
dirs.emplace_back(CreateDirectory(L"A", last_dir));
last_dir = dirs.back().get();
if ((i % 500) == 0) {
auto result = RunTest(GetName(last_dir) + L"\\X", iterations);
printf("%d,%f\n", i + 1, result);
}
}
ํ:
- ๋ถ๋ชจ ๋๋ ํฐ๋ฆฌ๊ฐ ์ค๋ณต์ ๊ฑฐ๋ถํ๊ธฐ ์์ํ๋ฉด ๊ฐ ๋ ๋ฒจ๋ง๋ค ๋ฌธ์(
A/B/C/...)๋ฅผ ๋ฒ๊ฐ์ ์ฌ์ฉํ์ธ์. - ํธ๋ค ๋ฐฐ์ด์ ์ ์งํ์ฌ exploitation ํ ์ฒด์ธ์ ๊น๋ํ๊ฒ ์ญ์ ํด ๋ค์์คํ์ด์ค ์ค์ผ์ ๋ฐฉ์งํ์ธ์.
Slowdown primitive #3 โ Shadow directories, hash collisions & symlink reparses (minutes instead of microseconds)
Object directories๋ shadow directories (fallback lookups)์ ์ํธ๋ฆฌ๋ฅผ ์ํ bucketed hash tables๋ฅผ ์ง์ํฉ๋๋ค. ๋๊ณผ 64-component symbolic-link reparse limit์ ์
์ฉํด UNICODE_STRING ๊ธธ์ด๋ฅผ ์ด๊ณผํ์ง ์์ผ๋ฉด์ slowdown์ ๊ณฑ์
ํ์ธ์:
\BaseNamedObjects์๋์ ๋ ๋๋ ํฐ๋ฆฌ๋ฅผ ์์ฑํ์ธ์. ์:A(shadow) ๋ฐA\A(target). ๋ ๋ฒ์งธ๋ ์ฒซ ๋ฒ์งธ๋ฅผ shadow directory๋ก ์ง์ ํ์ฌ(NtCreateDirectoryObjectEx) ์์ฑํ์ธ์. ์ด๋ ๊ฒ ํ๋ฉดA์์ ํญ๋ชฉ์ด ์์ ๋ lookup์ดA\A๋ก ์ด์ด์ง๋๋ค.- ๊ฐ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋์ผํ ํด์ ๋ฒํท์ ๋ค์ด๊ฐ๋ ์์ฒ ๊ฐ์ colliding names๋ก ์ฑ์ฐ์ธ์(์: ๋์ผํ
RtlHashUnicodeString๊ฐ์ ์ ์งํ๋ฉด์ ๋์๋ฆฌ ์ซ์๋ง ๋ณ๊ฒฝ). ์ด ๊ฒฝ์ฐ lookup์ ๋จ์ผ ๋๋ ํฐ๋ฆฌ ๋ด์์ O(n) ์ ํ ์ค์บ์ผ๋ก ์ ํ๋ฉ๋๋ค. - ์ฝ 63๊ฐ์ object manager symbolic links ์ฒด์ธ์ ๋ง๋ค์ด ๋ฐ๋ณต์ ์ผ๋ก ๊ธด
A\A\โฆ์ ๋ฏธ์ฌ๋ก reparse์์ผ reparse budget์ ์๋ชจํ์ธ์. ๊ฐ reparse๋ ํ์ฑ์ ์ฒ์๋ถํฐ ๋ค์ ์์ํด collision ๋น์ฉ์ ์ฆ๊ฐ์ํต๋๋ค. - ์ต์ข
์ปดํฌ๋ํธ(
...\\0)์ ๋ํ lookup์ ๊ฐ ๋๋ ํฐ๋ฆฌ์ 16โฏ000๊ฐ์ collisions๊ฐ ์์ ๋ Windows 11์์ ์ด์ ๋ถ ๋จ์๊ฐ ๋์ด, one-shot kernel LPEs์์ ์ฌ์ค์ ๋ณด์ฅ๋ race ์น๋ฆฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
ScopedHandle shadow = CreateDirectory(L"\\BaseNamedObjects\\A");
ScopedHandle target = CreateDirectoryEx(L"A", shadow.get(), shadow.get());
CreateCollidingEntries(shadow, 16000, dirs);
CreateCollidingEntries(target, 16000, dirs);
CreateSymlinkChain(shadow, LongSuffix(L"\\A", 16000), 63);
printf("%f\n", RunTest(LongSuffix(L"\\A", 16000) + L"\\0", 1));
์ค์ํ ์ด์ : ๋ช ๋ถ์ ๊ฑธ์น ์ง์ฐ์ one-shot race-based LPEs๋ฅผ ๊ฒฐ์ ์ exploits๋ก ๋ฐ๊ฟ๋๋ค.
race window ์ธก์ ํ๊ธฐ
exploit ๋ด๋ถ์ ๊ฐ๋จํ ํ๋์ค ์ฝ๋๋ฅผ ์ฝ์
ํ์ฌ ํผํด์ ํ๋์จ์ด์์ ์๋์ฐ๊ฐ ์ผ๋ง๋ ์ปค์ง๋์ง ์ธก์ ํ์ธ์. ์๋ ์ค๋ํซ์ ๋์ ์ค๋ธ์ ํธ๋ฅผ iterations๋ฒ ์ด๊ณ QueryPerformanceCounter๋ฅผ ์ฌ์ฉํด ๊ฐ๋ณ ์ด๊ธฐ๋น ํ๊ท ๋น์ฉ์ ๋ฐํํฉ๋๋ค.
static double RunTest(const std::wstring name, int iterations,
std::wstring create_name = L"", HANDLE root = nullptr) {
if (create_name.empty()) {
create_name = name;
}
ScopedHandle event_handle = CreateEvent(create_name, root);
ObjectAttributes obja(name);
std::vector<ScopedHandle> handles;
Timer timer;
for (int i = 0; i < iterations; ++i) {
HANDLE open_handle;
Check(NtOpenEvent(&open_handle, MAXIMUM_ALLOWED, &obja));
handles.emplace_back(open_handle);
}
return timer.GetTime(iterations);
}
The results feed directly into your race orchestration strategy (e.g., number of worker threads needed, sleep intervals, how early you need to flip the shared state).
Exploitation workflow
- Locate the vulnerable open โ ์นด๋ ๊ฒฝ๋ก๋ฅผ ์ถ์ ํฉ๋๋ค (symbols, ETW, hypervisor tracing, ๋๋ reversing ์ฌ์ฉ). ๊ณต๊ฒฉ์๊ฐ ์ ์ดํ๋ ์ด๋ฆ์ด๋ user-writable ๋๋ ํฐ๋ฆฌ์ symbolic link๋ฅผ ์ํํ๋
NtOpen*/ObOpenObjectByNameํธ์ถ์ ์ฐพ์ผ์ธ์. - Replace that name with a slow path
\BaseNamedObjects(๋๋ ๋ค๋ฅธ ์ฐ๊ธฐ ๊ฐ๋ฅํ OM ๋ฃจํธ) ์๋์ ๊ธด ์ปดํฌ๋ํธ ๋๋ ๋๋ ํฐ๋ฆฌ ์ฒด์ธ์ ๋ง๋ญ๋๋ค.- ์ปค๋์ด ๊ธฐ๋ํ๋ ์ด๋ฆ์ด ์ด์ ๋๋ฆฐ ๊ฒฝ๋ก๋ก ํด์๋๋๋ก symbolic link๋ฅผ ๋ง๋ญ๋๋ค. ์๋ ๋์์ ๊ฑด๋๋ฆฌ์ง ์๊ณ ์ทจ์ฝ ๋๋ผ์ด๋ฒ์ ๋๋ ํฐ๋ฆฌ ์กฐํ๋ฅผ ์ฌ๋ฌ๋ถ์ ๊ตฌ์กฐ๋ก ์ ๋ํ ์ ์์ต๋๋ค.
- Trigger the race
- Thread A (victim)๋ ์ทจ์ฝ ์ฝ๋๋ฅผ ์คํํ๊ณ ๋๋ฆฐ ์กฐํ ์์์ ๋ธ๋ก๋ฉ๋๋ค.
- Thread B (attacker)๋ Thread A๊ฐ ๋ฐ์ ๋์ guarded state๋ฅผ ๋ค์ง์ต๋๋ค(์: ํ์ผ ํธ๋ค ๊ต์ฒด, symbolic link ์ฌ์์ฑ, ๊ฐ์ฒด ๋ณด์ ํ ๊ธ).
- Thread A๊ฐ ์ฌ๊ฐ๋์ด ๊ถํ ์๋ ๋์์ ์ํํ ๋, ์ค๋๋(stale) ์ํ๋ฅผ ๊ด์ฐฐํ๊ณ ๊ณต๊ฒฉ์๊ฐ ์ ์ดํ๋ ์์ ์ ์ํํฉ๋๋ค.
- Clean up โ ์์ฌ์ค๋ฌ์ด ํ์ ์ ๋จ๊ธฐ๊ฑฐ๋ ์ ์์ ์ธ IPC ์ฌ์ฉ์๋ฅผ ๊นจ๋จ๋ฆฌ์ง ์๋๋ก ๋๋ ํฐ๋ฆฌ ์ฒด์ธ๊ณผ symbolic link๋ฅผ ์ญ์ ํฉ๋๋ค.
Operational considerations
- Combine primitives โ ๋๋ ํฐ๋ฆฌ ์ฒด์ธ์ ๊ฐ ๋ ๋ฒจ๋ง๋ค ๊ธด ์ด๋ฆ์ ์ฌ์ฉํ๋ฉด
UNICODE_STRINGํฌ๊ธฐ๋ฅผ ์์งํ ๋๊น์ง ์ง์ฐ ์๊ฐ์ ๋ ๋๋ฆด ์ ์์ต๋๋ค. - One-shot bugs โ ํ์ฅ๋ ์๋์ฐ(์์ญ ๋ง์ดํฌ๋ก์ด์์ ์๋ถ)๋ CPU affinity ๊ณ ์ ์ด๋ hypervisor-assisted preemption๊ณผ ๊ฒฐํฉํ๋ฉด โํ ๋ฒ์ ํธ๋ฆฌ๊ฑฐโ ๋ฒ๊ทธ๋ฅผ ํ์ค์ ์ผ๋ก ๋ง๋ญ๋๋ค.
- Side effects โ ๋๋ ค์ง๋ ํจ๊ณผ๋ ์ ์์ ์ธ ๊ฒฝ๋ก์๋ง ๊ตญํ๋๋ฏ๋ก ์ ์ฒด ์์คํ ์ฑ๋ฅ์๋ ์ํฅ์ ๊ฑฐ์ ์ฃผ์ง ์์ต๋๋ค; ๋ฐฉ์ด์๋ namespace ์ฆ๊ฐ๋ฅผ ๋ชจ๋ํฐ๋งํ์ง ์์ผ๋ฉด ๊ฑฐ์ ๋์น์ฑ์ง ๋ชปํฉ๋๋ค.
- Cleanup โ ๋ง๋ ๋ชจ๋ ๋๋ ํฐ๋ฆฌ/๊ฐ์ฒด์ ๋ํ ํธ๋ค์ ์ ์งํ์ฌ ์ดํ
NtMakeTemporaryObject/NtClose๋ฅผ ํธ์ถํ์ธ์. ๊ทธ๋ ์ง ์์ผ๋ฉด ๋ฌดํํ ๋๋ ํฐ๋ฆฌ ์ฒด์ธ์ด ์ฌ๋ถํ ํ์๋ ๋จ์ ์ ์์ต๋๋ค.
Defensive notes
- named objects์ ์์กดํ๋ kernel ์ฝ๋๋ open ์ดํ์ ๋ณด์์ ๋ฏผ๊ฐํ ์ํ๋ฅผ ์ฌ๊ฒ์ฆํ๊ฑฐ๋(๋๋ ์ฒดํฌ ์ ์ ๋ ํผ๋ฐ์ค๋ฅผ ํ๋ณด) TOCTOU ๊ฒฉ์ฐจ๋ฅผ ๋ฉ์์ผ ํฉ๋๋ค.
- user-controlled ์ด๋ฆ์ ์ญ์ฐธ์กฐ(dereference)ํ๊ธฐ ์ ์ OM ๊ฒฝ๋ก ๊น์ด/๊ธธ์ด์ ๋ํ ์ํ์ ๊ฐ์ ํ์ธ์. ์ง๋์น๊ฒ ๊ธด ์ด๋ฆ์ ๊ฑฐ๋ถํ๋ฉด ๊ณต๊ฒฉ์๋ ๋ง์ดํฌ๋ก์ด ์ฐฝ์ผ๋ก ๋ค์ ๋ฐ๋ ค๋ฉ๋๋ค.
- ๊ฐ์ฒด ๊ด๋ฆฌ์ ๋ค์์คํ์ด์ค์ ์ฑ์ฅ(ETW
Microsoft-Windows-Kernel-Object)์ ๊ณ์ธกํ์ฌ\BaseNamedObjects์๋ ์์ฒ ๊ฐ ์ปดํฌ๋ํธ ์ฒด์ธ ๊ฐ์ ์์ฌ์ค๋ฌ์ด ์ฆ๊ฐ๋ฅผ ํ์งํ์ธ์.
References
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


