jxpxfeiw 发表于 2012-4-17 22:57:36

请教P版,有什么方法阻止进程注入?

有什么方法阻止进程注入?防止进程被注入恶意模块。

pusofalse 发表于 2012-4-18 00:35:03

防止运行过程中被注入Dll,可以挂钩Kernel32.LoadLibrary函数或更加底层的Ntdll.LdrLoadDll函数,因为注入Dll实际原理就是在目标进程中创建一个远程线程,线程函数调用LoadLibrary,LoadLibrary在内部又会调用LdrLoadDll,LdrLoadDll完成实质的加载Dll的操作。这种情况下,可以简单调用Advapi32.SetKernelObjectSecurity为自己的进程定义一个DACL(访问控制列表),拒绝所有用户对自身进程的访问。但是,此法可以通过调用Advapi32.AdjustTokenPrivileges函数破解,进程对象的DACL完全形同虚设,因为一旦有了Debug权限,总是可以以PROCESS_ALL_ACCESS(完全控制)权限来获取进程对象、线程对象的句柄。有了这个完全控制权限的句柄,想做什么就能做什么。所以,通过调用SetKernelObjectSecurity设置自身进程的安全权限,只针对于那些不能提升至Debug权限的恶意进程。

另一种情况。进程运行之初,我们自己定义的代码并不是最先执行的,因为Au3的解析器会在内部做一些初始化工作,然后才运行我们自己写的代码。如果恶意程序瞅准了时机,在我们挂钩LoadLibrary之前就已经注入了Dll,那通过挂钩法防止注入 就一点意义也没有。如果是这样,那么可以在一个循环中实时枚举自身进程中的Dll,如果找到了不符合预期的Dll,就调用FreeLibrary来释放。但是,你应该想到,恶意程序也可能在循环中实时监测Dll是否仍在我们的进程中,如果不在了,还可能会重新注入。或者,恶意程序注入dll到我们的进程中,很可能只是为了执行一小段代码,没等我们的进程循环完毕,恶意程序就从我们的进程中释放了此Dll。再者,如果我们进程中的某个线程正在执行Dll中的代码,此时调用FreeLibrary就会导致进程崩溃,这种可能性非常大。所以通过调用FreeLibrary来阻止注入也不是一种可行的方法。

修改Dll也不行,因为恶意程序可能调用了类似FileInstall的函数,将Dll内置进自己的程序中,每次注入的都是未经修改过的Dll。

要确保绝对不会被注入,最重要的是要取得系统的控制权。谁启动得更早,谁就更能控制整个操作系统,甚至控制杀软也不在话下。

以下这段代码,先设置自身进程的DACL,拒绝所有用户所有形式的访问。再创建一个受限令牌,随同此令牌,创建一个不受信任的恶意程序,由于恶意进程的令牌中没有Debug权限,所以就不能通过AdjustTokenPrivileges提权,以此就达到了保护自身进程的目的。运行代码,你会发现任务管理器不能结束自身进程了,更不必说远程注入和读写内存等其他恶意操作了。用这种方法成功保护自己的前提是,必须确保自身进程比恶意程序启动得早。另外,有一个非常非常强大的函数,Ntdll中的NtCreateToken,可以创建自定义令牌,这意味着不需要密码,就能创建任意用户下的进程,并且此进程还能够拥有比SYSTEM还高级的权限,以及还能够访问其他任何进程都访问不了的文件等对象。

#include <lsasecur.au3>

; 获取自身进程令牌,之后会用到
Local $hToken = _SeOpenProcessToken(-1)

; 获取Everyone账户SID
Local $pTrusteeSid = _SeLookupAccountName("Everyone")

; 创建访问控制列表,拒绝所有用户所有形式的访问
Local $pDacl = _SeSetEntriesInAcl1($pTrusteeSid, $SE_GENERIC_ALL, $SE_DENY_ACCESS, $SE_NO_INHERITANCE)

Local $pSecurityDescriptor = _SeInitSecurityDescriptor()
_SeSetSecurityDescriptorDacl($pSecurityDescriptor, $pDacl)

; 设置自身进程的安全属性
_SeSetKernelObjectSecurity(-1, $SE_INFO_DACL, $pSecurityDescriptor)


Local $aPrivilege = [$SE_DEBUG_PRIV]

;Local $hToken = _SeOpenProcessToken(-1)

; 通过自身令牌创建受限令牌,不能通过此受限令牌提升至Debug权限
Local $hRestrictToken = _SeCreateRestrictedToken($hToken, 0, 0, $aPrivilege, 0)

;恶意程序路径
Local $sUntrustApp = @SystemDir & "\taskmgr.exe"

; 创建进程,并赋予此进程一个受限制的令牌
Local $tProcessInfo = _SeCreateUserProcess($hRestrictToken, $sUntrustApp)

_SeCloseHandle(DllStructGetData($tProcessInfo, "Process"))
_SeCloseHandle(DllStructGetData($tProcessInfo, "Thread"))

_SeCloseHandle($hRestrictToken)
_SeCloseHandle($hToken)

_SeHeapFree($pSecurityDescriptor)
_SeHeapFree($pTrusteeSid)
_SeLocalFree($pDacl)

MsgBox(0, "OK", "Done~")

nmgwddj 发表于 2012-4-18 00:41:52

看的眼花缭乱的,能明白P版在说什么,看到代码就一塌糊涂了。
一些腾讯的游戏为了防止恶意程序结束,通过普通进程查看工具无法看到程序的运行目录,是不是就是后面提到的那种方式?

pusofalse 发表于 2012-4-18 00:56:56

回复 3# nmgwddj


    我不知道腾讯是怎样做的。我这样做:
#include <lsasecur.au3>

_SeImpersonateProcessPath(" ")
MsgBox(0, "OK", "@AutoItExe=" & @AutoItExe)

编译之后再测试。我不知这个函数能否工作于其他操作系统,我的是XP SP3。

nmgwddj 发表于 2012-4-18 01:15:54



的确给力,不过编译成64位就不成了。

nmgwddj 发表于 2012-4-18 01:20:31

看lsasecur的说明,这个也只是模拟进程路径。起不到防止被结束的目的。

Qokelate 发表于 2012-4-18 01:42:47

回复 4# pusofalse


    任务管理器的右键菜单 “打开文件位置” 还是能找出文件本身位置,不过命令行列里面显示的是假位置

环境Server2008SP2x32

pusofalse 发表于 2012-4-18 01:51:42

回复 7# Qokelate

我不知这个系统是如何获取进程路径的,在我的系统中点击“打开所在目录”,任务管理器没任何反应,说明模拟进程路径模拟成功了。用XP用习惯了,身边的朋友也都是在用XP,也没法测试。感谢你提出的BUG~

pp648852 发表于 2012-4-18 06:28:06

UDF相关牛X,佩服P版

haijie1223 发表于 2012-4-18 07:54:43

标记一下...

jxpxfeiw 发表于 2012-4-19 09:05:24

多谢P大讲解,不过我的意思不是保护自身进程,而是保护指定进程,而且每次被注入的文件名称都是随机的。
刚在WGLM上看到XBS的一个拦截DLL注入,不过他只能拦截指定的DLL文件。
页: [1]
查看完整版本: 请教P版,有什么方法阻止进程注入?