游戏里的攻防-检测与反检测

0x0.提出问题
  • 游戏公司通过自己的检测技术检测到我们的注入模块时,我们应该采取什么样的反检测技术进行别人看不到的攻击呢?
    游戏里的攻防-检测与反检测_第1张图片
0x1.检测技术的原理:
  • 能够检测到对应的模块信息,说明这个模块存在于某块内存中,一定有个结构体记录了这些模块信息,那么我们可以尝试去把这个注入模块的信息给删除掉。
0x2.PEB和TEB
PEB(Process Environment Block,进程环境块):存放进程信息的结构体,尺寸非常大
TEB(Thread Environment Block): 该结构体包含进程中运行线程的各种信息,进程中的每个线程都对应着一个TEB结构体

MSDN文档的介绍

typedef struct _PEB {
  BYTE                          Reserved1[2];
  BYTE                          BeingDebugged;
  BYTE                          Reserved2[1];
  PVOID                         Reserved3[2];
  PPEB_LDR_DATA                 Ldr;
  PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
  PVOID                         Reserved4[3];
  PVOID                         AtlThunkSListPtr;
  PVOID                         Reserved5;
  ULONG                         Reserved6;
  PVOID                         Reserved7;
  ULONG                         Reserved8;
  ULONG                         AtlThunkSListPtr32;
  PVOID                         Reserved9[45];
  BYTE                          Reserved10[96];
  PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
  BYTE                          Reserved11[128];
  PVOID                         Reserved12[1];
  ULONG                         SessionId;
} PEB, *PPEB;

Reserved:

  • 闭源,微软不告诉我们,要我们自己去猜
  • 不同操作系统(xp,win7…)下有不同的含义,微软也不知道怎么告诉我们
  • 可以用Windbg打印出来去研究不同操作系统下是什么含义;也可以去参考别人分析好的资料

BeingDebugged: 我们可以利用这个特性来检测有没有被调试的一种检测方案

  • 当我们附加调试器,它会被修改为1
  • 当我们没有附调试器,他会被修改为0

Ldr : 该结构包含有关进程的已加载模块的信息。

typedef struct _PEB_LDR_DATA {
  BYTE       Reserved1[8];
  PVOID      Reserved2[3];
  LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _LIST_ENTRY {
   struct _LIST_ENTRY *Flink;
   struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
typedef struct _LDR_DATA_TABLE_ENTRY {
    PVOID Reserved1[2];
    LIST_ENTRY InMemoryOrderLinks;
    PVOID Reserved2[2];
    PVOID DllBase;
    PVOID EntryPoint;
    PVOID Reserved3;
    UNICODE_STRING FullDllName;
    BYTE Reserved4[8];
    PVOID Reserved5[3];
    union {
        ULONG CheckSum;
        PVOID Reserved6;
    };
    ULONG TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
0x3.攻击方案:把注入模块的节点在PEB结构体中删除掉

提出问题:怎么获取到PEB结构体呢?✔ 答:TEB里面有PEB指针,我们只需要得到TEB就可以了

typedef struct _TEB {
  PVOID Reserved1[12];
  PPEB  ProcessEnvironmentBlock;
  PVOID Reserved2[399];
  BYTE  Reserved3[1952];
  PVOID TlsSlots[64];
  BYTE  Reserved4[8];
  PVOID Reserved5[26];
  PVOID ReservedForOle;
  PVOID Reserved6[4];
  PVOID TlsExpansionSlots;
} TEB, *PTEB;

提出问题:怎么得到TEB结构体呢?答:它放在了FS段寄存器里面,我们通过访问它就可以得到TEB

#include 
#include 
int main() {
	PPEB peb;
	_asm {
		mov eax, fs:[0x30];
		mov peb, eax;
	}
}

设计程序验证我们的想法:
游戏里的攻防-检测与反检测_第2张图片

0x4 利用PEB模块获取进程模块信息

游戏里的攻防-检测与反检测_第3张图片

游戏里的攻防-检测与反检测_第4张图片

0x30.如果LDR_DATA_TABLE_ENTRY结构体发生了变化,那么这个程序就不能够正常使用了;
0x31.为了提高程序的兼容性,我们需要把0x8替换成动态的

int structDis = (int)&lDis->InMemoryOrderLinks;

当我们通过自己的猜测各种手段得到结构体里面的属性代表的含义,可以自己声明一个结构体类型

typedef struct _LDR_DATA_TABLE_ENTRYA {
	PVOID Reserved1[2];
	LIST_ENTRY InMemoryOrderLinks;
	PVOID Reserved2[2];
	PVOID DllBase;
	PVOID EntryPoint;
	PVOID ImageSize;//
	UNICODE_STRING FullDllName;
	BYTE Reserved4[8];
	PVOID Reserved5[3];
#pragma warning(push)
#pragma warning(disable: 4201) // we'll always use the Microsoft compiler
	union {
		ULONG CheckSum;
		PVOID Reserved6;
	} DUMMYUNIONNAME;
#pragma warning(pop)
	ULONG TimeDateStamp;
} LDR_DATA_TABLE_ENTRYA, * PLDR_DATA_TABLE_ENTRYA;
0x5 隐藏对应的模块:通过删除节点,但是通过实证发现并没有被隐藏,为什么呢?

游戏里的攻防-检测与反检测_第5张图片
通过Windbg的调试打印和逆向分析, 填充了微软官方文档实际的结构体不一致的地方,从而实现了模块的隐藏
游戏里的攻防-检测与反检测_第6张图片

二.通过PE特征的角度去定位注入模块

通过CE或者自己写代码搜索

在这里插入图片描述

去除PE特征

通过pchunter64去搜索进程模块

无痕注入:
1.在驱动层驱动干掉
2.在应用层驱动层干掉

总结:网络攻防无止境的,最终一定是技术强的人获胜

你可能感兴趣的:(#,GameHacker,游戏)