{"id":113,"date":"2022-04-01T16:27:58","date_gmt":"2022-04-01T08:27:58","guid":{"rendered":"http:\/\/www.aqwu.net\/wp\/?p=113"},"modified":"2022-04-10T22:00:36","modified_gmt":"2022-04-10T14:00:36","slug":"ntdllpipe-%e4%bd%bf%e7%94%a8-cmd-exe-%e6%a3%80%e7%b4%a2%e5%b9%b2%e5%87%80%e7%89%88%e6%9c%ac%e7%9a%84-ntdll-dll","status":"publish","type":"post","link":"https:\/\/www.aqwu.net\/wp\/?p=113","title":{"rendered":"NtdllPipe &#8211; \u4f7f\u7528 cmd.exe \u68c0\u7d22\u5e72\u51c0\u7248\u672c\u7684 ntdll.dll"},"content":{"rendered":"\n<p>\u539f\u6587\u94fe\u63a5\uff1ahttps:\/\/www.x86matthew.com\/view_post?id=ntdll_pipe<\/p>\n\n\n\n<p>\u6211\u6700\u8fd1\u4f7f\u7528\u4e86\u4e00\u53f0\u5b89\u88c5\u4e86 AV \u8f6f\u4ef6\u7684\u8ba1\u7b97\u673a\uff0c\u8be5\u8f6f\u4ef6\u5c06\u7528\u6237\u6a21\u5f0f\u6302\u94a9\u6ce8\u5165\u5230ntdll.dll\u4e2d\u7684\u5404\u79cd\u51fd\u6570\u4e2d\u3002\u6211\u4e0d\u4e86\u89e3\u73b0\u4ee3 AV \u8f6f\u4ef6\u7684\u8fd0\u884c\u65b9\u5f0f\uff0c\u6240\u4ee5\u6211\u51b3\u5b9a\u770b\u770b\u8fd9\u662f\u591a\u4e48\u5bb9\u6613\u514b\u670d\u3002<\/p>\n\n\n\n<p>\u6700\u660e\u663e\u7684\u65b9\u6cd5\u662f\u4f7f\u7528CreateFile\u548cReadFile\u4ece\u78c1\u76d8\u8bfb\u53d6ntdll.dll\uff0c\u4f46\u8fd9\u4f1a\u89e6\u53d1 AV \u542f\u53d1\u5f0f\u5f15\u64ce\u3002&nbsp;\u6211\u7684\u4e0b\u4e00\u4e2a\u60f3\u6cd5\u662f\u4f7f\u7528\u53d7\u4fe1\u4efb\u7684 Microsoft \u53ef\u6267\u884c\u6587\u4ef6\u4e3a\u6211\u5b8c\u6210\u8fd9\u9879\u5de5\u4f5c &#8211; \u4e00\u4e2a\u5019\u9009\u8005\u662fcmd.exe\u3002&nbsp;\u6211\u4f7f\u7528CreateProcess\u521b\u5efa\u4e86\u4e00\u4e2a\u9690\u85cf\u7684\u5e26\u6709stdin\u7684cmd.exe\u8fdb\u7a0b<\/p>\n\n\n\n<p>\u91cd\u5b9a\u5411\u5230\u6211\u7684\u7a0b\u5e8f\u4e2d\u7684\u81ea\u5b9a\u4e49\u547d\u540d\u7ba1\u9053\u3002\u6211\u8fd8\u4e3antdll.dll\u8f93\u51fa\u5185\u5bb9\u521b\u5efa\u4e86\u4e00\u4e2a\u5355\u72ec\u7684\u547d\u540d\u7ba1\u9053\u3002\u4f7f\u7528WriteFile\u5c06\u7c7b\u578b %windir%\\\\system32\\\\ntdll.dll &gt; \\\\.\\pipe\\ntdll_output_pipe\u53d1\u9001\u5230\u81ea\u5b9a\u4e49\u6807\u51c6\u8f93\u5165\u7ba1\u9053\uff0c\u7136\u540e\u5c06ntdll.dll\u7684\u5185\u5bb9\u5199\u5165\u6211\u7684\u8f93\u51fa\u7ba1\u9053\uff0c\u6211\u8bfb\u53d6\u5e76\u5b58\u50a8\u5728\u7f13\u51b2\u533a\u4e2d.&nbsp;\u8fd9\u79cd\u7b80\u5355\u7684\u65b9\u6cd5\u6ca1\u6709\u89e6\u53d1\u4efb\u4f55 AV \u8b66\u544a\u3002<\/p>\n\n\n\n<p>\u8fd9\u53ef\u4ee5\u901a\u8fc7\u5220\u9664\u6807\u51c6\u8f93\u5165\u91cd\u5b9a\u5411\u5e76\u4f7f\u7528\u521d\u59cb\u53c2\u6570\u4e2d\u7684 type \u547d\u4ee4\u542f\u52a8 cmd.exe \u6765\u7a0d\u5fae\u7b80\u5316\uff08&nbsp;cmd.exe&nbsp;\/&nbsp;c&nbsp;type&nbsp;%&nbsp;windir%\\\\system32\\\\ntdll.dll &gt; \\\\.\\pipe\\ntdll_output_pipe)\uff0c\u4f46\u8fd9\u770b\u8d77\u6765\u66f4\u53ef\u7591\u3002<\/p>\n\n\n\n<p>\u6211\u5df2\u7ecf\u6e05\u7406\u4e86\u4ee3\u7801\uff0c\u4ee5\u4fbf\u53ef\u4ee5\u8f7b\u677e\u5730\u4f7f\u7528\u5b83\u6765\u8bfb\u53d6\u4efb\u4f55\u547d\u4ee4\u7684\u8f93\u51fa\u5185\u5bb9\u3002<\/p>\n\n\n\n<p>\u5b8c\u6574\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ NtdllPipe.cpp : \u6b64\u6587\u4ef6\u5305\u542b \"main\" \u51fd\u6570\u3002\u7a0b\u5e8f\u6267\u884c\u5c06\u5728\u6b64\u5904\u5f00\u59cb\u5e76\u7ed3\u675f\u3002\n\/\/\n\n#include &lt;stdio.h>\n#include &lt;windows.h>\n\nstruct BackgroundConsoleInstanceStruct\n{\n\tchar szInstanceName&#91;128];\n\tHANDLE hConsoleProcess;\n\tHANDLE hConsoleInputPipe;\n};\n\nstruct CommandOutput_StoreDataParamStruct\n{\n\tBYTE* pOutputPtr;\n\tDWORD dwMaxOutputSize;\n\tDWORD dwTotalSize;\n};\n\nDWORD BackgroundConsole_Create(const char* pInstanceName, BackgroundConsoleInstanceStruct* pBackgroundConsoleInstance)\n{\n\tPROCESS_INFORMATION ProcessInfo;\n\tSTARTUPINFO StartupInfo;\n\tchar szConsoleInputPipeName&#91;512];\n\tchar szLaunchCmd&#91;1024];\n\tBackgroundConsoleInstanceStruct BackgroundConsoleInstance;\n\tHANDLE hConsoleInputPipe;\n\n\t\/\/ create console input pipe\n\tmemset(szConsoleInputPipeName, 0, sizeof(szConsoleInputPipeName));\n\t_snprintf(szConsoleInputPipeName, sizeof(szConsoleInputPipeName) - 1, \"\\\\\\\\.\\\\pipe\\\\BackgroundConsoleIn_%s\", pInstanceName);\n\thConsoleInputPipe = CreateNamedPipe(szConsoleInputPipeName, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 4096, 4096, 0, NULL);\n\tif (hConsoleInputPipe == INVALID_HANDLE_VALUE)\n\t{\n\t\t\/\/ error\n\t\treturn 1;\n\t}\n\n\t\/\/ initialise startupinfo\n\tmemset(&amp;StartupInfo, 0, sizeof(StartupInfo));\n\tStartupInfo.cb = sizeof(StartupInfo);\n\tStartupInfo.dwFlags = STARTF_USESHOWWINDOW;\n\tStartupInfo.wShowWindow = SW_HIDE;\n\n\t\/\/ create launch cmd\n\tmemset(szLaunchCmd, 0, sizeof(szLaunchCmd));\n\t_snprintf(szLaunchCmd, sizeof(szLaunchCmd) - 1, \"cmd \/c cmd &lt; %s\", szConsoleInputPipeName);\n\n\t\/\/ launch cmd.exe\n\tif (CreateProcess(NULL, szLaunchCmd, NULL, NULL, 0, CREATE_NEW_CONSOLE, NULL, NULL, &amp;StartupInfo, &amp;ProcessInfo) == 0)\n\t{\n\t\t\/\/ error\n\t\tCloseHandle(hConsoleInputPipe);\n\t\treturn 1;\n\t}\n\n\t\/\/ close thread handle\n\tCloseHandle(ProcessInfo.hThread);\n\n\t\/\/ wait for cmd.exe to connect to input pipe\n\tif (ConnectNamedPipe(hConsoleInputPipe, NULL) == 0)\n\t{\n\t\t\/\/ error\n\t\tCloseHandle(hConsoleInputPipe);\n\t\tCloseHandle(ProcessInfo.hProcess);\n\t\treturn 1;\n\t}\n\n\t\/\/ store background console entry data\n\tmemset((void*)&amp;BackgroundConsoleInstance, 0, sizeof(BackgroundConsoleInstance));\n\tstrncpy(BackgroundConsoleInstance.szInstanceName, pInstanceName, sizeof(BackgroundConsoleInstance.szInstanceName) - 1);\n\tBackgroundConsoleInstance.hConsoleProcess = ProcessInfo.hProcess;\n\tBackgroundConsoleInstance.hConsoleInputPipe = hConsoleInputPipe;\n\tmemcpy((void*)pBackgroundConsoleInstance, (void*)&amp;BackgroundConsoleInstance, sizeof(BackgroundConsoleInstance));\n\n\treturn 0;\n}\n\nDWORD BackgroundConsole_Close(BackgroundConsoleInstanceStruct* pBackgroundConsoleInstance)\n{\n\t\/\/ close console input pipe\n\tCloseHandle(pBackgroundConsoleInstance->hConsoleInputPipe);\n\n\t\/\/ wait for console process to end\n\tWaitForSingleObject(pBackgroundConsoleInstance->hConsoleProcess, INFINITE);\n\tCloseHandle(pBackgroundConsoleInstance->hConsoleProcess);\n\n\treturn 0;\n}\n\nDWORD BackgroundConsole_Exec(BackgroundConsoleInstanceStruct* pBackgroundConsoleInstance, const char* pCommand, DWORD(*pCommandOutput)(BYTE* pBufferData, DWORD dwBufferLength, BYTE* pParam), BYTE* pCommandOutputParam)\n{\n\tchar szWriteCommand&#91;2048];\n\tchar szCommandOutputPipeName&#91;512];\n\tHANDLE hCommandOutputPipe = NULL;\n\tBYTE bReadBuffer&#91;1024];\n\tDWORD dwBytesRead = 0;\n\n\t\/\/ create output pipe\n\tmemset(szCommandOutputPipeName, 0, sizeof(szCommandOutputPipeName));\n\t_snprintf(szCommandOutputPipeName, sizeof(szCommandOutputPipeName) - 1, \"\\\\\\\\.\\\\pipe\\\\BackgroundConsoleOut_%s\", pBackgroundConsoleInstance->szInstanceName);\n\thCommandOutputPipe = CreateNamedPipe(szCommandOutputPipeName, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 4096, 4096, 0, NULL);\n\tif (hCommandOutputPipe == INVALID_HANDLE_VALUE)\n\t{\n\t\t\/\/ error\n\t\treturn 1;\n\t}\n\n\t\/\/ write command to console\n\tmemset(szWriteCommand, 0, sizeof(szWriteCommand));\n\t_snprintf(szWriteCommand, sizeof(szWriteCommand) - 1, \"%s > %s\\n\", pCommand, szCommandOutputPipeName);\n\tif (WriteFile(pBackgroundConsoleInstance->hConsoleInputPipe, szWriteCommand, strlen(szWriteCommand), NULL, NULL) == 0)\n\t{\n\t\t\/\/ error\n\t\tCloseHandle(hCommandOutputPipe);\n\t\treturn 1;\n\t}\n\n\t\/\/ wait for target to connect to output pipe\n\tif (ConnectNamedPipe(hCommandOutputPipe, NULL) == 0)\n\t{\n\t\t\/\/ error\n\t\tCloseHandle(hCommandOutputPipe);\n\t\treturn 1;\n\t}\n\n\t\/\/ get data from output pipe\n\tfor (;;)\n\t{\n\t\t\/\/ read data from stdout pipe (ensure the buffer is null terminated in case this is string data)\n\t\tmemset(bReadBuffer, 0, sizeof(bReadBuffer));\n\t\tif (ReadFile(hCommandOutputPipe, bReadBuffer, sizeof(bReadBuffer) - 1, &amp;dwBytesRead, NULL) == 0)\n\t\t{\n\t\t\t\/\/ failed - check error code\n\t\t\tif (GetLastError() == ERROR_BROKEN_PIPE)\n\t\t\t{\n\t\t\t\t\/\/ pipe closed\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t\/\/ error\n\t\t\t\tCloseHandle(hCommandOutputPipe);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\t\/\/ send current buffer to output function\n\t\tif (pCommandOutput(bReadBuffer, dwBytesRead, pCommandOutputParam) != 0)\n\t\t{\n\t\t\t\/\/ error\n\t\t\tCloseHandle(hCommandOutputPipe);\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\t\/\/ close handle\n\tCloseHandle(hCommandOutputPipe);\n\n\treturn 0;\n}\n\nDWORD CommandOutput_StoreData(BYTE* pBufferData, DWORD dwBufferLength, BYTE* pParam)\n{\n\tCommandOutput_StoreDataParamStruct* pCommandOutput_StoreDataParam = NULL;\n\n\t\/\/ get param\n\tpCommandOutput_StoreDataParam = (CommandOutput_StoreDataParamStruct*)pParam;\n\n\t\/\/ check if an output buffer was specified\n\tif (pCommandOutput_StoreDataParam->pOutputPtr != NULL)\n\t{\n\t\t\/\/ validate length\n\t\tif (dwBufferLength > (pCommandOutput_StoreDataParam->dwMaxOutputSize - pCommandOutput_StoreDataParam->dwTotalSize))\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\n\t\t\/\/ copy data\n\t\tmemcpy((void*)(pCommandOutput_StoreDataParam->pOutputPtr + pCommandOutput_StoreDataParam->dwTotalSize), pBufferData, dwBufferLength);\n\t}\n\n\t\/\/ increase output size\n\tpCommandOutput_StoreDataParam->dwTotalSize += dwBufferLength;\n\n\treturn 0;\n}\n\n\/\/ www.x86matthew.com\nint main()\n{\n\tBackgroundConsoleInstanceStruct BackgroundConsoleInstance;\n\tCommandOutput_StoreDataParamStruct CommandOutput_StoreDataParam;\n\tBYTE* pNtdllCopy = NULL;\n\tDWORD dwAllocSize = 0;\n\n\tprintf(\"Creating hidden cmd.exe process...\\n\");\n\n\t\/\/ create background console\n\tif (BackgroundConsole_Create(\"mytest\", &amp;BackgroundConsoleInstance) != 0)\n\t{\n\t\treturn 1;\n\t}\n\n\tprintf(\"Retrieving ntdll file size...\\n\");\n\n\t\/\/ call the function with a blank output buffer to retrieve the file size\n\tmemset((void*)&amp;CommandOutput_StoreDataParam, 0, sizeof(CommandOutput_StoreDataParam));\n\tCommandOutput_StoreDataParam.pOutputPtr = NULL;\n\tCommandOutput_StoreDataParam.dwMaxOutputSize = 0;\n\tCommandOutput_StoreDataParam.dwTotalSize = 0;\n\tif (BackgroundConsole_Exec(&amp;BackgroundConsoleInstance, \"type %windir%\\\\system32\\\\ntdll.dll\", CommandOutput_StoreData, (BYTE*)&amp;CommandOutput_StoreDataParam) != 0)\n\t{\n\t\treturn 1;\n\t}\n\n\tprintf(\"ntdll.dll file size: %u bytes - allocating memory...\\n\", CommandOutput_StoreDataParam.dwTotalSize);\n\n\t\/\/ allocate memory\n\tdwAllocSize = CommandOutput_StoreDataParam.dwTotalSize;\n\tpNtdllCopy = (BYTE*)malloc(dwAllocSize);\n\tif (pNtdllCopy == NULL)\n\t{\n\t\treturn 1;\n\t}\n\n\tprintf(\"Reading ntdll.dll data from disk...\\n\");\n\n\t\/\/ call the function again to read the file contents\n\tmemset((void*)&amp;CommandOutput_StoreDataParam, 0, sizeof(CommandOutput_StoreDataParam));\n\tCommandOutput_StoreDataParam.pOutputPtr = pNtdllCopy;\n\tCommandOutput_StoreDataParam.dwMaxOutputSize = dwAllocSize;\n\tCommandOutput_StoreDataParam.dwTotalSize = 0;\n\tif (BackgroundConsole_Exec(&amp;BackgroundConsoleInstance, \"type %windir%\\\\system32\\\\ntdll.dll\", CommandOutput_StoreData, (BYTE*)&amp;CommandOutput_StoreDataParam) != 0)\n\t{\n\t\treturn 1;\n\t}\n\n\tprintf(\"Read %u bytes successfully\\n\", CommandOutput_StoreDataParam.dwTotalSize);\n\n\t\/\/ (pNtdllCopy now contains a copy of ntdll)\n\n\t\/\/ clean up\n\tfree(pNtdllCopy);\n\tBackgroundConsole_Close(&amp;BackgroundConsoleInstance);\n\n\treturn 0;\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u539f\u6587\u94fe\u63a5\uff1ahttps:\/\/www.x86matthew.com\/view_post?id=ntdll_pipe [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[45,37,43],"tags":[29],"class_list":["post-113","post","type-post","status-publish","format-standard","hentry","category-x86matthew-com","category-samples","category-infoarticle","tag-ntdll"],"views":1286,"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.aqwu.net\/wp\/index.php?rest_route=\/wp\/v2\/posts\/113","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.aqwu.net\/wp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aqwu.net\/wp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aqwu.net\/wp\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aqwu.net\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=113"}],"version-history":[{"count":2,"href":"https:\/\/www.aqwu.net\/wp\/index.php?rest_route=\/wp\/v2\/posts\/113\/revisions"}],"predecessor-version":[{"id":123,"href":"https:\/\/www.aqwu.net\/wp\/index.php?rest_route=\/wp\/v2\/posts\/113\/revisions\/123"}],"wp:attachment":[{"href":"https:\/\/www.aqwu.net\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=113"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aqwu.net\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=113"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aqwu.net\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=113"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}