C++ 邮件槽ShellCode跨进程传输

打印 上一主题 下一主题

主题 643|帖子 643|积分 1944

在计算机安全领域,进程间通信(IPC)一直是一个备受关注的话题。在本文中,我们将探讨如何使用Windows邮件槽(Mailslot)实现ShellCode的跨进程传输。邮件槽提供了一种简单而有效的单向通信机制,使得任何进程都能够成为邮件槽服务器,并通过UDP通信向其他进程发送数据。
邮件槽是Windows操作系统提供的一种用于本地进程间通信的机制。它允许一个进程创建一个命名的槽,并允许其他进程通过该槽向创建它的进程发送消息。在本文中,我们将使用邮件槽实现进程间的ShellCode传输。如果需要双向通信或更复杂的通信需求,需要考虑其他IPC机制,例如命名管道、套接字等。
服务端部分

服务端端部分的实现非常简单,通过使用MAIL_SLOT_NAME 可以定义邮件槽的名称,该名称用于标识服务端和客户端之间的邮件槽。这是一个字符串常量,按照 Windows 命名约定的格式指定了邮件槽的路径。
让我来解释这个定义的具体含义:

  • \\\\.:表示本地计算机,即当前计算机的命名空间。
  • mailslot:指定邮件槽的类型。
  • Name:是你给邮件槽指定的名称,可以根据实际需要更改。
所以,整个路径 \\\\.\\mailslot\\Name 指代的是一个本地计算机上的邮件槽,其名称为 Name。这个路径会在创建和打开邮件槽时使用,确保两个进程使用相同的路径来通信。
在服务端创建邮件槽时,通过 CreateFile 函数中的 MAIL_SLOT_NAME 参数指定邮件槽的名称,确保服务端和客户端使用相同的名称来建立通信连接。
CreateFile
用于创建或打开文件、文件夹、邮件槽、管道等对象的句柄。在你提供的代码中,CreateFile 主要用于打开邮件槽,以便在服务端写入数据。
以下是 CreateFile 函数的一般形式:
  1. HANDLE CreateFile(
  2.   LPCTSTR               lpFileName,
  3.   DWORD                 dwDesiredAccess,
  4.   DWORD                 dwShareMode,
  5.   LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  6.   DWORD                 dwCreationDisposition,
  7.   DWORD                 dwFlagsAndAttributes,
  8.   HANDLE                hTemplateFile
  9. );
复制代码
参数说明:

  • lpFileName:指定文件或对象的名称,可以是一个路径、文件名或其他标识符。
  • dwDesiredAccess:指定对文件的访问权限,例如 GENERIC_READ、GENERIC_WRITE 等。
  • dwShareMode:指定共享模式,例如 FILE_SHARE_READ、FILE_SHARE_WRITE 等。
  • lpSecurityAttributes:指定安全属性,通常设置为 NULL。
  • dwCreationDisposition:指定文件的创建或打开方式,例如 OPEN_EXISTING、CREATE_NEW 等。
  • dwFlagsAndAttributes:指定文件或对象的属性,例如 FILE_ATTRIBUTE_NORMAL。
  • hTemplateFile:指定一个文件句柄,用于复制文件属性。
如上所示,我们只需要遵循邮件槽的创建流程并使用CreateFile创建通信,当需要传输邮件的时候可以直接调用WriteFile发送邮件,这是一个很好的功能,你可以发送邮件也可以发送各种你喜欢的乱七八糟的东西。
  1. #include <windows.h>
  2. #include <iostream>
  3. using namespace std;
  4. #define MAIL_SLOT_NAME "\\\\.\\mailslot\\Name"
  5. char ShellCode[] = "此处是ShellCode";
  6. int main(int argc, char* argv[])
  7. {
  8.     HANDLE hWriteMailSlot = NULL;
  9.     while (TRUE)
  10.     {
  11.         hWriteMailSlot = CreateFile(MAIL_SLOT_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  12.         if (hWriteMailSlot == INVALID_HANDLE_VALUE)
  13.             continue;
  14.         else
  15.             break;
  16.     }
  17.     DWORD dwReturn = 0;
  18.     // 发送邮件槽
  19.     WriteFile(hWriteMailSlot, ShellCode, strlen(ShellCode), &dwReturn, NULL);
  20.     CloseHandle(hWriteMailSlot);
  21.     return 0;
  22. }
复制代码
客户端部分

为了实现通信,客户端部分也需要使用邮件槽,在MAIL_SLOT_NAME中指定相同的邮件名,通过CreateMailslot 函数,创建邮件槽(Mailslot),这是一种用于本地进程间通信的机制。邮件槽是一种命名的管道,用于在同一台计算机上的不同进程之间传递数据。
以下是 CreateMailslot 函数的一般形式:
  1. HANDLE CreateMailslot(
  2.   LPCTSTR               lpName,
  3.   DWORD                 nMaxMessageSize,
  4.   DWORD                 lReadTimeout,
  5.   LPSECURITY_ATTRIBUTES lpSecurityAttributes
  6. );
复制代码
参数说明:

  • lpName:指定邮件槽的名称,形如 \\.\mailslot\your_mailslot_name。
  • nMaxMessageSize:指定邮件槽中消息的最大大小。
  • lReadTimeout:指定在读取数据时的超时时间(以毫秒为单位)。
  • lpSecurityAttributes:指定邮件槽的安全属性,可以为 NULL。
在代码中,CreateMailslot 用于创建邮件槽:
  1. hReadMailSlot = CreateMailslot(MAIL_SLOT_NAME, 0, 0, NULL);
复制代码
这行代码的作用是创建一个邮件槽,使用了预定义的邮件槽名称 MAIL_SLOT_NAME 作为参数,nMaxMessageSize 和 lReadTimeout 都设置为零,表示使用默认值。如果创建成功,hReadMailSlot 将获得一个有效的邮件槽句柄,可以用于后续的数据读取操作。
创建好链接之后接下来就可以通过GetMailslotInfo函数获取邮件了,当然了这个要死循环等待邮件,GetMailslotInfo 用于检查邮件槽的状态信息。它提供了有关邮件槽当前状态的信息,例如有多少消息在邮件槽中、每个消息的大小等。
以下是 GetMailslotInfo 函数的一般形式:
  1. BOOL GetMailslotInfo(
  2.   HANDLE       hMailslot,
  3.   LPDWORD      lpMaxMessageSize,
  4.   LPDWORD      lpNextSize,
  5.   LPDWORD      lpMessageCount,
  6.   LPDWORD      lpReadTimeout
  7. );
复制代码
参数说明:

  • hMailslot:邮件槽的句柄,通过 CreateMailslot 函数或 CreateFile 函数获得。
  • lpMaxMessageSize:指向一个变量,用于接收邮件槽中单个消息的最大大小。
  • lpNextSize:指向一个变量,用于接收下一个消息的大小。
  • lpMessageCount:指向一个变量,用于接收邮件槽中当前的消息数目。
  • lpReadTimeout:指向一个变量,用于接收在读取数据时的超时时间(以毫秒为单位)。
在你的代码中,GetMailslotInfo 用于获取邮件槽的信息:
  1. bOk = GetMailslotInfo(hReadMailSlot, NULL, &cbMessage, &cMessage, NULL);
复制代码
这行代码的作用是获取邮件槽 hReadMailSlot 的信息,其中 cbMessage 接收消息的大小,cMessage 接收消息的数量。这样的信息可以在接收方确定是否有待处理的消息,以及处理这些消息所需的空间。
一般来说当收到了新邮件之后可以直接使用ReadFile函数读出这段邮件,读出来的邮件就可以直接反弹了,如下代码所示;
[code]#include #include using namespace std;#define MAIL_SLOT_NAME "\\\\.\\mailslot\\Name" HANDLE hReadMailSlot = INVALID_HANDLE_VALUE;DWORD WINAPI ReadMail(){    hReadMailSlot = CreateMailslot(MAIL_SLOT_NAME, 0, 0, NULL);    if (hReadMailSlot == INVALID_HANDLE_VALUE)    {        return -1;    }    // 查看油槽的信息    DWORD cbMessage = 0, dwReturn = 0, cMessage = 0;    BOOL bOk = FALSE;    char ShellCode[4096] = { 0 };    while (TRUE)    {        bOk = GetMailslotInfo(hReadMailSlot, NULL, &cbMessage, &cMessage, NULL);        if (bOk == FALSE)            break;        if (cMessage == 0)            continue;        else        {            if (ReadFile(hReadMailSlot, ShellCode, cbMessage, &dwReturn, 0) == TRUE)            {                HANDLE hThread = NULL;                cout
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大连全瓷种植牙齿制作中心

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表