您当前的位置: 首页 >  windows

合天网安实验室

暂无认证

  • 1浏览

    0关注

    748博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

windows安全初探之命名管道

合天网安实验室 发布时间:2020-04-13 10:30:00 ,浏览量:1

前言:

 

最近学校开了操作系统这门课,记录自己学习命名管道中与网络安全有关的内容。

 

关于命名管道:

“命名管道”又名“命名管线”(Named Pipes),是一种简单的进程间通信(IPC)机制,Microsoft Windows大都提供了对它的支持(但不包括Windows CE)。命名管道可在同一台计算机的不同进程之间或在跨越一个网络的不同计算机的不同进程之间,支持可靠的、单向或双向的数据通信。推荐用命名管道作为进程通信方案的一项重要的原因是它们充分利用了Windows内建的安全特性(ACL等)。

用命名管道来设计跨计算机应用程序实际非常简单,并不需要事先深入掌握底层网络传送协议(如TCP、UDP、IP、IPX)的知识。这是由于命名管道利用了微软网络提供者(MSNP)重定向器通过同一个网络在各进程间建立通信,这样一来,应用程序便不必关心网络协议的细节。

 

命名管道是一个具有名称,可以单向或双面在一个服务器和一个或多个客户端之间进行通讯的管道。命名管道的所有实例拥有相同的名称,但是每个实例都有其自己的缓冲区和句柄,用来为不同客户端通许提供独立的管道。使用实例可使多个管道客户端同时使用相同的命名管道。

 

命名管道的名称在本系统中是唯一的。

命名管道可以被任意符合权限要求的进程访问。

命名管道只能在本地创建。

命名管道的客户端可以是本地进程(本地访问:\.\pipe\PipeName)或者是远程进程(访问远程:\ServerName\pipe\PipeName)。

 命名管道使用比匿名管道灵活,服务端、客户端可以是任意进程,匿名管道一般情况下用于父子进程通讯。

 

 

列出计算机内所有的命名管道:

 

在powershell3以上的版本中,我们可以使用

 

[System.IO.Directory]::GetFiles("\\.\\pipe\\")

 

来查看本机上所有的存在的命名管道,或者使用process explorer来进行查看

 

命名管道的创建及通信

 

在windows中命名管道的通信方式是:

①创建命名管道 -->  ②连接命名管道  -->  ③读写命名管道

详细过程如下:

命名管道通过调用函数CreateNamedPipe()创建,函数原型如下:

HANDLE WINAPI CreateNamedPipe(
  _In_     LPCTSTR               lpName,
  _In_     DWORD                 dwOpenMode,
  _In_     DWORD                 dwPipeMode,
  _In_     DWORD                 nMaxInstances,
  _In_     DWORD                 nOutBufferSize,
  _In_     DWORD                 nInBufferSize,
  _In_     DWORD                 nDefaultTimeOut,
  _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes
);

详细参数可以参考:https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea

 

创建完成后服务端可以调用函数ConnectNamedPipe()等待客户端的连接请求,函数原型如下:

 BOOL WINAPI ConnectNamedPipe(
  _In_        HANDLE       hNamedPipe,
 _Inout_opt_ LPOVERLAPPED lpOverlapped
);

详细参数可以参考:https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-connectnamedpipe

 

对于客户端而言,在连接服务器创建的命名管道前需要判断该命名管道是否可用,可调用函数WaitNamedPipe()实现

函数原型如下:

BOOL WaitNamedPipeA(
  LPCSTR lpNamedPipeName,
  DWORD  nTimeOut
);

详细参数可以参考:https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-waitnamedpipea

 

当WaitNamedPipe()调用成功后,便可使用CreateFile()将命名管道打开已获得管道的句柄。

 

然后客户端对命名管道的读写操作利用函数ReadFile()和WriteFile()完成,函数原型如下:

BOOL WriteFile(
  HANDLE       hFile,
  LPCVOID      lpBuffer,
  DWORD        nNumberOfBytesToWrite,
  LPDWORD      lpNumberOfBytesWritten,
  LPOVERLAPPED lpOverlapped
);
BOOL ReadFile(
  HANDLE       hFile,
  LPVOID       lpBuffer,
  DWORD        nNumberOfBytesToRead,
  LPDWORD      lpNumberOfBytesRead,
  LPOVERLAPPED lpOverlapped
);

具体参数可以参考:

 

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfile

 

demo:

下面是一个命名管道通信的小demo:

服务端:

#include
#include


#define BUF_SIZE 1024


using namespace std;


int main(int argc,char * argv[]) {


  HANDLE h_pipe;
  char rev_buf[BUF_SIZE];
  DWORD rel_buf;


  h_pipe = CreateNamedPipe(
    "\\\\.\\pipe\\pipename",
    PIPE_ACCESS_INBOUND,
    PIPE_READMODE_BYTE | PIPE_WAIT,
    PIPE_UNLIMITED_INSTANCES,
    BUF_SIZE,
    BUF_SIZE,
    0,
    nullptr
  );


  if (h_pipe == INVALID_HANDLE_VALUE) {
    cout            
关注
打赏
1665306545
查看更多评论
0.1274s