如何设计一个CobaltStrike的Job管理机制

admin 2025年2月22日00:11:27评论10 views字数 2303阅读7分40秒阅读模式

如何设计一个CobaltStrike的Job管理机制

CobaltStrike的job管理机制,主要是提供给操作者,撤销一些类似耗时等不想继续运行的任务的能力。主要用在长时间的命令执行,大文件的下载等过程中 (注意这个job并不是windows系统自身的job机制)

如何实现

定义数据结构

语言使用c/c++,首先我们需要定义一个结构体,用于保存每个job的状态,其中包含任务id,任务进程id,读写管道句柄等信息。
同时,我们后续要对所有的job进行查找,添加,删除操作,所以我们需要一个数据结构,在高级语言中有很多方式可以实现,在c/c++ 我们可以通过链表的方式来搞定:

typedefstruct_JOB_NODE
{
int jobid;
int pid
    HANDLE process;
    HANDLE hRead;
    HANDLE hWrite;
struct_JOB_NODE* next;
} JOB_NODE;

以上就是一个最精简的job状态结构,你也可以加一些自己的定义进去,比如描述信息之类的。

命令执行引入job机制

然后我们看,如何在进程中使用job机制:
首先你要思考,通过job kill掉一个正常长时间运行,并且在不断的输出信息的过程中会设计到哪些东西。
首先读写管道也要涉及到,因为我们关闭管道后,就不会回读取输出,其次进程句柄要涉及到,因为我们要去kill掉这个进程,释放资源,不然进程会一直都在。
代码大致如下:

    STARTUPINFOA si = { sizeof(si) };
    PROCESS_INFORMATION pi = { 0 };
    SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
    HANDLE hRead, hWrite;
CreatePipe(&hRead, &hWrite, &sa, 0x100000);
    si.hStdInput = NULL;
    si.hStdOutput = hWrite;
    si.hStdError = hWrite;
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
CreateProcessA(NULL,commandline,NULL,NULL,true,CREATE_NO_WINDOW,NULL,NULL,&si,&pi)
if(waitforsingleobject(pi.hprocess,5000)==WAIT_TIMEOUT)
    {
Jobadd();
         ........
    }

这里有一个细节,我们创建了进程后,会等待一段时间,因为很多命令执行可能一下就完了,这种我们没必要加入到job管理中,我们只针对那些长时间运行的任务。

添加job

添加job的过程,其实就是在链表中加入节点的一个简单的算法,你可以直接让gpt给你生出一个:

JOB_NODE* GobalJobs = NULL;
JOB_NODE* JobAdd(JOB_NODE* newJob)
{
static DWORD JobCurrentId = 0;

    JOB_NODE* job = GobalJobs;
    newJob->id = JobCurrentId++;
if (job)
    {
while (job->next)
            job = job->next;

        job->next = newJob;
    }
else
    {
        GobalJobs = newJob;
    }
return job;
}

这是一个尾插的方式。
但是在插入之前,你要初始化一些job结构体,把需要赋值的变量赋值一下,比如进程句柄,管道句柄。

jobkill

jobkill中所做的事其实就是关闭相关的句柄,结束对应的进程,但是cobaltstike中好像只是关闭了管道的句柄,使得不再打印输出,但进程实际还是运行的,需要等它自己结束。结束完后,再把job从链表中删除。

for (JOB_NODE* job = GobalJobs; job; job = job->next)
{
if (job->jobid == id)
    {
TerminateProcess(job->process,0);
CloseHandle(job->process);
CloseHandle(job->hRead);
CloseHandle(job->hWrite);
JobRemove(id);
     }
}
voidJobRemove(int id){
    JOB_NODE* prev = NULL;
    JOB_NODE** pNext;
for (JOB_NODE* job = GobalJobs; job; job = *pNext)
    {
if (job->jobid == id)
        {
            prev = job;
            pNext = &job->next;
continue;
        }
if (prev)
            pNext = &prev->next;
else
            pNext = &GobalJobs;
        *pNext = job->next;
free(job);
    }

}

以上代码都可以让gpt给你搞定,自己修一下就行了。

整体的代码逻辑就是大概这样,文章也只是为了简单说明一下这种job任务管理机制,并且本文也只是涉及到了命令执行这一个方面,像Cobaltstrike中涉及到的文件下次的job,后渗透的一些都没有涉及,不过这些都是大同小异的,可以根据自己的需求来逐步添加!

原文始发于微信公众号(黑晶):如何设计一个CobaltStrike的Job管理机制

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月22日00:11:27
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   如何设计一个CobaltStrike的Job管理机制https://cn-sec.com/archives/3768478.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息