91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

使用匿名管道技術獲取CMD命令的執(zhí)行結果

蛇矛實驗室 ? 來源:蛇矛實驗室 ? 2023-04-03 18:04 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

序言

遠程 CMD 是指惡意程序接收到控制端發(fā)送的 CMD 指令后,在本地執(zhí)行 CMD 命令,并將執(zhí)行結果回傳至控制端。本文將演示使用匿名管道技術獲取 CMD 命令的執(zhí)行結果。

相關API

CreatePipe:用于創(chuàng)建管道

PeekNamedPipe:用于判斷管道中是否有數據存在

ReadFile、WriteFile:用于向管道讀取或寫入數據

CreateProcess:用于創(chuàng)建CMD子進程,可指定啟動信息(STARTUPINFO)

實現原理

管道是一種進程間通信的技術,Window 上進程間通信技術還有文件映射、共享內存、郵槽、剪切板、事件等。

管道分為命名管道和匿名管道:

* 匿名管道只能在父子進程間通信,數據傳輸單向,不能網絡通信

* 命名管道可在任意進程間通信,數據傳輸雙向,但同一時間只能有一端讀寫。

由于遠程 CMD 中僅僅需要執(zhí)行 CMD 指令的結果,所以使用匿名管道即可,其使用流程如下:

1. 使用 CreatePipe 創(chuàng)建匿名管道,獲取管道數據讀取句柄和管道數據寫入句柄。

2. 初始化進程結構體,將管道寫入句柄賦給新進程控制臺窗口的緩存句柄;

3. 使用CreateProcess創(chuàng)建新進程執(zhí)行CMD命令,并等待命令執(zhí)行結束;

4. 在循環(huán)中使用 PeekNamedPipe 函數判斷管道中是否有數據,通過管道讀取句柄從緩沖區(qū)中獲取執(zhí)行結果。

5. 關閉句柄,釋放資源。

編碼實現

關鍵代碼

// 執(zhí)行 cmd 命令, 并獲取執(zhí)行結果數據
bool PipeCmd(TCHAR* cmd_str, std::string& outbuf)
{
BOOL bRet = FALSE;

HANDLE hReadPipe = NULL;
HANDLE hWritePipe = NULL;
SECURITY_ATTRIBUTES securityAttributes = {0};
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};

// 設定管道的安全屬性
securityAttributes.bInheritHandle = TRUE;
securityAttributes.nLength = sizeof(securityAttributes);
securityAttributes.lpSecurityDescriptor = NULL;
// 創(chuàng)建匿名管道
bRet = ::CreatePipe(&hReadPipe, &hWritePipe, &securityAttributes, 0);
if(FALSE== bRet)
{
printf("CreatePipe");
returnfalse;
}
// 設置新進程參數
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdError = hWritePipe;
si.hStdOutput = hWritePipe;
// 創(chuàng)建新進程執(zhí)行命令, 將執(zhí)行結果寫入匿名管道中
bRet = ::CreateProcess(NULL, cmd_str, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
if(FALSE== bRet)
{
printf("CreateProcess");
returnfalse;
}

// 等待命令執(zhí)行結束
::WaitForSingleObject(pi.hThread, INFINITE);
::WaitForSingleObject(pi.hProcess, INFINITE);

// 不斷從匿名管道中讀取結果到輸出緩沖區(qū)
while(true)
{
char buf[2048]{};
DWORD readbytes = 0;
DWORD availbytes = 0;

if(!PeekNamedPipe(hReadPipe, NULL, 0, NULL, &availbytes, NULL)) break;
if(!availbytes) break;
if(!ReadFile(hReadPipe, buf, min(sizeof(buf) - 1, availbytes), &readbytes, NULL) || !readbytes) break;

buf[readbytes] = 0;
outbuf += buf;
}

// 關閉句柄, 釋放內存
::CloseHandle(pi.hThread);
::CloseHandle(pi.hProcess);
::CloseHandle(hWritePipe);
::CloseHandle(hReadPipe);

returntrue;
}

上面的代碼中首先調用 CreatePipe 函數創(chuàng)建匿名管道,并將返回的讀寫句柄保存到 hReadPipe 和 hWritePipe 變量中。

然后,通過設置STARTUPINFO結構體中的參數,將新進程的標準錯誤輸出和標準輸出都重定向到管道中,以便將命令執(zhí)行結果寫入管道中。

接著,調用CreateProcess函數創(chuàng)建新進程,并將命令行命令作為參數傳入。

CreateProcess 函數執(zhí)行成功后,新進程開始執(zhí)行命令,并將命令執(zhí)行結果寫入管道中,之后通過循環(huán)調用 PeekNamedPipe 和 ReadFile 函數,不斷從管道中讀取數據,并將讀取到的數據存儲到輸出緩沖區(qū)中。

最后,代碼關閉句柄,釋放內存。

測試實現

測試代碼

intmain(intargc, char** argv)
{
TCHAR cmd_str[] = L"ping 127.0.0.1";

// 執(zhí)行 cmd 命令, 并獲取執(zhí)行結果數據
std::stringoutbuf;
if(false== PipeCmd(cmd_str, outbuf))
{
printf("pipe cmd error.
");
}
else
{
printf("CMD執(zhí)行結果為:
%s
", outbuf.c_str());
}

system("pause");
return0;
}

b4ead242-d004-11ed-bfe3-dac502259ad0.png

遠程傳輸

前面僅僅是把 cmd 命令的執(zhí)行結果獲取了,要想實現遠程傳輸,需要加入網絡傳輸部分。

b4fd46e8-d004-11ed-bfe3-dac502259ad0.png

測試

服務端

#definePORT 9982
inttest_server()
{
SOCKET listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

sockaddr_in bindaddr;
bindaddr.sin_family = AF_INET;
bindaddr.sin_addr.S_un.S_addr = ADDR_ANY;
bindaddr.sin_port = htons(PORT);
bind(listenfd, (SOCKADDR*)&bindaddr, sizeof(SOCKADDR));

listen(listenfd, 1);

sockaddr_in clientaddr;
intclientaddrlen = sizeof(SOCKADDR);
SOCKET clientfd = accept(listenfd, (SOCKADDR*)&clientaddr, &clientaddrlen);

charbuf[1024]{};
intrecvbytes = recv(clientfd, buf, 1024, 0);
if(recvbytes <= 0) return?-1;

???std::string?outbuf;
???PipeCmd((LPTSTR)buf, outbuf);
???std::cout?<< outbuf << std::endl;

???closesocket(clientfd);
???closesocket(listenfd);

???return?0;
}

客戶端

inttest_client()
{
SOCKET connfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

structsockaddr_inServerAddr;
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
ServerAddr.sin_port = htons(PORT);

connect(connfd, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr));

TCHAR cmdbuf[100] = _T("ipconfig");
send(connfd, (char*)cmdbuf, (lstrlen(cmdbuf) + 1) * sizeof(TCHAR), 0);

closesocket(connfd);

return0;

效果

開啟服務器后,通過客戶端向服務端發(fā)送指令,服務端接收到指令后開始處理,最終測試能夠正確處理。

小結

上述的遠程 CMD 的實現通過一個匿名管道實現的,它是通過直接執(zhí)行 cmd 命令,從而不需要創(chuàng)建傳遞命令的管道。遠程 CMD 的實現方法還有幾種變形方式,比如雙管道遠程 CMD,和零管道遠程 CMD,它們對應的思路就是對 CMD 的輸出輸入重定向位置進行控制,比如:

雙管道實現遠程 CMD 就是將 CMD 進程的輸入、輸出句柄替換為讀寫管道的句柄。

零管道實現遠程 CMD 就是將 CMD 進程的輸入、輸出句柄替換為 socket 的句柄。






審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • WINDOWS
    +關注

    關注

    4

    文章

    3702

    瀏覽量

    94057
  • CMD命令
    +關注

    關注

    0

    文章

    28

    瀏覽量

    8748

原文標題:安全研發(fā)之遠程CMD

文章出處:【微信號:蛇矛實驗室,微信公眾號:蛇矛實驗室】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    ???????使用 DMM Web API 獲取搜索列表數據

    ? ?DMM 平臺提供了豐富的 Web API 接口,允許開發(fā)者獲取其平臺上的各種數據。其中一個常用的接口是用于獲取搜索列表結果的 API。本文將介紹如何調用此 API 來獲取商品或內
    的頭像 發(fā)表于 02-09 15:34 ?161次閱讀
    ???????使用 DMM Web API <b class='flag-5'>獲取</b>搜索列表數據

    為什么不建議用匿名結構體

    說起匿名結構體,想必大家第一感覺就是看著好高大上的名字,但實際上也就那樣。 typedef struct { union { struct { uint8_t bit_0:1
    發(fā)表于 12-04 07:39

    Shell歷史命令history用法

    1. 顯示歷史命令列表 「介紹」:history 命令用于顯示當前會話中執(zhí)行過的命令的列表,以及每個命令對應的編號。「示例代碼」:histo
    發(fā)表于 12-02 06:10

    飛凌嵌入式ElfBoard-文件I/O的了解探究之fcntl和ioctl

    -1,并且會設置errno;執(zhí)行成功的情況下,其返回值與cmd(操作命令)有關,譬如cmd=F_DUPFD(復制文件描述符)將返回一個新的文件描述符、
    發(fā)表于 11-28 09:17

    NICE指令的完整執(zhí)行過程

    做進一步的譯碼,請求通道接收指令并依次執(zhí)行指令。 5、協處理器通過反饋通道反饋結果、返回值。 6、主處理器提取命令,并將結果寫回通用寄存器(如果需要寫回)。
    發(fā)表于 10-23 07:25

    [RT-Thread Nano 4.1.1] Finsh 控制 命令執(zhí)行 創(chuàng)建定時器 第三次無法執(zhí)行怎么解決?

    軟件平臺:RT-Thread Nano 4.1.1 組件:Finsh 控制臺 硬件平臺:Numaker-M252SD 任務: MSH_CMD_EXPORT user_timer_test 控制命令
    發(fā)表于 10-13 07:09

    使用AT組件命令行可以發(fā)送成功,但是在程序里發(fā)送總是超時,怎么解決?

    是AT說明里的例程,按照例程把發(fā)送命令加入到控制臺,輸入命令是可以正確響應的。 但是我在程序里寫是類似的代碼,就提示超時。 在提示超時后,又會顯示正確的響應結果,這是為了個啥?! 下面是我的程序 int
    發(fā)表于 09-23 07:14

    遠程命令執(zhí)行:IT 運維效率翻倍新方式

    。SplashtopAEM(自動端點管理)解決方案內置的遠程命令提示符功能,允許IT管理員無需啟動完整的遠程會話,即可輕松在遠程設備上執(zhí)行命令行指令。該功能同時兼容W
    的頭像 發(fā)表于 09-04 17:15 ?1093次閱讀
    遠程<b class='flag-5'>命令</b><b class='flag-5'>執(zhí)行</b>:IT 運維效率翻倍新方式

    【HZ-T536開發(fā)板免費體驗】5- 無需死記 Linux 命令!用 CangjieMagic 在 HZ-T536 開發(fā)板上搭建 MCP 服務器,自然語言輕松控板

    對應的 Linux 命令或 API 調用; MCP服務器執(zhí)行指令,獲取HZ-T536開發(fā)板上的運行結果(如命令輸出、硬件狀態(tài)); MCP服務
    發(fā)表于 08-23 13:10

    310V額定電壓無刷管道風扇驅動方案技術解析--【其利天下】

    市面上的無刷管道風扇驅動方案,看看它們的指標、難題,以及其利天下技術有限公司的解決方案。一、市面上無刷管道風扇驅動方案難題啟動問題:單相無刷電機存在啟動死點,當扇葉停
    的頭像 發(fā)表于 08-01 18:05 ?1296次閱讀
    310V額定電壓無刷<b class='flag-5'>管道</b>風扇驅動方案<b class='flag-5'>技術</b>解析--【其利天下】

    Linux基礎命令which詳解

    在Linux系統(tǒng)中,which命令用于查找并顯示指定命令的可執(zhí)行文件路徑。這對于系統(tǒng)管理員和開發(fā)人員來說是一個非常有用的工具,可以幫助定位命令所在的位置,確認
    的頭像 發(fā)表于 07-29 17:58 ?856次閱讀

    oracle數據恢復—oracle數據庫誤執(zhí)行錯誤truncate命令如何恢復數據?

    oracle數據庫誤執(zhí)行truncate命令導致數據丟失是一種常見情況。通常情況下,oracle數據庫誤操作刪除數據只需要通過備份恢復數據即可。也會碰到一些特殊情況,例如數據庫備份無法使用或者還原
    的頭像 發(fā)表于 06-05 16:01 ?1087次閱讀
    oracle數據恢復—oracle數據庫誤<b class='flag-5'>執(zhí)行</b>錯誤truncate<b class='flag-5'>命令</b>如何恢復數據?

    allegro軟件走線命令下參數不顯示如何解決

    在PCB設計中,走線命令是頻繁使用的功能之一。執(zhí)行走線命令后,通常會在Options面板中顯示線寬、層、角度等設置選項,用于調整走線參數。然而,有時執(zhí)行走線
    的頭像 發(fā)表于 06-05 09:30 ?2031次閱讀
    allegro軟件走線<b class='flag-5'>命令</b>下參數不顯示如何解決

    HarmonyOS5云服務技術分享--匿名登錄功能指南

    哦\') break; } 希望這篇指南能讓大家少走彎路!如果遇到任何問題,歡迎來評論區(qū)找我嘮嗑~ 也記得關注我們的公眾號獲取最新技術資訊哦!? 祝各位開發(fā)順利,咱們下期見! ? 【本期小互動】你更傾向用手機驗證碼登錄還是游客快速體驗?評論區(qū)聊聊你的看法吧~ ?
    發(fā)表于 05-22 16:41

    HarmonyOS5云服務技術分享--認證文檔問題

    oh-package.json5?? 在應用級oh-package.json5中添加依賴: 點擊右上角 ??Sync Now?? 同步配置。 ??方式二:命令行安裝?? 進入entry目錄執(zhí)行命令: ??3. 初始化SDK
    發(fā)表于 05-22 13:20