일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- vcruntime140.dll
- arudino
- IAT Hooking
- Windows Kernel Debug
- Windows
- 네트워크 바이트 오더
- 윈도우 커널
- 포너블
- Msvcrt.dll
- ucrtbase.dll
- Windows Kernel
- 윈도우 커널 디버깅
- Network Byte Order
- vcruntime.dll
- pcap packet capture
- 개발하기
- windows kernel debugging
- pcap packet
- 윈도우 커널 드라이버
- 시스템해킹
- 바이트 오더
- packet capture
- hacking
- Windows Kernel Driver
- 개발 환경 준비
- 해킹
- C언어 패킷캡쳐
- apphelp.dll
- HackCTF
- pwnable
- Today
- Total
미친해커
[Windows] Instrumentation Callback 응용하기 - syscall detect 본문
[Windows] Instrumentation Callback 응용하기 - syscall detect
미친해커 2022. 8. 15. 06:50GitHub - jungjin0003/Instrumentation-Callback
Contribute to jungjin0003/Instrumentation-Callback development by creating an account on GitHub.
github.com
Instrumentation Callback을 통해 알 수 있는 것
지금까지의 포스팅만 봤을 때 Instrumentation Callback은 그저 syscall 어셈블리가 실행되었다는 정보 밖에 알 수 없었다. 하지만 Instrumentation Callback은 그 외에도 아래와 같은 정보들을 구할 수 있다.
- Original Return Address (sysret 가 되었을 때 원래 돌아가야 할 주소)
- Syscall Number
- Function Name
How Do I Get The Above Information?
Instrumentation Callback으로 등록된 함수가 호출되었을 때 r10 레지스터에는 원래 돌아가야 할 리턴 주소가 기록되어 있다. 이를 보고 어떠한 커널 함수를 호출했는지 알아낼 수 있다.
What is The Syscall Detect?
결국 tracking와 크게 다를게 없다. 하지만 이번 응용하기에서 다른점은 syscall instruction을 호출한 주소가 실제 ntdll.dll 또는 win32u.dll가 아니라면 프로그램 실행을 중지하는 원리이다.
Sample
#include <stdio.h>
#include <windows.h>
#pragma comment (lib, "ntdll.lib")
#define PROCESS_INFO_CLASS_INTRUMENTATION 40
#define RIP_SANITY_CHECK(Rip,BaseAddress,ModuleSize) (Rip > BaseAddress) && (Rip < (BaseAddress + ModuleSize))
NTSYSAPI NTSTATUS NTAPI NtSetInformationProcess(HANDLE ProcessHandle, PROCESS_INFORMATION_CLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength);
#ifdef __GUNC__
__declspec(naked) NTSTATUS SystemCall(ULONG number)
{
__asm__ __volatile__ ("mov rax, r10");
__asm__ __volatile__ ("syscall");
__asm__ __volatile__ ("ret");
}
#elif _MSC_VER
extern PVOID GetSyscallReturnAddress();
extern NTSTATUS SystemCall(ULONG number);
#endif
typedef struct _PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION
{
ULONG Version;
ULONG Reserved;
PVOID Callback;
} PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION, *PPROCESS_INSTRUMENTATION_CALLBACK_INFORMATION;
VOID CALLBACK InstrumentationCallback()
{
static HANDLE NtdllBase;
static HANDLE Win32uBase;
PVOID ReturnAddress = NULL;
#ifdef __GNUC__
__asm__ __volatile__ (
"mov %[ReturnAddress], r10\n\t"
:
: [ReturnAddress] "m" (ReturnAddress)
);
#elif _MSC_VER
ReturnAddress = GetSyscallReturnAddress();
#else
#error This compiler is not supported. Please checck the compiler or target OS
#endif
if (NtdllBase == NULL)
NtdllBase = GetModuleHandleA("ntdll.dll");
if (Win32uBase == NULL)
Win32uBase = GetModuleHandleA("win32u.dll");
DWORD NtdllSize = ((IMAGE_NT_HEADERS *)((ULONG_PTR)NtdllBase + ((IMAGE_DOS_HEADER *)NtdllBase)->e_lfanew))->OptionalHeader.SizeOfImage;
DWORD Win32uSize = Win32uBase == NULL ? 0 : ((IMAGE_NT_HEADERS *)((ULONG_PTR)Win32uBase + ((IMAGE_DOS_HEADER *)Win32uBase)->e_lfanew))->OptionalHeader.SizeOfImage;
if (!(RIP_SANITY_CHECK(ReturnAddress, (ULONG_PTR)NtdllBase, NtdllSize)) || (Win32uBase != NULL && !(RIP_SANITY_CHECK(ReturnAddress, (ULONG_PTR)Win32uBase, Win32uSize))))
{
printf("[SYSCALL-DETECT] Kernel returns to unverified module, preventing further execution!\n");
__debugbreak();
}
return;
}
int main(int argc, char *argv[])
{
PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION nirvana;
nirvana.Version = 0;
nirvana.Reserved = 0;
nirvana.Callback = InstrumentationCallback;
NtSetInformationProcess(GetCurrentProcess(), PROCESS_INFO_CLASS_INTRUMENTATION, &nirvana, sizeof(PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION));
SystemCall(0x46); // NtYieldExecution
printf("[SYSTEM] Successfully executed the syscall instruction\n");
return 0;
}
MSVC 컴파일용 어셈블리
; File : extern.asm
_TEXT SEGMENT
PUBLIC GetSyscallReturnAddress
PUBLIC SystemCall
GetSyscallReturnAddress PROC
mov rax, r10
ret
GetSyscallReturnAddress ENDP
SystemCall PROC
mov rax, rcx
syscall
ret
SystemCall ENDP
_TEXT ENDS
END
=====GCC=====
CommandLine : gcc.exe main.c -o main.exe -lntdll -masm=intel
=====MSVC====
CommandLine : ml64.exe /c extern.asm => result : extern.obj
CommandLink : cl.exe main.c extern.obj /Od /Z7 /link /MANIFEST:NO /DEBUG:FULL /OPT:REF /OPT:ICF /OPT:LBR
실행 결과
$ main.exe
[SYSCALL-DETECT] Kernel returns to unverified module, preventing further execution!
Reference
Detecting Manual Syscalls from User Mode - Winternl
By now direct system calls are ubiquitous in offensive tooling. Manual system calls remain effective for evading userland based EDRs. From within userland, there has been little answer to this powerful technique. Such syscalls can be effectively mitigated
winternl.com
'Windows > Instrumentation Callback' 카테고리의 다른 글
[Windows] Instrumentation Callback 응용하기 - syscall tracking (0) | 2022.08.02 |
---|---|
[Windows] Instrumentation Callback 등록하기 (0) | 2022.08.02 |
[Windows] Instrumentation Callback이란? (0) | 2022.08.01 |