探索Windows内核系列——句柄,利用句柄进行进程保护
方便在R3查看句柄信息的小工具
我们可以使用微软官方的工具Process Explorer来查看文件或进程被哪个进程使用着,它的官方文档在这里。
比如我使用CE打开了notepad.exe,使用Process Explorer查找句柄功能,搜索notepad.exe,即可找到对应占用它的进程。这在我们想删除一个文件却提示"该文件已被占用"时非常有用,可以直接搜索到占用它的进程。
句柄在内核中的存在形式
本节将通过实时内核调试结合逆向查看内核源代码的方式,来探索内核中的句柄结构。句柄结构经历各个windows版本到现在,变化非常大,这里使用的系统是Win10 1809。
Windows系统的句柄表主要有三种,第一种是系统全局PspCidTable句柄表,保存所有进程和线程的句柄,第二种是进程内部句柄表,保存该进程所打开的内核对象句柄,最后一种是系统进程system的全局句柄表,这几种句柄表对应的格式都是一样的。我们主要介绍进程中的句柄表。
_EPROCESS是进程在内核中内核对象结构,每个进程在内核中都有一个这样对应的内核结构来记录进程的信息。EPOCESS结构中的ObjectTable即该进程所有的句柄表,ObjectTable中的TableCode指向handle_table_entrys的首地址。
<center>EPROCESS -> HANDLE_TABLE -> handle_table_entry </center>
TableCode事实上比上图描述的要复杂一点点,句柄表是一个多层结构,TableCode的低两位代表了句柄表的层数。若低两位为0,则TableCode直接指向一个存放handle_table_entrys的表,若低两位为1则TableCode指向一个中间的句柄表,该表里存放的也是"TableCode";同理若TableCode低两位为3,则往后还有两层TableCode表。
从EPROCESS中找到ObjectTable,即句柄表 _HANDLE_TABLE
查看句柄表的TableCode
这里TableCode为0xffffa08c`9ec4f001,最低为1,则表示后续还有一层TableCode表。去除TableCode的低两位,查看一下内容,表里只有两项TableCode,且它们的低两位均为0,表示它们指向的就是handle_table_entrys的基址。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
方便在R3查看句柄信息的小工具
我们可以使用微软官方的工具Process Explorer来查看文件或进程被哪个进程使用着,它的官方文档在这里。
比如我使用CE打开了notepad.exe,使用Process Explorer查找句柄功能,搜索notepad.exe,即可找到对应占用它的进程。这在我们想删除一个文件却提示"该文件已被占用"时非常有用,可以直接搜索到占用它的进程。
句柄在内核中的存在形式
本节将通过实时内核调试结合逆向查看内核源代码的方式,来探索内核中的句柄结构。句柄结构经历各个windows版本到现在,变化非常大,这里使用的系统是Win10 1809。
Windows系统的句柄表主要有三种,第一种是系统全局PspCidTable句柄表,保存所有进程和线程的句柄,第二种是进程内部句柄表,保存该进程所打开的内核对象句柄,最后一种是系统进程system的全局句柄表,这几种句柄表对应的格式都是一样的。我们主要介绍进程中的句柄表。
_EPROCESS是进程在内核中内核对象结构,每个进程在内核中都有一个这样对应的内核结构来记录进程的信息。EPOCESS结构中的ObjectTable即该进程所有的句柄表,ObjectTable中的TableCode指向handle_table_entrys的首地址。
<center>EPROCESS -> HANDLE_TABLE -> handle_table_entry </center>
TableCode事实上比上图描述的要复杂一点点,句柄表是一个多层结构,TableCode的低两位代表了句柄表的层数。若低两位为0,则TableCode直接指向一个存放handle_table_entrys的表,若低两位为1则TableCode指向一个中间的句柄表,该表里存放的也是"TableCode";同理若TableCode低两位为3,则往后还有两层TableCode表。
从EPROCESS中找到ObjectTable,即句柄表 _HANDLE_TABLE
查看句柄表的TableCode
这里TableCode为0xffffa08c`9ec4f001,最低为1,则表示后续还有一层TableCode表。去除TableCode的低两位,查看一下内容,表里只有两项TableCode,且它们的低两位均为0,表示它们指向的就是handle_table_entrys的基址。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
CobaltStrike Beacon生成原理
反编译的一个CobaltStrike4.1版本,所以不在需要重新反编译了。如下是工作目录。decomplie_src是存储着CS反编译的代码,lib目录存储着cobaltstrike4.1.jar文件,作为库文件。out作为编译输出的目录,src存放着所需要的源码文件,也就是decomplie_src源码的子集。这里需要使用的工具是IDEA。
把反编译之后的decomplie_src目录里面的所有java文件复制到项目中的decomplie_src,并把cobaltstrike4.1.jar文件放到项目中的lib目录。
对项目进行设置,添加模块依赖,在路径File-->Project Structure-->Modules-->Dependencies设置SDK。然后在Dependencies这个页面点一下"+"号,添加jar包,完成后点应用。
进入Artifacts-->JAR-->From modules with dependencies,设置一个MAIN CLASS为aggressor.Aggressor,这个值可以在MANIFEST.MF文件中查看。完成之后就是这样的结果。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
反编译的一个CobaltStrike4.1版本,所以不在需要重新反编译了。如下是工作目录。decomplie_src是存储着CS反编译的代码,lib目录存储着cobaltstrike4.1.jar文件,作为库文件。out作为编译输出的目录,src存放着所需要的源码文件,也就是decomplie_src源码的子集。这里需要使用的工具是IDEA。
把反编译之后的decomplie_src目录里面的所有java文件复制到项目中的decomplie_src,并把cobaltstrike4.1.jar文件放到项目中的lib目录。
对项目进行设置,添加模块依赖,在路径File-->Project Structure-->Modules-->Dependencies设置SDK。然后在Dependencies这个页面点一下"+"号,添加jar包,完成后点应用。
进入Artifacts-->JAR-->From modules with dependencies,设置一个MAIN CLASS为aggressor.Aggressor,这个值可以在MANIFEST.MF文件中查看。完成之后就是这样的结果。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
从handle_table_entry找到句柄对应的内核对象
从进程的Handle找到进程内核中的handle_table_entry,本节我们将介绍如何从handle_table_entry找到对应的内核对象,完成从进程的handle找到对应内核对象的过程。
<center>handle_table_entry -> object</center>
在Win7中,handle_table_entry结构中的object直接指向对应的内核对象地址,但在win10并没有这么简单。接着前文的调试内容继续查看ffffa08c`9e0e3010地址处handle_table_entry结构的具体内容。通常我们会去google这些新结构的含义,但这些都是未公开的,假设在google找不到的情况下,我们如何去做呢。
这个时候我们会去IDA查看内核中相关的实现,思路是找到handle与object相关联的函数。如ObFindHandleForObject,ObReferenceObjectByHandle
这里我选择ObFindHandleForObject来介绍,因为它流程相对简单一些。
该函数首先使用ObReferenceProcessHandleTable从EPROCESS的中获取HANDLE_TABLE,然后使用ExEnumHandleTable遍历该HANDLE_TABLE中的handle_table_entry。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
从进程的Handle找到进程内核中的handle_table_entry,本节我们将介绍如何从handle_table_entry找到对应的内核对象,完成从进程的handle找到对应内核对象的过程。
<center>handle_table_entry -> object</center>
在Win7中,handle_table_entry结构中的object直接指向对应的内核对象地址,但在win10并没有这么简单。接着前文的调试内容继续查看ffffa08c`9e0e3010地址处handle_table_entry结构的具体内容。通常我们会去google这些新结构的含义,但这些都是未公开的,假设在google找不到的情况下,我们如何去做呢。
这个时候我们会去IDA查看内核中相关的实现,思路是找到handle与object相关联的函数。如ObFindHandleForObject,ObReferenceObjectByHandle
这里我选择ObFindHandleForObject来介绍,因为它流程相对简单一些。
该函数首先使用ObReferenceProcessHandleTable从EPROCESS的中获取HANDLE_TABLE,然后使用ExEnumHandleTable遍历该HANDLE_TABLE中的handle_table_entry。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
Artifacts-->JAR-->From modules with dependencies,设置一个MAIN CLASS为aggressor.Aggressor,这个值可以在MANIFEST.MF文件中查看。完成之后就是这样的结果。
然后就是将decomplie_src复制到src中,这里直接将网上编译的那个版本的src目录复制到本项目的src目录中,如果有其他需求可以自己从decomplie_src复制添加即可。
以后每次要运行或者调试的时候,都可以
最后就完成了。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
然后就是将decomplie_src复制到src中,这里直接将网上编译的那个版本的src目录复制到本项目的src目录中,如果有其他需求可以自己从decomplie_src复制添加即可。
Build -->Build Artifacts -->Build进行编译。在out目录就可以看到生成的.jar文件。以后每次要运行或者调试的时候,都可以
Run-->Profile-->Run(debug)最后就完成了。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
beacon生成原理
beacon生成主要有3个步骤,首先是将C2Patch的相关数据patch到beacon中,便于beacon使用,第二步,处理beacon的PE数据和添加引导shellcode,这段shellcode是引导执行ReflectiveLoader。第三步将beacon加密,并和一些数据patch到loader中。
在beacon生成这块,主要涉及到4个java文件。BeaconPayload.java主要是对beacon进行C2Profile相关的处理,主要涉及的函数为exportBeaconStage。MalleablePE.java,主要用于对beacon进行一些PE相关的处理,主要涉及的函数为process函数。而BeaconLoader.java主要是patch beacon的开头那段shellcode。主要涉及到patchDOSHeader函数。BaseArtifactUtils主要是将加密beacon数据和一些加密beacon的key之类的数据patch到loader模板上,
CobaltStrike服务端,通过()生成beacon,经过分析,将断点分别下在WindowsExecutableStageDialog.dialogAction和WindowsExecutableStageDialog.dialogResult这两个函数处。通过 dialogAction函数,选择需要保存的文件的内容或者格式。然后调用SafeDialogs.saveFile函数,弹出保存文件的选择框。
接着调用dialogResult函数,dialogResult函数是生成beacon的主要流程,参数的参数var1表示保存beacon的路径。
依次获取架构类型(x86或者x64),然后监听器这里选的是reverse_http。
然后调用ScListener.export函数,export函数的作用是通过不同的监听器,选择不同的Stage。本例中是调用eaconPayload.exportBeaconStageHTTP函数。exportBeaconStageHTTP的参数分别是(var1)端口,(var2)链接地址,var3,var4分别是false,var5是架构。通过不同的架构选择不同的BeaconStage数据。
在exportBeaconStage函数中,首先调用SleevedResource.readResource加载指定的beacon原始文件
然后读取C2Profile中的uri等C2Profile信息。我曾经根据这些默认的C2Profile的URI信息,捞到过一批有价值的CobaltStrike样本。
在解析完C2Profile数据之后,就会按照一定的顺序将这些C2Profile的参数拼装起来,并patch到beacon中,以供beacon使用。
在beacon\BeaconConstants.java这个文件中,可以看到C2Profile数据拼接序号的含义。在之前分析exportBeaconStageHTTP参数的时候,var1为端口。可以看到这里第二个处理的就是端口。而beacon\BeaconConstants.java文件的第二项的内容也是端口。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke
beacon生成主要有3个步骤,首先是将C2Patch的相关数据patch到beacon中,便于beacon使用,第二步,处理beacon的PE数据和添加引导shellcode,这段shellcode是引导执行ReflectiveLoader。第三步将beacon加密,并和一些数据patch到loader中。
在beacon生成这块,主要涉及到4个java文件。BeaconPayload.java主要是对beacon进行C2Profile相关的处理,主要涉及的函数为exportBeaconStage。MalleablePE.java,主要用于对beacon进行一些PE相关的处理,主要涉及的函数为process函数。而BeaconLoader.java主要是patch beacon的开头那段shellcode。主要涉及到patchDOSHeader函数。BaseArtifactUtils主要是将加密beacon数据和一些加密beacon的key之类的数据patch到loader模板上,
CobaltStrike服务端,通过()生成beacon,经过分析,将断点分别下在WindowsExecutableStageDialog.dialogAction和WindowsExecutableStageDialog.dialogResult这两个函数处。通过 dialogAction函数,选择需要保存的文件的内容或者格式。然后调用SafeDialogs.saveFile函数,弹出保存文件的选择框。
接着调用dialogResult函数,dialogResult函数是生成beacon的主要流程,参数的参数var1表示保存beacon的路径。
依次获取架构类型(x86或者x64),然后监听器这里选的是reverse_http。
然后调用ScListener.export函数,export函数的作用是通过不同的监听器,选择不同的Stage。本例中是调用eaconPayload.exportBeaconStageHTTP函数。exportBeaconStageHTTP的参数分别是(var1)端口,(var2)链接地址,var3,var4分别是false,var5是架构。通过不同的架构选择不同的BeaconStage数据。
在exportBeaconStage函数中,首先调用SleevedResource.readResource加载指定的beacon原始文件
然后读取C2Profile中的uri等C2Profile信息。我曾经根据这些默认的C2Profile的URI信息,捞到过一批有价值的CobaltStrike样本。
在解析完C2Profile数据之后,就会按照一定的顺序将这些C2Profile的参数拼装起来,并patch到beacon中,以供beacon使用。
在beacon\BeaconConstants.java这个文件中,可以看到C2Profile数据拼接序号的含义。在之前分析exportBeaconStageHTTP参数的时候,var1为端口。可以看到这里第二个处理的就是端口。而beacon\BeaconConstants.java文件的第二项的内容也是端口。
/网站渗透 /黑客编程技术
/软件渗透 /提取数据
/网站权限 /网站入侵破解
有需求的找我 @MoA_Ke