我試圖冒充具有SYSTEM特權的客戶。
我注意到這個客戶端試圖連接到命名管道:\\.\pipe\abc。
我設定了一個命名管道服務器\\.\pipe\abc并等待它連接。
一旦連接,它就失敗了:
[ ] Creating pipe server
[ ] Waiting for client to connect
[ ] Client connected
[ ] Client impersonated!
[ ] Failed to get thread token! 1347
根據 Microsoft的錯誤 1347 :
ERROR_CANT_OPEN_ANONYMOUS
1347 (0x543)
無法打開匿名級別的安全令牌。
為什么會這樣?它成功模擬但隨后未能打開執行緒。
這是我的代碼,直到OpenThreadToken.
SECURITY_ATTRIBUTES SecurityAttrs = {
sizeof(SECURITY_ATTRIBUTES),
NULL, // assigned access token of calling process
FALSE
};
DWORD openMode = PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | WRITE_OWNER;
DWORD pipeMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT;
std::cout << "[ ] Creating pipe server\n";
for (;;) {
// create the named pipe
HANDLE pipe = NULL;
DWORD msgSize = 1024;
pipe = CreateNamedPipeA(
"\\\\.\\pipe\\abc",
openMode,
pipeMode,
1, // max instances
msgSize, // out buffer size
msgSize, // in buffer size
0, // timeout. 0 ~= 50ms
&SecurityAttrs);
if (pipe == INVALID_HANDLE_VALUE) {
DWORD err = GetLastError();
std::cout << "[!] Pipe creation failed! " << err << std::endl;
return err;
}
// wait for client to connect
std::cout << "[ ] Waiting for client to connect\n";
bool connected = ConnectNamedPipe(pipe, NULL) ? true : (
GetLastError() == ERROR_PIPE_CONNECTED);
if (!connected)
continue;
std::cout << "[ ] Client connected\n";
// read from pipe
char buf[msgSize];
DWORD bytesread = 0;
bool status = ReadFile(
pipe,
&buf,
msgSize,
&bytesread,
NULL);
// impersonate the connector
if (!ImpersonateNamedPipeClient(pipe)) {
DWORD err = GetLastError();
std::cout << "[!] Impersonation failed! " << err << std::endl;
return -1;
}
std::cout << "[ ] Client impersonated!\n";
HANDLE hToken = {};
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, false, &hToken)) {
DWORD err = GetLastError();
std::cout << "[!] Failed to get thread token! " << err << std::endl;
return err;
}
uj5u.com熱心網友回復:
根據OpenThreadToken,
如果令牌具有匿名模擬級別,則不會打開令牌,并且 OpenThreadToken 將 ERROR_CANT_OPEN_ANONYMOUS 設定為錯誤。
并且根據模仿級別,
命名管道、RPC 或 DDE 連接的客戶端可以控制模擬級別。例如,命名管道客戶端可以呼叫 CreateFile 函式來打開命名管道的句柄并指定服務器的模擬級別。
當命名管道、RPC 或 DDE 連接是遠程的時,傳遞給 CreateFile 以設定模擬級別的標志將被忽略。在這種情況下,客戶端的模擬級別由服務器啟用的模擬級別確定,該級別由目錄服務中服務器帳戶上的標志設定。例如,如果服務器啟用了委派,則客戶端的模擬級別也將設定為委派,即使傳遞給 CreateFile 的標志指定了標識模擬級別。
您的命名管道客戶端確實需要呼叫該CreateFile函式來打開命名管道的句柄并指定服務器的模擬級別。
uj5u.com熱心網友回復:
基于注釋,在客戶端代碼中 -
FILE_FLAG_OPEN_NO_RECALL | FILE_FLAG_OVERLAPPED;
如果在呼叫中放置 dwFlagsAndAttributes,則使用CreateFile
但是需要注意FILE_FLAG_OPEN_NO_RECALL == (SECURITY_SQOS_PRESENT|SECURITY_ANONYMOUS)和FILE_FLAG_OPEN_NO_RECALL == SECURITY_SQOS_PRESENT
這兩個標志都具有相同的二進制值0x00100000(和SECURITY_ANONYMOUS == 0)
認為這是CreateFileapi設計的問題。它具有較少的引數,比較NtCreateFile它并嘗試將不同的引陣列合在一起。例如在單個dwFlagsAndAttributescombine FileAttributes CreateOptions中ObjectAttributes->SecurityQualityOfService。所以引數是“多載”
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/430536.html
上一篇:如何使彈出視窗出現在App的TASKBAR按鈕的確切位置
下一篇:如何在kotlin中簡化此代碼?
