
Frida 기반 동적 분석 도구로, 런타임 인스트루먼테이션과 IAT 파싱을 통해 Windows 실행 파일에서 DLL 사이드로딩 및 COM 하이재킹 취약점을 자동으로 식별합니다.
Windows Feature Hunter (WFH)는 Frida, 동적 계측 도구 키트를 사용하여 Windows 실행 파일 내의 일반적인 "취약점" 또는 "기능"을 잠재적으로 식별하는 데 도움을 주는 개념 증명 파이썬 스크립트입니다. WFH는 현재 대규모로 잠재적인 DLL(Dynamic Linked Library) 사이드로딩 및 COM(Component Object Model) 하이재킹 기회를 자동으로 식별할 수 있습니다.
DLL 사이드로딩은 Windows side-by-side(WinSXS) 어셈블리를 사용하여 side-by-side(SXS) 목록에서 악성 DLL을 로드합니다. COM 하이재킹은 공격자가 COM 참조 및 관계를 하이재킹하여 합법적인 소프트웨어 대신 실행될 수 있는 악성 코드를 삽입할 수 있게 합니다. WFH는 잠재적인 취약점을 출력하고 대상 Windows 실행 파일의 잠재적 취약점을 포함하는 CSV 파일을 작성합니다.
pip install -r requirements.txt
PS C:\Tools\WFH > python .\wfh.py -h
usage: wfh.py [-h] -t T [T ...] -m {dll,com} [-v] [-timeout TIMEOUT]
Windows Feature Hunter
optional arguments:
-h, --help show this help message and exit
-t T [T ...], -targets T [T ...]
list of target windows executables
-m {dll,com}, -mode {dll,com}
vulnerabilities to potentially identify
-v, -verbose verbose output from Frida instrumentation
-timeout TIMEOUT timeout value for Frida instrumentation
EXAMPLE USAGE
NOTE: It is recommended to copy target binaries to the same directory as wfh for identifying DLL Sideloading
DLL Sideloading Identification (Single): python wfh.py -t .\mspaint.exe -m dll
DLL Sideloading Identification (Verbose): python wfh.py -t .\mspaint.exe -m dll -v
DLL Sideloading Identification (Timeout 30s): python wfh.py -t .\mspaint.exe -m dll -timeout 30
DLL Sideloading Identification (Wildcard): python wfh.py -t * -m dll
DLL Sideloading Identification (List): python wfh.py -t .\mspaint.exe .\charmap.exe -m dll
COM Hijacking Identification (Single): python wfh.py -t "C:\Program Files\Internet Explorer\iexplore.exe" -m com
COM Hijacking Identification (Verbose): python wfh.py -t "C:\Program Files\Internet Explorer\iexplore.exe" -m com -v
COM Hijacking Identification (Timeout 60s): python wfh.py -t "C:\Program Files\Internet Explorer\iexplore.exe" -m com -timeout 60
COM Hijacking Identification (Wildcard): python wfh.py -t * -m com -v
COM Hijacking Identification (List): python wfh.py -t "C:\Program Files\Internet Explorer\iexplore.exe" "C:\Windows\System32\notepad.exe" -m com -v
먼저 분석하려는 바이너리를 WFH와 같은 디렉토리로 복사해야 합니다.
PS C:\Tools\WFH > copy C:\Windows\System32\mspaint.exe .
PS C:\Tools\WFH > copy C:\Windows\System32\charmap.exe .
PS C:\Tools\WFH > dir
Directory: C:\Tools\WFH
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 5/14/2021 2:12 PM .vscode
-a---- 5/6/2021 2:39 PM 1928 .gitignore
-a---- 12/7/2019 2:09 AM 198656 charmap.exe
-a---- 5/18/2021 7:39 AM 6603 loadlibrary.js
-a---- 4/7/2021 12:48 PM 988160 mspaint.exe
-a---- 5/18/2021 7:53 AM 8705 README.md
-a---- 5/17/2021 11:27 AM 5948 registry.js
-a---- 5/6/2021 2:41 PM 11 requirements.txt
-a---- 5/18/2021 8:35 AM 10623 wfh.py
이제 wfh를 바이너리에 대해 실행하여 DLL 사이드로딩 기회를 식별할 수 있습니다.
PS C:\Tools\WFH > python .\wfh.py -t * -m dll
==================================================
Running Frida against charmap.exe
--------------------------------------------------
[+] Potential DllMain Sideloading: LoadLibraryW,LPCWSTR: MSFTEDIT.DLL
[+] Potential DllMain Sideloading: LoadLibraryExW,LPCWSTR : MSFTEDIT.DLL, dwFlags : NONE
[*] Writing raw Frida instrumentation to charmap.exe-raw.log
[*] Writing Potential DLL Sideloading to charmap.exe-sideload.log
--------------------------------------------------
==================================================
Running Frida against mspaint.exe
--------------------------------------------------
[+] Potential DllMain Sideloading: LoadLibraryExW,LPCWSTR : gdiplus.dll, dwFlags : NONE
[-] Potential DllExport Sideloading: GetProcAddress,hModule : C:\WINDOWS\WinSxS\amd64_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.19041.789_none_faf0a7e97612e7bb\gdiplus.dll, LPCSTR: GdiplusStartup
[+] Potential DllMain Sideloading: LoadLibraryW,LPCWSTR: MSFTEDIT.DLL
[+] Potential DllMain Sideloading: LoadLibraryExW,LPCWSTR : MSFTEDIT.DLL, dwFlags : NONE
[*] Writing raw Frida instrumentation to mspaint.exe-raw.log
[*] Writing Potential DLL Sideloading to mspaint.exe-sideload.log
--------------------------------------------------
==================================================
[*] Writing dll results to dll_results.csv
PS C:\Tools\WFH > type .\dll_results.csv
Executable,WinAPI,DLL,EntryPoint / WinAPI Args
charmap.exe,LoadLibraryW,LPCWSTR: MSFTEDIT.DLL
charmap.exe,LoadLibraryExW,LPCWSTR : MSFTEDIT.DLL, dwFlags : NONE
mspaint.exe,LoadLibraryExW,LPCWSTR : gdiplus.dll, dwFlags : NONE
mspaint.exe,GetProcAddress,hModule : C:\WINDOWS\WinSxS\amd64_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.19041.789_none_faf0a7e97612e7bb\gdiplus.dll, LPCSTR: GdiplusStartup
mspaint.exe,LoadLibraryW,LPCWSTR: MSFTEDIT.DLL
mspaint.exe,LoadLibraryExW,LPCWSTR : MSFTEDIT.DLL, dwFlags : NONE
더 자세한 출력을 원한다면 "-v"를 사용하여 Frida가 Windows API 호출을 계측하는 모든 메시지를 볼 수 있습니다. 이 출력은 원시 로그 파일에서도 확인할 수 있습니다.
PS C:\Tools\WFH > python .\wfh.py -t * -m dll -v
==================================================
Running Frida against charmap.exe
{'type': 'send', 'payload': 'LoadLibraryW,LPCWSTR: MSFTEDIT.DLL'}
{'type': 'send', 'payload': 'LoadLibraryExW,LPCWSTR : MSFTEDIT.DLL, dwFlags : NONE'}
--------------------------------------------------
[+] Potential DllMain Sideloading: LoadLibraryW,LPCWSTR: MSFTEDIT.DLL
[+] Potential DllMain Sideloading: LoadLibraryExW,LPCWSTR : MSFTEDIT.DLL, dwFlags : NONE
[*] Writing raw Frida instrumentation to charmap.exe-raw.log
[*] Writing Potential DLL Sideloading to charmap.exe-sideload.log
--------------------------------------------------
==================================================
Running Frida against mspaint.exe
{'type': 'send', 'payload': 'LoadLibraryExW,LPCWSTR : gdiplus.dll, dwFlags : NONE'}
{'type': 'send', 'payload': 'GetProcAddress,hModule : C:\\WINDOWS\\WinSxS\\amd64_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.19041.789_none_faf0a7e97612e7bb\\gdiplus.dll, LPCSTR: GdiplusStartup'}
{'type': 'send', 'payload': 'LoadLibraryW,LPCWSTR: MSFTEDIT.DLL'}
{'type': 'send', 'payload': 'LoadLibraryExW,LPCWSTR : MSFTEDIT.DLL, dwFlags : NONE'}
--------------------------------------------------
[+] Potential DllMain Sideloading: LoadLibraryExW,LPCWSTR : gdiplus.dll, dwFlags : NONE
[-] Potential DllExport Sideloading: GetProcAddress,hModule : C:\WINDOWS\WinSxS\amd64_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.19041.789_none_faf0a7e97612e7bb\gdiplus.dll, LPCSTR: GdiplusStartup
[+] Potential DllMain Sideloading: LoadLibraryW,LPCWSTR: MSFTEDIT.DLL
[+] Potential DllMain Sideloading: LoadLibraryExW,LPCWSTR : MSFTEDIT.DLL, dwFlags : NONE
[*] Writing raw Frida instrumentation to mspaint.exe-raw.log
[*] Writing Potential DLL Sideloading to mspaint.exe-sideload.log
--------------------------------------------------
==================================================
[*] Writing dll results to dll_results.csv
PS C:\Tools\WFH > python .\wfh.py -t "C:\Program Files\Internet Explorer\iexplore.exe" -m com
==================================================
Running Frida against C:\Program Files\Internet Explorer\iexplore.exe
--------------------------------------------------
[+] Potential COM Hijack: Path : HKEY_LOCAL_MACHINE\Software\Classes\CLSID\{0E5AAE11-A475-4C5B-AB00-C66DE400274E}\InProcServer32,lpValueName : null,Type : REG_EXPAND_SZ, Value : %SystemRoot%\system32\Windows.Storage.dll
[+] Potential COM Hijack: Path : HKEY_CLASSES_ROOT\CLSID\{1FD49718-1D00-4B19-AF5F-070AF6D5D54C}\InProcServer32,lpValueName : null,Type : REG_SZ, Value : C:\Program Files (x86)\Microsoft\Edge\Application\90.0.818.62\BHO\ie_to_edge_bho_64.dll
[*] Writing raw Frida instrumentation to .\iexplore.exe-raw.log
[*] Writing Potential COM Hijack to .\iexplore.exe-comhijack.log
--------------------------------------------------
==================================================
[*] Writing dll results to comhijack_results.csv
모든 네이티브 Windows 서명된 바이너리를 wfh 디렉토리에 복사하십시오.
Get-ChildItem c:\ -File | ForEach-Object { if($_ -match '.+?exe$') {Get-AuthenticodeSignature $_.fullname} } | where {$_.IsOSBinary} | ForEach-Object {Copy-Item $_.path . }
DLL 사이드로딩 기회를 찾으십시오.
python wfh.py -t * -m dll
COM 하이재킹 기회를 찾으십시오.
python wfh.py -t * -m com
Windows Feature Hunter Dridex (WFH Dridex)는 Dridex loader에서 영감을 받은 개념 증명 파이썬 스크립트입니다. WFH Dridex는 대상 실행 파일의 IAT(Import Address Table)를 분석하고, 실행 파일의 IAT에 있는 각 항목에 대해 DLL을 컴파일한 다음 DLL 사이드로드가 식별되었는지 확인합니다.
원래 WFH 릴리스는 약 96개의 잠재적 DLL 사이드로딩 기회를 식별했습니다. WFH Dridex는 약 966개의 검증된 DLL 사이드로딩 기회를 식별했습니다.
pip install -r requirements.txt
g++.exe는 WFH Dridex가 제대로 작동하려면 설치 후 PATH 환경 변수에 추가되어야 합니다.
먼저 분석하려는 바이너리를 WFH Dridex와 같은 디렉토리로 복사해야 합니다.
❯ cp C:\Windows\System32\mspaint.exe .
❯ cp C:\Windows\System32\charmap.exe .
❯ python .\wfh_dridex.py
[*] Creating a payload for charmap.exe with GetUName.dll
|_ Compiling with: g++.exe -s -Os -static -shared -fpermissive -oGetUName.dll dllmain.c
|_ Testing charmap.exe with GetUName.dll for DLL sideloading opportunity
|_ PID: 8936
[>] Listing working DLL sideloads
|_ charmap.exe GetUName.dll
[*] Creating a payload for mspaint.exe with MFC42u.dll
|_ Compiling with: g++.exe -s -Os -static -shared -fpermissive testaroo.def -oMFC42u.dll dllmain.c
|_ Testing mspaint.exe with MFC42u.dll for DLL sideloading opportunity
|_ PID: 9472
[*] Creating a payload for mspaint.exe with PROPSYS.dll
|_ Compiling with: g++.exe -s -Os -static -shared -fpermissive -oPROPSYS.dll dllmain.c
|_ Testing mspaint.exe with PROPSYS.dll for DLL sideloading opportunity
|_ PID: 11308
[*] Creating a payload for mspaint.exe with WINMM.dll
|_ Compiling with: g++.exe -s -Os -static -shared -fpermissive -oWINMM.dll dllmain.c
|_ Testing mspaint.exe with WINMM.dll for DLL sideloading opportunity
|_ PID: 180
[>] Listing working DLL sideloads
|_ mspaint.exe MFC42u.dll
|_ mspaint.exe PROPSYS.dll
|_ mspaint.exe WINMM.dll
이제 WFH Dridex를 바이너리에 대해 실행하여 DLL 사이드로딩 기회를 식별할 수 있습니다.
❯ gc .\results.csv
Executable,DllName
charmap.exe,GetUName.dll
mspaint.exe,MFC42u.dll
mspaint.exe,PROPSYS.dll
mspaint.exe,WINMM.dll
C:\Windows\System32에 대해 실행된 WFH Dridex의 샘플 CSV 출력은 여기에서 확인할 수 있습니다.
원래 WFH 릴리스는 약 96개의 잠재적 DLL 사이드로딩 기회를 식별했습니다. WFH Dridex는 약 966개의 검증된 DLL 사이드로딩 기회를 식별했습니다.
WFH Dridex 릴리스의 일환으로, 풀 리퀘스트가 Wietze의 HijackLibs 프로젝트에 제출되었으며, 여기에는 507개의 새로운 항목이 포함되었습니다.