您的位置:首页 > 运维架构

一种检查rootkit的方法(wineggdrop)

2004-11-23 17:21 459 查看
rootkit本来一直都是*nix系统中流行的一种后门,但现在win下也开始流行rootkit了,由于rootkit一般具有隐藏自己的特性,所以并不是象一般后门那样可以轻易的找出来.现在win下最流行的后门是国外的那个hxdef,代码也已经发放了.hxdef一个不足是主程序在隐藏自己的进程上做得不好,已经有多种方法可以将它本身的隐藏进程查出来,但将来的rootkit会在隐藏进程方面做得更好,或者会使用没有进程的方法另这种查隐藏进程去检测rootkit的方法失效.已知新版的hxdef(还没开始写),已要开始使用另类的隐藏进程方法,也已经有人开发出第三方的工具去隐藏其它程序的进程,而且这种方法可以令klister也无法查到其隐藏的进程.自然还有其它多种方法可以检测rootkit的,我也介绍一种可行的,但会有限制的检查方法.一般的rootkit都无法将隐远程session的,hxdef和国产的ntrootkit都一样,这样就我们只要使用远程枚举的方法,就应该能够检测到rootkit的存在.

                        原理是远程枚举系统的服务,hxdef和ntrootkit隐藏的服务都是无法对于远程的枚举服务进行隐藏的,那我们只要对比一下远程枚举出来的服务和本地枚举出来的服务,就能得到rootkit隐藏了的服务了.这种方法的限制在于需要远程系统允许远程的验证(ipc,rpc等).

                        以下代码是可以进行远程和本地的枚举WIN32类型的所有正在运行的服务,改变枚举的服务类型的话,可以枚举所有的服务(WIN32+Driver),通过比较远程和本地枚举结果,就应该能查出是否存在隐藏了的服务了.远程枚举需要远程系统允许ipc远程验证.

 

                        //********************************************************************************

                        // Version: V1.0
                        // Coder: WinEggDrop
                        // Date Release: NULL
                        // Purpose: To View Local Or Remote WIN32 Service(A Way
                        To Detect Some Rookits)
                        // Test PlatForm: Win 2K Pro And Server SP4
                        // Compiled On: VC++ 6.0
                        // Others:
                        //        A Way To Detect Rootkit By Comparing The
                        Results Of Listing Service
                        //        Locally And Remotely Since Most Rootkit
                        Doesn't Hide Service In Remote
                        //        Session.
                        //        The Code Only List WIN32 Service;Modifying The
                        ServiceType Can List All
                        //        Services(WIN32 + Driver)
                        // Limitation:
                        //        IPC Connection Is Enabled
                        //********************************************************************************

                        #include <stdio.h>
                        #include <windows.h>
                        #include <Winnetwk.h>
                        #include <Shlwapi.h>
                        #include <Winsvc.h>

                        #pragma comment(lib, "Advapi32.lib")
                        #pragma comment(lib, "Mpr.lib")

                        // Function ProtoType Declaration
                        //------------------------------------------------------------------------------------------------------

                        BOOL ListRemoteService(const char *RemoteIP,const char
                        *UserName,const char *Password);
                        BOOL ListSpecifiedTypeService(const char *RemoteIP,const
                        DWORD dwServiceType);
                        BOOL EstablishIPCConnection(const char *RemoteIP,const
                        char *UserName,const char *Password);
                        BOOL DisconnectIPC(const char *RemoteIP);
                        //------------------------------------------------------------------------------------------------------

                        // End Of Fucntion ProtoType Declaration

                        int main(int argc,char *argv[])
                        {
                        if (argc != 4 && argc != 2)        // Argument Number Is
                        Wrong, Display Usage And Exit
                        {
                             printf("Usage:   %s Local / RemoteIP UserName
                        Password/n",argv[0]);
                             printf("Example: %s //12.12.12.12 test
                        test/n",argv[0]);
                             printf("Example: %s Local/n",argv[0]);
                             return -1;
                        }

                        if (argc == 4)
                        {
                             ListRemoteService(argv[1],argv[2],argv[3]);       
                        // Let's List The RemoteIP Service
                        }
                        else
                        {
                             if (strcmpi(argv[1],"Local") == 0)        // List
                        Local Service
                             {
                                 ListSpecifiedTypeService(NULL,SERVICE_WIN32);  
                             
                             }
                        }
                        return 0;
                        }// End Of Main();

                        //------------------------------------------------------------------------------------

                        // Purpose: To List Service Remotely
                        // Return Type: BOOLEAN
                        // Parameters:  
                        //           In: const char *RemoteIP   --> Remote IP To
                        Connect
                        //           In: const char *UserName   --> User Name
                        For IPC Connection
                        //           In: const char *Password   --> Password For
                        IPC Connection
                        //------------------------------------------------------------------------------------

                        BOOL ListRemoteService(const char *RemoteIP,const char
                        *UserName,const char *Password)
                        {
                        char     RemoteAddress[128] = {0};

                        if (strncmp(RemoteIP,"//",2) != 0)        // Check
                        Whether It's In //IP Form
                        {
                             sprintf(RemoteAddress,"//%s/ipc$",RemoteIP);       
                        // Add // If It's Not In //IP Form
                        }
                        else
                        {
                             sprintf(RemoteAddress,"%s/ipc$",RemoteIP);
                        }

                        printf("Connecting IPC....../r");
                        if
                        (!EstablishIPCConnection(RemoteAddress,UserName,Password))
                               // Fail To Connect IP
                        {
                             printf("Fail To Establish IPC Connection/n");
                             return FALSE;
                        }
                        printf("Connecting IPC OK        /n");
                        DWORD dwServiceType = SERVICE_WIN32;
                        ListSpecifiedTypeService(RemoteIP,dwServiceType);       
                        // List Service RemoteLY
                        return DisconnectIPC(RemoteAddress);
                        }// End of ListRemoteService()

                        //------------------------------------------------------------------------------------

                        // Purpose: To List Service Based On The ServiceType
                        // Return Type: BOOLEAN
                        // Parameters:  
                        //           In: const char *RemoteIP       --> Remote
                        IP To Connect
                        //           In: const DWORD dwServiceType  --> The
                        Service Type
                        //------------------------------------------------------------------------------------

                        BOOL ListSpecifiedTypeService(const char *RemoteIP,const
                        DWORD dwServiceType)
                        {
                        char     RemoteAddress[128] = {0};
                        LPENUM_SERVICE_STATUS lpServices = NULL;
                        DWORD    nSize = 0;
                        DWORD    nServicesReturned;
                        DWORD    nResumeHandle = 0;
                        SC_HANDLE schSCManager = NULL;
                        BOOL     Flag = FALSE;
                        DWORD    i = 0;
                        UINT     j = 0;

                        if (RemoteIP != NULL)        // List Service Remotely
                        {
                             if (strncmp(RemoteIP,"//",2) != 0)        // Check
                        Whether It's In //IP Form
                             {
                                 sprintf (RemoteAddress, "//%s",RemoteIP);      
                         // Add // If It's Not In //IP Form
                             }
                             else
                             {
                                 sprintf (RemoteAddress, "%s",RemoteIP);
                             }
                        }

                        if (RemoteIP != NULL)
                        {
                             schSCManager = OpenSCManager(RemoteAddress, NULL,
                        SC_MANAGER_ALL_ACCESS);
                        }
                        else
                        {
                             schSCManager = OpenSCManager(NULL, NULL,
                        SC_MANAGER_ALL_ACCESS);
                        }

                        if (schSCManager == NULL)        // Fail To Open SCM
                        {
                             printf("Fail To Open SCM/n");
                             return FALSE;
                        }

                        lpServices = (LPENUM_SERVICE_STATUS) LocalAlloc(LPTR, 64
                        * 1024);        // Allocate Ram

                        if (lpServices == NULL)        // Fail To Allocate Ram
                        {
                             printf("Fail To Allocate Ram/n");
                             goto CleanUP;
                        }

                        // Enum All Service Based On Service Type
                        if (EnumServicesStatus(schSCManager,
                                                dwServiceType,
                                                SERVICE_ACTIVE,
                                               
                        (LPENUM_SERVICE_STATUS)lpServices,
                                                64 * 1024,
                                                &nSize,
                                                &nServicesReturned,
                                                &nResumeHandle) == NULL)

 

                        {
                             printf("Fail To Enum Service/n");
                             goto CleanUP;
                        }

                        // Display The Services
                        printf("%-34s%s/n/n","ServiceName","DisplayName");
                        for (i = 0; i < nServicesReturned; i++)
                        {
                             if (lpServices[i].ServiceStatus.dwCurrentState ==
                        SERVICE_RUNNING)
                             {
                                
                        printf("%d:%-32s%s/n",++j,lpServices[i].lpServiceName,
                        lpServices[i].lpDisplayName);
                             }
                        }
                        Flag = TRUE;

                        // Close Service Handle,Free Allocated Ram And Return To
                        The Caller
                        CleanUP:
                        CloseServiceHandle(schSCManager);
                        if (lpServices != NULL)
                        {
                             LocalFree(lpServices);
                        }
                        return Flag;
                        }// End Of ListSpecifiedTypeService()

                        //------------------------------------------------------------------------------------

                        // Purpose: To Establish IPC Connection
                        // Return Type: BOOLEAN
                        // Parameters:  
                        //           In: const char *RemoteIP   --> Remote IP To
                        Connect
                        //           In: const char *UserName   --> User Name
                        For IPC Connection
                        //           In: const char *Password   --> Password For
                        IPC Connection
                        // This Is Too Simple,I Won't Comment It
                        //------------------------------------------------------------------------------------

                        BOOL EstablishIPCConnection(const char *RemoteIP,const
                        char *UserName,const char *Password)
                        {
                        NETRESOURCE NET;

                        NET.lpLocalName = NULL;
                        NET.lpRemoteName = (char *)RemoteIP;
                        NET.dwType = RESOURCETYPE_ANY;
                        NET.lpProvider = NULL;
                        return (WNetAddConnection2(&NET, Password,UserName,
                        CONNECT_INTERACTIVE) == NO_ERROR);
                        }// End Of EstablishIPCConnection()

                        //------------------------------------------------------------------------------------

                        // Purpose: To Disconnect IPC Connection
                        // Return Type: BOOLEAN
                        // Parameters:  
                        //           In: const char *RemoteIP   --> Remote IP To
                        Connect
                        // This Is Too Simple,I Won't Comment It
                        //------------------------------------------------------------------------------------

                        BOOL DisconnectIPC(const char *RemoteIP)
                        {
                        return (WNetCancelConnection2(RemoteIP,NULL,TRUE) ==
                        NO_ERROR);
                        }// End Of DisconnectIPC()
                        // End Of File

                  其实不需要写程序也可以,有现成的程序可以做到的了,sc.exe可以查看到远程的服务,只不过sc.exe列出来一个服务的信息太多了,我们关心的只是正在运行的服务的服务名和显示名,而且给每个服务前加个编号,比较起来也比较容易.例如远程枚举时最后的服务编号是40,但本地枚举时最后的服务编号是35,那么你已经可以知道有5个服务是被隐藏的了.

                  

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息